It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
This is just a simple test program. I'm trying to have the Arduino print "received" on an LCD screen attached to it. I think it's my if statement causing the error, any ideas?
Currently when "send" is put in the serial monitor nothing happens.
Here is the code:
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
char serialinput; // for incoming serial data
void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
serialinput = Serial.read();
if (serialinput == 'send')
{
lcd.print("received");
}
}
}
You're reading a byte (a char in C) from your serial port, but you try to compare it to a string:
If you want to read 4 char and compare it to "send" then you would have to do something like:
#include <LiquidCrystal.h>
#include <string.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
char serialinput [5] = {0}; // for incoming serial data
// 4 char + ending null char
void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
// send data only when you receive data:
if (Serial.available() > 0) {
memmove (serialinput, &serialinput[1], 3); // Move 3 previous char in the buffer
serialinput [3] = Serial.read(); // read char at the end of input buffer
if (0 == strcmp(serialinput, "send")) // Compare buffer content to "send"
{
lcd.print("received");
}
}
}
Assuming that <string.h> header is valid within the Arduino SDK
PS : litteral strings in C code are written between " (double quotation marks). ' is for characters.
What errors did you have when uploading to the arduino ?
Related
I would like to measure a pulse using the pic 18f4550 in capture mode, this pulse is generated by the pic microcontroller itself, for this I use a function which plays the role of the XOR logic gate (you find the function that I've used below). with RC0 and RC2 the inputs and RC6 the signal output. the pulse leaving RC6 enters ccp2 to be measured.
The problem I found is that the ccp2 cannot detect the impulse generated by the microcontroller. I don't know if there are any conditions to connect the pins of the microcontroller or something.
If anyone has an answer or a hint to fix this, I will be grateful!
and if you have any questions feel free to ask .thanks !!
UPDATE: I changed some instructions in the code, now the RC6 output provides a signal. but my LCD does not display anything. the RC6 output is present below.
UPDATE 2: the while(1) in the xor() function blocking the rest of my program, so the program never get out of xor() and my LCD wont display anything. when I don't use the while loop in xor () my RC6 produce anything, the same for the LCD.
I don't know where the problem is, I did everything in my power to find the bug . but the system still not working!!!
I will leave the program as it is, so new readers can understand what I am talking about.
#include <stdio.h>
#include <stdlib.h>
#include "osc_config.h"
#include "LCD_8bit_file.h"
#include <string.h>
unsigned long comtage,capt0,x;
char pulse[20];
char cosinus[20];
float period,dephTempo,deph,phi;
void init (){
IRCF0 =1; /* set internal clock to 8MHz */
IRCF1 =1;
IRCF2 =1;
PIE2bits.CCP2IE=1;
PIR2bits.CCP2IF=0;
CCPR2 =0; /*CCPR1 is capture count Register which is cleared initially*/
T3CONbits.RD16=1;
T3CKPS0=0;
T3CKPS1=0;
TMR3CS=0;
TMR3IF=0;
T3CCP2=0; /*Timer3 is the capture clock source for CCP2*/
}
void xor()
{
while(1)
{
if (PORTCbits.RC0==PORTCbits.RC2)
{
PORTCbits.RC6=0;
}
else if (PORTCbits.RC0!=PORTCbits.RC2)
{
PORTCbits.RC6=1;
}
}
}
void main()
{
TRISCbits.TRISC0=1;
TRISCbits.TRISC2=1;
TRISCbits.TRISC6=0;
xor();
LCD_Init();
while(1)
{
CCP2CON = 0b00000101;
PIR2bits.CCP2IF = 0;
TMR3ON = 0;
TMR3 = 0;
while (!PIR2bits.CCP2IF);
TMR3ON = 1;
CCP2CON = 0b00000100;
PIR2bits.CCP2IF = 0;
while (!PIR2bits.CCP2IF);
comtage = CCPR2;
dephTempo = (((float)comtage /30.518)/65536 );
sprintf(pulse,"%.3f ",dephTempo);
LCD_String_xy(0,0,"the pulse width is : ");
LCD_String_xy(2,9,pulse);
}
}
I have been playing around with SparkFun 16x2 SerLCD LCD from SparkFun and controlling it via the Tiva C EK-TM4C123GXL board. I have managed to connect the LCD via SPI communication and written code to display strings on the board. However I was having trouble writing code that would clear the screen for me until I came across this code online:
#include <stdint.h>
#include <stdlib.h>
#include "inc/tm4c123gh6pm.h"
void spi_master_ini(void){ //Setup SPI
SYSCTL_RCGCSSI_R|=(1<<2);
//SYSCTL_RCGCGPIO_R |=(1<<1);
SYSCTL_RCGC2_R |=(1<<1);
GPIO_PORTB_AFSEL_R|=(1<<4)|(1<<5)|(1<<6)|(1<<7);
GPIO_PORTB_PCTL_R=0x22220000;
GPIO_PORTB_DEN_R|=(1<<4)|(1<<5)|(1<<6)|(1<<7);
GPIO_PORTB_PUR_R|=(1<<4)|(1<<5)|(1<<6)|(1<<7);
SSI2_CR1_R=0;
SSI2_CC_R=0;
SSI2_CR1_R=64;
SSI2_CR0_R=0x7;
SSI2_CR1_R|=(1<<1);
}
void send_byte(char data){
SSI2_DR_R=data;
while((SSI2_SR_R&(1<<0))==0);
}
void send_str(char *buffer){
while(*buffer!=0){
send_byte(*buffer);
buffer++;
}
}
int main(){
spi_master_ini();
SSI2_DR_R=0x7C; //Put into setting mode.
SSI2_DR_R=0x2D; //Clear screen, move cursor to home position.
send_str("Testing");
}
Specifically the 2 lines of code that are puzzling me:
SSI2_DR_R=0x7C; //Put into setting mode.
SSI2_DR_R=0x2D; //Clear screen, move cursor to home position.
After reading through the HD44780U datasheet I wasn't able to see how sending those HEX values to the data lines would do anything other than print "|" and "-" to the LCD. However, to my surprise when I ran the code it works and clears my LCD screen.
The data sheet for the HD44780U is irrelevant - you are not talking directly to the display controller. On the SparkFun 16x2 SerLCD, the SPI communication is with the ATmega328P which in turn communicates with the display controller.
This simplifies the interface to the display, since you only need an SPI or I2C link and do not need a 4/8 bit data bus and additional control lines required by the display controller.
The software running on the ATMega328P interprets and translates commands independently of the display controller. The source code at https://github.com/sparkfun/OpenLCD applies.
settings.h has:
#define SPECIAL_SETTING '|' //124, 0x7C, the pipe character: The command to do special settings: baud, lines, width, backlight, splash, etc
Then in OpenLCD.ino void updateDisplay() there is:
//Check to see if the incoming byte is special
if (incoming == SPECIAL_SETTING) //SPECIAL_SETTING is 127
{
currentMode = MODE_SETTING;
}
...
note the comment is erroneous, it is 124 not 127 (perhaps says something about the quality of this code).
Then later:
else if (currentMode == MODE_SETTING)
{
currentMode = MODE_NORMAL; //In general, return to normal mode
...
//Clear screen and buffer
else if (incoming == 45) //- character
{
SerLCD.clear();
SerLCD.setCursor(0, 0);
clearFrameBuffer(); //Get rid of all characters in our buffer
}
...
Then clearFrameBuffer() simply fills the buffer with spaces rather then using the HD44780 "Clear Display" instruction:
//Flushes all characters from the frame buffer
void clearFrameBuffer()
{
//Clear the frame buffer
characterCount = 0;
for (byte x = 0 ; x < (settingLCDwidth * settingLCDlines) ; x++)
currentFrame[x] = ' ';
}
Much of the documentaton is for Arduino, but the command table at https://learn.sparkfun.com/tutorials/avr-based-serial-enabled-lcds-hookup-guide/firmware-overview is valid regardless. It is interms of characters rather then integer codes so has:
...
...
And many more commands you might find useful.
I am currently working on a project where we have to use an AVR ATMEGA328 micro-controller, specifically the USART peripheral, to control 8 LED's. We have to send commands to the micro-controller that will turn on, off, and blink the LED's at different rates. I have written a program in C that I think will do the job, but I would like someone to look at it and help me fix any mistakes that I may have. Your help will be greatly appreciated!
*P.S. Each command in the commands array associates with its corresponding LED state in the LED array. The LED's are connected to PORTB of the micro-controller.
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
/* Arrays that contain all input commands and LED states */
const char *commands[] = {"ON0","ON1","ON2","ON3","ON4","ON5","ON6","ON7","ON8","OFF0","OFF1","OFF2","OFF3","OFF4","OFF5","OFF6","OFF7","OFF8","BLINK0","BLINK1","BLINK2","BLINK3","BLINK4","BLINK5","BLINK6","BLINK7","BLINK8","STOP"\0}
int LEDs[28] = {0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80,0XFF,0XFE,0XFD,0XFB,0XF7,0XEF,0XDF,0XBF,0X7F,0,0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80,0XFF,0}
int i;
int j;
int Blinky(int j); // Function to execute blinking commands where j is the argument
{
PORTB = LEDs[j];
_delay_ms[250 + (j-18) * 50]; /* Calculates blinking delay times */
PORTB = 0;
_delay_ms[250 + (j-18) * 50];
}
int main(void)
{
DDRB=0XFF; // PORTB is set to output
DDRD=0X02; // Turns on the transmit pin for the USART in PORTD
/* Setup USART for 9600,N,8,1 */
USCR0B = 0X18;
USCR0C = 0X06;
UBRR0 = 51;
sei(); // Enable Global Interrupts
char input;
if(UCSR0A & 0X80) /* Reads data from the USART and assigns the contents to the character input */
input = UDR0;
j=28;
char cmd;
cmd = *commands[i];
for(i=0; i<28; i++)
{
if(input==cmd) /* If the contents of UDR0 are equal to one of the commands */
j = i;
}
while(1)
{
if(j<18)
PORTB=LEDs[j]; // Executes the "ON" and "OFF" commands
else if(j<27)
Blinky(j); // Executes the blinking command by calling the Blinky function
else if(j=27)
PORTB=0; // Executes the "STOP" command
else
PORTB=0; // Accounts for typing errors
}
return(0);
}
There is a lot wrong with this program, but code review is not the purpose of Stack Overflow. See the FAQ for how to ask an appropriate question.
That said, some of the obvious problems are:
The _delay_ms() function needs to be called with a compile-time constant. It won't work correctly if the parameter needs to be calculated at run-time.
if you don't read any char from USART, then you still go through the rest of the loop.
char cmd declares a character variable, but then you assign a pointer to it.
i is used before it is set to a meaningful value.
input== cmd will likely never be true as one side is a character and the other is a pointer.
This question will likely close soon. Good luck, and come back if you have a question better suited to Stack Overflow.
I'm currently developing a system which involves sending a request string to a sensor device connected via UART to an Atmel SAML21 Xplained Pro board. I'm testing with an Arduino board as the "sensor device", but eventually, it'll be for a Rotronic HC-2 sensor.
The process goes something like this:
MCU sends string { 99RDD} over UART to sensor
-> delay of up to 500ms
-> Response string of 99 bytes sent back via UART
-> Response transmitted to virtual com port on embedded debugger
My issue is that for some reason, I'm either not getting anything sent back, or it's sending back the variable request_msg
I know that the response from the sensor should be 99 bytes of ASCII, and I've tested both the actual sensor, and the Arduino test board over serial connectors to ensure that the readings are coming back correctly.
The software is using Atmel ASF v4.0, which is great when it works, but the documentation is fairly flaky, so I was hoping someone with more experience could point me as to where I'm going wrong in the code.
I have the following code for my main application:
#include "atmel_start.h"
#include "atmel_start_pins.h"
#include <string.h>
static uint8_t example_hello_world[14] = "Hello World!\n";
static uint8_t example_error_msg[13] = "UART Error!\n";
static uint8_t request_msg[24] = "Sending Sensor Request\n";
static uint8_t rotronic_ascii[8] = "{ 99RDD}";
volatile static uint32_t data_arrived = 0;
volatile static uint32_t reading_received = 0;
static void tx_cb_EDBG_COM(const struct usart_async_descriptor *const io_descr)
{
/* Transfer completed */
gpio_toggle_pin_level(LED0);
}
static void rx_cb_EDBG_COM(const struct usart_async_descriptor *const io_descr)
{
/* Receive completed */
data_arrived = 1;
}
static void err_cb_EDBG_COM(const struct usart_async_descriptor *const io_descr)
{
/* error handle */
io_write(&EDBG_COM.io, example_error_msg, 13);
}
static void tx_cb_COM1(const struct usart_async_descriptor *const io_descr)
{
/* Transfer completed */
gpio_toggle_pin_level(LED0);
}
static void rx_cb_COM1(const struct usart_async_descriptor *const io_descr)
{
/* Receive completed */
reading_received = 1;
}
static void err_cb_COM1(const struct usart_async_descriptor *const io_descr)
{
/* error handle */
io_write(&COM1.io, example_error_msg, 13);
}
int main(void)
{
volatile uint8_t recv_char[99];
atmel_start_init();
// Setup the EDBG Serial Port
usart_async_register_callback(&EDBG_COM, USART_ASYNC_TXC_CB, tx_cb_EDBG_COM);
usart_async_register_callback(&EDBG_COM, USART_ASYNC_RXC_CB, rx_cb_EDBG_COM);
usart_async_register_callback(&EDBG_COM, USART_ASYNC_ERROR_CB, err_cb_EDBG_COM);
usart_async_enable(&EDBG_COM);
// Send a test string to ensure EDBG Serial is working
io_write(&EDBG_COM.io, example_hello_world, 14);
// Setup the Rotronic [Arduino] Serial Port
usart_async_register_callback(&COM1, USART_ASYNC_TXC_CB, tx_cb_COM1);
usart_async_register_callback(&COM1, USART_ASYNC_RXC_CB, rx_cb_COM1);
usart_async_register_callback(&COM1, USART_ASYNC_ERROR_CB, err_cb_COM1);
usart_async_enable(&COM1);
while (1) {
if (reading_received == 0)
{
// Delay for a Bit
delay_ms(5000);
// Notify the EDBG COM Port
io_write(&EDBG_COM.io, request_msg, 24);
// Send the Rotronic ASCII
io_write(&COM1.io, rotronic_ascii, 8);
}
// Check if Reading has been Received
if (reading_received == 1)
{
while (io_read(&COM1.io, &recv_char, 99) == 99)
{
// Write what's on the buffer from the receiver
io_write(&EDBG_COM.io, recv_char, 99);
}
// Reset the flag
reading_received = 0;
}
}
}
You seem to be coding for ASFv3 - v4 will trigger your receive callback for any incoming bytes, not only once when your buffer is full (and you have received every 99 characters).
That means that io_read will most probably never return 99 (because it was only a partial read of your message) and you will most probably never send anything back.
Note the docs say (Scroll down to "different read function behavior..."):
In ASFv4 a data reception type callback in a driver with a ring buffer is triggered for every received data.
The UART apparently is a driver with a ring buffer.
You need to repeatedly call io_read and sum up the number of received bytes until you have got 99. Only then proceed. The ASF docs have an example for that. Make sure you copy code from there that fits your version.
I need to read values form a distance sensor in volts. The sensor sends the voltages binary values to the MUC (Atmega8) and then the atmega8 communicates to my pc using USART with and RS232 cable. The readings displayed on the PC are weird random characters. I don't understand what am I doing wrong.
Here is my code
//USART communicating with Atmega8
#include <avr/io.h>
#include <inttypes.h>
#include <util/delay.h>
#include <string.h>
//1MHZ Baud 9600
#define F_CPU 1000000
char *Bestbelieve ="t \r\n";
void InitADC()
{
ADMUX=(0<<REFS1)|(1<<REFS1); // For Aref=internal;
ADCSRA=(1<<ADEN)|(0<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //Prescalar div factor =8
}
uint16_t ReadADC()
{
ADMUX=0x05;
//Start Single conversion
ADCSRA|=(1<<ADSC);
//Wait for conversion to complete
while(!(ADCSRA & (1<<ADIF)));
//Clear ADIF by writing one to it
//Note you may be wondering why we have write one to clear it
//This is standard way of clearing bits in io as said in datasheets.
//The code writes '1' but it result in setting bit to '0' !!!
ADCSRA|=(1<<ADIF);
return(ADC);
}
void Wait()
{
uint8_t i;
for(i=0;i<20;i++)
_delay_loop_2(0);
}
char USARTReadChar()
{
//Wait until a data is available
while(!(UCSRA & (1<<RXC)))
{
//Do nothing
}
//Now USART has got data from host
//and is available is buffer
return UDR;
}
void USARTWriteChar(char* data)
{
//Wait until the transmitter is ready
while(*data)
{ while(!(UCSRA & (1<<UDRE)))
{
//Do nothing
}
//Now write the data to USART buffer
UDR=*data;
data++;
}}
void USARTInit(uint16_t ubrr_value)
{
UBRRL = 12;
UBRRH = 0;
UCSRC=(1<<URSEL)|(3<<UCSZ0);
UCSRB=(1<<RXEN)|(1<<TXEN);
UCSRA=(1<<U2X);
}
int main()
{
uint16_t adc_result;
//Initialize ADC
InitADC();
USARTInit(12); //UBRR = 12
//Loop forever
while(1)
{
adc_result=ReadADC(); // Read Analog value from channel-0
char *result[15];
sprintf(result,"%d",adc_result);
Wait();
USARTWriteChar(adc_result);
/* The code continuously has t outputted and skipped lines.
*/
}
}
You are using sprintf to format your data into result. However, you then use USARTWriteChar on your binary value adc_result.
You need to print out result instead, presumably with a loop over the characters calling USARTWriteChar.