Reading Consecutive Serial Data MOD5270

Discussion to talk about software related topics only.
Post Reply
mezz64
Posts: 9
Joined: Mon Feb 02, 2009 8:50 am

Reading Consecutive Serial Data MOD5270

Post by mezz64 »

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.

I've tried something similar to this:

Code: Select all

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.

Thanks!
-John
seulater
Posts: 445
Joined: Fri Apr 25, 2008 5:26 am

Re: Reading Consecutive Serial Data MOD5270

Post by seulater »

Not sure what your trying to accomplish.

if you want to get 25 chars at a pop then just make it this.

char buffer[26];
read( fdserial, buffer, 25);

then all your data will be buffer[0] - buffer[24].

if you want to read a char at a time. then the way you showed in your example the data will will always be buffer[0] each time through.
mezz64
Posts: 9
Joined: Mon Feb 02, 2009 8:50 am

Re: Reading Consecutive Serial Data MOD5270

Post by mezz64 »

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.

Any help is appreciated.
User avatar
lgitlitz
Posts: 331
Joined: Wed Apr 23, 2008 11:43 am
Location: San Diego, CA
Contact:

Re: Reading Consecutive Serial Data MOD5270

Post by lgitlitz »

You keep reading a single byte to the same address in the buffer:

Code: Select all

while (n < 25){
      n += read( fdserial, buffer, 1);
   }
You should try the following:

Code: Select all

#define BUFF_SIZE (25)
char buffer[BUFF_SIZE];
int n = 0;
while ( n < BUFF_SIZE ){
      n += read( fdserial, buffer+n, BUFF_SIZE-n);
   }
This will make sure you read the data to the correct part of the buffer and also make sure you never read past the buffer size

-Larry
User avatar
lgitlitz
Posts: 331
Joined: Wed Apr 23, 2008 11:43 am
Location: San Diego, CA
Contact:

Re: Reading Consecutive Serial Data MOD5270

Post by lgitlitz »

You can also keep reading until you see the null terminator at the end of the string. This will allow you to read strings of different sizes.

Code: Select all

#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.

-Larry
mezz64
Posts: 9
Joined: Mon Feb 02, 2009 8:50 am

Re: Reading Consecutive Serial Data MOD5270

Post by mezz64 »

Thank You! :)

That was exactly what I needed to know, I wasn't aware of the "buffer+n" syntax and figured it was something simple.

Thanks Again!
Ridgeglider
Posts: 513
Joined: Sat Apr 26, 2008 7:14 am

Re: Reading Consecutive Serial Data MOD5270

Post by Ridgeglider »

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.
seulater
Posts: 445
Joined: Fri Apr 25, 2008 5:26 am

Re: Reading Consecutive Serial Data MOD5270

Post by seulater »

I would rather ask and be embarrassed and learn, than to not ask out of embarrassment and an remain less knowledgeable.

in the example of:

Code: Select all

#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 ?
User avatar
yevgenit
Posts: 84
Joined: Fri Apr 25, 2008 12:47 am
Contact:

Re: Reading Consecutive Serial Data MOD5270

Post by yevgenit »

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.

in the example of:

Code: Select all

#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 ?
Yevgeni Tunik
Embedded/RealTime software engineer
https://www.linkedin.com/in/yevgenitunik/
________________________
User avatar
lgitlitz
Posts: 331
Joined: Wed Apr 23, 2008 11:43 am
Location: San Diego, CA
Contact:

Re: Reading Consecutive Serial Data MOD5270

Post by lgitlitz »

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.
Post Reply