NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.
Microcontroller Programming » Sending a string in UART
Hi! As the title says I am trying to send a string through UART.
I recently got the well-known 434 MHz RF Link Transmitter/Receiver from sparkfun in the mail.
I searched some on the net and found some examples with sending some bytes between two micro controllers with a simple encoding. The problem now is that I want to send a whole string as my "data packet" instead of the 8 bit integer. When I try to implement it within the code I was already using I get a warning in the compiler saying I am "making an integer from a pointer without a cast". I guess it has something to do with the code tries to send my string as an int. Don't worry about the while loop, I just didn't remove it from the original code which just sent a byte repeatedly for testing purposes.
What am I doing wrong?
Main code:
int main(void)
{
/****************INITIALIZATIONS*******************/
lcd_init(); //Initialize lcd
DDRC |= (1<<PC4);
uartInit(); // initialize the UART (serial port)
uartSetBaudRate(2400);// set the baud rate of the UART for our debug/reporting output
rprintfInit(uartSendByte);// initialize rprintf system
receive(); //Go to the subroutine responsible for receiving, it is located in "rf_rx.c"
//transmit(); //Go to the subroutine responsible for transmitting, it is located in "rf_rx.c"
return 0;
}
rf_rx.c:
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/delay.h"
// Get Byte Subroutine
int GetByte(void) // Subroutine to get a byte from the UART
{
//Syntax is var= GetByte(); where var is any variable capable of storing a byte
while((UCSR0A&(1<<RXC0)) == 0); // wait until a byte is received
return UDR0; // once a byte is received send back to the program the byte
}
// Send Byte Subroutine
void SendByte(char c) { //Subroutine to send a byte to the U
}
// The Receive Subroutine
void receive(void)
{
int start; // create variable named start
int addr; // create variable named addr
int data; // create variable named data
int chksum; // create variable named chksum
while(1) // Do an infinite loop
{
/ == (start+addr)) //if chksum is equal to data+addr then
{
lcd_line_two();
FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
fprintf_P(&lcd_stream, PSTR("string: %c "), data);
}//endif
}//endif
} //endwhile
} //end sub
// The Transmit subroutine
//Sample program for transmitting packet with contents - 0x55, 0x8E ,0x27,0xB3
void transmit(void)
{
int start; // create variable named start
int addr; // create variable named addr
char data; // create variable named data
int chksum; // create variable named chksum
start = 0x55 ; // put 0x55 into the variable
addr = 0x8E; // put 0x8E into the variable
data = ("hey"); // put 0x27 into the variable
chksum = (addr + start); // put the checksum into the variable
while(1) //run an infinite loop
{
SendByte(start); // Send start byte
SendByte(data); // Send data byte
SendByte(addr); // Send address byte
SendByte(chksum); // Send checksum byte
delay_ms(2); // delay for 2 milliseconds
PORTC |= (1<<PC4);
delay_ms(20);
PORTC &= ~(1<<PC4);
} //endwhile
}//endsub
Thanks!
Hi met_fredrik,
Which line is the compiler saying there is a problem in. I see an issue on line 63. You are putting a string, which essentially is a pointer to a character array into a char variable. I think it might throw that warning when you try to do that.
Humberto
Thank you for your answer!
That's the line my compiler is talking about.
Anyway, I don't quite understand the problem. Shouldn't this work?
Also the example I have modified here talks about bytes, I mean, I am sending one byte for start, one for address, and then a whole string, and then one byte again. How is this handled by the USART? Can I really do it like this? Just using single bytes and big variables containing lots of bytes in the same mix?
Hope there is a simple way of explaining this to me!
-Fredrik
EDIT:
rf_rx.c:64: warning: assignment makes integer from pointer without a cast
is the error I get.
This is really line 63 in the code I posted.
The SendByte function sends exactly one byte. If you want to send a string you'll have to send each byte of the string separately and the receiver has to know where the string bytes start and end so it can reconstruct the string on the receiving end.
Okay, this seems doable in my application because I am going to send a string that I know the exact length of each time.
But what if I wanted to send a string with unknown length?
Can I, maybe, send the length of the string as a byte before the actual string is sent and then store it again with the correct length in the receiver?
Your solution of sending the length of the string first is a good solution, however you can get around it by knowing how strings work in C. Strings are just arrays of chars terminated with a null character (0), with each value in the array holding one character. In C when you do something line "Hi" the expression evaluates to a pointer to first element in the array that is holding your string. That first memory location holds the character H, the second holds the character i, and the third location holds 0 (note that is the actual value 0, not the ASCII representation of the character 0).
To send strings you can just send them one character at a time, and send the null terminating byte at the end, this will signal the receiver that the full string has come in. In this scheme you will still have to have a maximum size that you can receive, since you need to allocate that memory before hand on the receiver side. Otherwise you would not have any place to put the bytes as they come in.
Hope that makes sense.
Hello,
I too am having trouble with strings right now. I have been searching through the threads for
similar situations but I don't see my question asked anywhere. Anyway since this thread touches
real close I want to ask:
How do you compare a string? I assume from what I read that there is no such thing as an
actual string variable. Instead it is always an array of char variables right? If so,
I understand that "looping out" each char can "appear" to be a string when output one after
another to lcd or uart but what about a comparison of the entire collection of characters as
a string? For instance;
If I type "flash" it is actualy represented as:
int array=0;
char My_string[20];
My_string [array] = {'f','l','a','s','h'};
right?
How can I tell the compiler to compare that? I dont want a pre defined char string, it has to be
variable and then compared to a set comparison... something like this:
if (My_string[array] == "flash" //or {{'f','l','a','s','h'}
{//do something};
what is the syntax for this? or what is the appropriate way to perform such a check?
Thanks so much!
There are a couple of functions included in avr-libc that you can use for this. Of particular interest to you will be the strstr() function, or the strcmp() function,.
Note that both of these functions expect the string to be in RAM, not program memory. So if you are storing the string to compare against in program memory you will have to copy into RAM first. Hope that gets you started!
Thank you Humberto!
I will look at this right away!
Ok,
strcmp() looks like what I want... I still have a qustion though:
it says that the function returns an integer based on whether s1 is less than
the same as or greater than s2. What does that mean? What I am confused about
is what exactly is being compared. Is it the total value of the characters in the
char array? or is it the number of characters in the char array?
If the former then wouldnt it make mistakes? like if the total value of the characters
m,e,s,s may be the same as the total character value as a,a,a,a for instance.
If the later then its not going to be accurate at all as
m,e,s,s would come up the same as t,r,u,e.
Or is there another kind of value being compared like the exact value of each char 1 by 1
in both strings? cause that would work. What Am I missing in all of this?
thank you for your patience,
T.C.
I believe this is a good explanation.
One of the most useful things any developer can do, is learn how things sit in memory- it's memory your working with, everything else is generic data.
Strings aren't difficult. They are just bytes, consecutively spaced in memory. For the OP, the original error was: "making an integer from a pointer without a cast".
All that means is that you are trying to treat the address (location) of an object (contents) as a content value, not an address OF a content value.
Everything has to sit in memory somewhere.
If you want to compare to strings, either find a library that contains a function to do it, or write it yourself.
/* PROTOTYPE */
bool strcompare(char*,char*);
/* FUNCTION */
bool strcompare(char *str1,char *str2)
{
if(strlen(str1) != strlen(str2)) /* lengths don't match */
return(FALSE);
while((str1 != 0x00) && (str2 != 0x00)) /* loop through until hit end-marker */
if(str1++ != str2++)
return(FALSE);
return(TRUE);
}
This is from my head, quick and dirty- probably needs some fixes; gives you a start.
BM
tchilzer2-
"it says that the function returns an integer based on whether s1 is less than the same as or greater than s2. "
The function can be used to sort strings- By knowing whether one string evaluates as 'less than' or 'greater than' another string, you can order it. If they're equal, it returns zero (as I recall).
Awsome! Its a lexicoographic comparison! That clears it right up and I can use strcmp()
to do what I need to. Thank you for that very clear explanation Treymd! This concept has
eluded me for the past year even with c++. That explanation took all the uncertainty
right out of my head!
Boba, I am slowly working my way toward learning how to use more advanced programming techniques
I want to thank you for posting your example because I know it will be there when I come to it.
Oh my! Please forgive my exceeding frustration.
what ever happened to a string = b string or if a string = b string?
Jeez whats all this pointer stuff? why am I comparing const char's
Im trying to compare variable characters! I dont know if I am assigning
my variable char array wrong
char cmd_flash[6]={'f','l','a','s','h'};
or what const char *s1 is supposed to be... a pointer to what?
here is what I got ... please explain to me what in the world is so
darn complicated with comparing a string!
char cmd_flash[6]={'f','l','a','s','h'};
char cmd_str[16];
int ltr=0;
input cmd_str[ltr]; // I know this middle part isn't actual code... I am
roughing it as a general whats goin on.
ltr ++ and repeat // basically
int strcmp (const char* cmd_str[], const char* cmd_flash[]);
if (strcmp == 0){do something}
why wont this work?
strcmp is a function, you can either store its result in a variable, or use it within your if statement, passing it the parameters within, like I do in the following:
// char array way of initializing
// this will work, it's just not as easy as the next method
//char str1[] = {'a','b','c','\0'};
//char str2[] = {'1','b','c','\0'};
// C-string or char* way of initializing
char* str1 = "abc";
char* str2 = "def";
if ( strcmp(str1,str2) == 0)
{
printf("strings are equal");
}
else if ( strcmp(str1,str2) < 0)
{
printf("str1 is less");
}
else
{
printf("str1 is greater");
}
the backslash-0 in the char arrays is a null character, terminating the string. If you use double quotes, the c compiler adds this for you, note that the null char is there in memory, so a 3 char string takes up 4 bytes in memory.
By the way you CAN manipulate a C-string with the bracket operators if you are wondering. I'm a little rusty, but I believe the compiler treats a C-string just like a char array, so str1[0], str1[2], etc. are valid ways of manipulating char* str1
Please log in to post a reply.