Hello,
I'm reading data in from a serial device and I'm having trouble parsing the data into a human readable format. The serial device sends out a 75 byte packet at a rate of 3hz. Using read() I get data from the serial port as it becomes available, and write it to a char array.

The overall program is quite large so I've tried to include the pertinent part of the program (I didn't write the rest of it, and it function properly if I don't do anything to it, it just streams raw serial data through a TCP socket). Basically the 75 byte packet consists of 25 5byte 'frames'. Each frame begins with 1 and the 1/25 frames has it's second bytes least sig bit set to 1. The code snippet below (partially provided as an example by the device manufacture[PDF]) should read all available data from the serial port and write it into char array c. Then it should step through the buffer and find the '1' frame header and then check to see if the next bytes lsb is 1 and check that the frame checksum is correct. If the beginning of a new packet is found The RCV_Flag is set to one, and I should be able to begin parsing the data:

int frm_chksum = 0; 
char *buf_pointer;
char buf[1024];
int RCV_Flag;
int csize; 

... setting up connections... 
while(1){
... some stuff pertaining to TCP writing/reading...
            
   if ((csize = read(sd2, buf, 200)) >= 200) {
      buf_pointer=buf;
      for ( ;buf_pointer < RCV_BUFFER_MAX; ++buf_pointer){
	RCV_Flag = 0;	
      	if (*buf_pointer == 1){
		frm_chksum = *buf_pointer + *(buf_pointer+1) + *(buf_pointer+2) + *(buf_pointer+3);
	   if (*(buf_pointer+1) & 0x01 && *(buf_pointer+4) == frm_chksum){
      	        RCV_Flag = 1;  
      		break;                      
      	   }
      	}
   }
}

My problem is that I'm having trouble figuring out what format 'buf' should be in when I'm trying to manipulate it and how to get it to that format. It doesn't make sense to me that I could calculate a checksum by adding elements of a char array, but the above code does make it into the loop where *buf_pointer==1, but the checksum never seems to be calculated correctly. I tried converting it to an integer array:

...

int buf_int[1024];
int *pbuf_int;
pbuf_int=&buf_int[0];
for(i=0;i<strlen(buf);i++){
   *(pbuf_int+i)=(int)buf[i];
}

This gives me a bunch of negative numbers that I know aren't right. This might have something to do with going from char(1 byte) to int(4 bytes), but I don't know how to rectify this situation and I'm not even sure I have to.

So my overall question(s) would be what is the best format to parse serial data in, and if I should be converting it to a int array how do I go about doing that? Also presumably there will be packet 'stragglers' before and after each 'packet'. Is it acceptable practice to just declare a char buf_tmp[1024] and write any unused bytes from buf[] to it and then after the next read to do

strcat(buf_tmp,buf); 
strcpy(buf,buf_tmp);

Do I have to be careful about clearing buf_tmp in some special way after each iteration through the while(1) loop?

Sorry for asking a bunch of different questions in one post. Any help would be greatly appreciated.

Thanks!

Do you need to put an end of string char into buff[0]? '\0'

Yes - even if you don't NEED to, you need to, ;) and I would. Just good defensive programming when dealing with different strings, going into the same variable.

Edited 5 Years Ago by Adak: n/a

I would say dont use a char array to read data from serial port. Use it as int array, and convert the data you get in hex. I am sure you will find this helpful.
I am saying this from experience. I have done serial interfacing using C enough times. And whenever I had to read something from serial port, I just read it as hex and then manipulated the way I want.

Edited 5 Years Ago by Software guy: n/a

This article has been dead for over six months. Start a new discussion instead.