I'm fairly new to the entire embedded C environment and am having a hard time reading in a string of ascii characters into a char array using the read function. I have no problems reading in one byte but keep running into issues when reading in a string of say 25 characters since the function will only hold until at least one byte has been read.
while (n < 25){
n += read( fdserial, buffer, 1);
}
But the buffer just starts at 0 during every read and the entire string never makes it into the char array. If I try to address only a specific spot in the buffer, such as buffer[j] and then increase j with ever loop I get an initializing error.
I'd greatly appreciate it if someone could steer me in the right direction or even post an example.
I'm trying to read in a data string from a logging board, formatted like this "05/12/09,16:08,3.56,34.5"
I want to then write that string to a txt file on an SD card and then send it out via a TCP socket to a Flex application.
I've got the file writing figured out and I can communicate with Flex via a TCP socket but I can't seem to read in more than 1 character at a time via serial or TCP. I've just realized it might have something to do with the way i'm testing things at the moment since i'm using the MTTY window to input serial data.
I've set it up so Flex sends a one-character command as to what operation the netburner should perform, then netburner then launches a function which will hopefully read in each data string (new one gets sent every 30s) and write it to file then send it over TCP to be formatted by Flex.
I just can't get it to constantly add my inputted characters into the read array, it just does the first one then stops. I got the same behavior using you're suggested method.
#define BUFF_SIZE (100)
char buffer[BUFF_SIZE];
int n = 0;
while ( n < BUFF_SIZE ){
n += read( fdserial, buffer+n, BUFF_SIZE-n);
if( *buffer[n-1] == '\0' ) // if the last char read was a null char, end of string
break;
}
This will work in cases where you know you will only receive a single string per read. If the PC app sends more then one string at a time you will need to do a similar loop but only read a 1 char each loop instead of "BUFF_SIZE-n". This will prevent you from reading part of the next string you may have received.
In response to seulater's post, be very careful to realize that
read( fdserial, buffer, 25);
is only guaranteed to return one char, although it MAY return up to 25. It depends what's actually available in the buffer.
This means that sometimes you will not get all that you ask for and you need to account for this by reading the number returned and adjusting the pointers typically to the stored (received) data, as well as (perhaps) to the number you may ask to read the next time This is a bit counter-intuitive, but there are good reasons not to force the system into waiting for characters that are not there yet. By returning only what is actually available, it lets the system do more productive things until chars eventually do become available. I also believe that if speed matters, it usually makes the most sense to read ad store in big chunks as many as are available and then to parse them later as opposed to reading, storing and possibly parsing char by char.
#define BUFF_SIZE (100)
char buffer[BUFF_SIZE];
int n = 0;
while ( n < BUFF_SIZE ){
n += read( fdserial, buffer+n, BUFF_SIZE-n);
if( *buffer[n-1] == '\0' ) // if the last char read was a null char, end of string
break;
}
what is the reason for using a pointer to buffer ? I.E. " *buffer[n-1] == '\0' "
would not using " buffer[n-1] == '\0' " accomplish the same thing ?
The line
if( *buffer[n-1] == '\0' )
contains the bug.
The correct line:
if( buffer[n-1] == '\0' )
or
if( *(buffer+n-1) == '\0' )
Note, that above search for the finishing character assumes typical (but not guaranteed) case : the finishing character is the last in some read chunk.
In case of the read chunk contains the last characters of the message are followed by the first characters of the next message, the finishing character will not be detected.
seulater wrote:I would rather ask and be embarrassed and learn, than to not ask out of embarrassment and an remain less knowledgeable.
#define BUFF_SIZE (100)
char buffer[BUFF_SIZE];
int n = 0;
while ( n < BUFF_SIZE ){
n += read( fdserial, buffer+n, BUFF_SIZE-n);
if( *buffer[n-1] == '\0' ) // if the last char read was a null char, end of string
break;
}
what is the reason for using a pointer to buffer ? I.E. " *buffer[n-1] == '\0' "
would not using " buffer[n-1] == '\0' " accomplish the same thing ?
That was a typo on my part.
if( buffer[n-1] == '\0' )
or
if( *(buffer+n-1) == '\0' )
is correct.
Note, that above search for the finishing character assumes typical (but not guaranteed) case : the finishing character is the last in some read chunk.
In case of the read chunk contains the last characters of the message are followed by the first characters of the next message, the finishing character will not be detected.
This is true. This can easily be solved by reading a single char at a time but this can be a hit on performance like Ridgeglider said. If speed is an issue you can create circular buffer for parsing data. Read all the data in large chunks to the circular buffer and then parse out the strings after the read.