CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Help on RS232 and string

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
morind79



Joined: 11 Apr 2008
Posts: 2

View user's profile Send private message

Help on RS232 and string
PostPosted: Sun May 02, 2010 10:55 am     Reply with quote

Hi all,

I am sorry, I did some C coding a long time ago, and I need to create a program but it does not work.

Here is what I want to do : the Pic receive data from the serial port, and it should get some value from it.

Here is the data received :
Quote:

TDETAT 000000 B
ADCO 050622013932 8
OPTARIF HC.. <
ISOUSC 45 ?
HCHC 000000000 F
HCHP 000000001 T
PTEC HP..
IINST 000 W
IMAX 000 ?
PAPP 00000 !
HHPHC A ,


I want to get the HCHC and HCHP value 000000000 and 000000001 respectively.

Here is my code:
Code:

char etiquettes[12][16] = {"ADCO", "OPTARIF", "ISOUSC", "HCHP", "HCHC", "PTEC", "IINST", "IMAX", "PAPP", "HHPHC", "MOTDETAT", "ADPS"} ;
char valeurs[12][18];
char checksum[255];
char ligne[30];
int res;

/*------------------------------------------------------------------------------*/
/* Test checksum d'un message (Return 1 si checkum ok)            */
/*------------------------------------------------------------------------------*/
int checksum_ok(char *etiquette, char *valeur, char checksum)
{
   unsigned char sum=32 ;      // Somme des codes ASCII du message + un espace
   int i ;
 
   for (i=0; i<strlen(etiquette); i++) sum=sum+etiquette[i];
   for (i=0; i<strlen(valeur); i++) sum=sum+valeur[i];
   sum=(sum&63)+32;
   if (sum==checksum) return 1;   // Return 1 si checkum ok.
   //syslog(LOG_INFO, "Checksum lu:%02x   calculĂ©:%02x", checksum, sum) ;
   return 0;
}

char *readSerial(char *key)
{
  char sep[3], *ptr;
  char car_prec;
  char ch;
  int id, i=0;
  // Space is the separator
  strcpy(sep," ");
  // Read data (0d 03 02 0a => end transmission and start of a new one)
  do
  {
    car_prec=ch;
   ch=getc();
  }
  while (!(ch==0x02 && car_prec==0x03));  // Wait for the end and begining of transmission
  do
  {
    ch=getc();
  }
  while (ch!=0x03);                      // Wait for the end of transmission.
  for (id=0; id<12; id++)
  {
    // Read the complete line
     gets(ligne);
     // Split ligne in 3, separator is space
     ptr = strtok(ligne, sep);
     while (ptr!=0)
    {
      // 3 fields to read
      if (i<3)
      {
        if (i==0) strcpy(etiquettes[id], ptr);
        if (i==1) strcpy(valeurs[id], ptr);
        if (i==2) strcpy(checksum, ptr);
        i++;
      }
      ptr = strtok(0, sep);
    }
    // Test if the checksum is correct   
     if (!checksum_ok(etiquettes[id], valeurs[id], checksum[0]))
     {
      // Test if the value is the one we are interested of
      if (etiquettes[id]==key)
      {
        return(valeurs[id]);
      }
     }
  }
   
}

I am prety sure the code is not correct (pointer...)

If you have some advices :-)

Thanks

Denis
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun May 02, 2010 4:13 pm     Reply with quote

A few comments:
1)
Code:
(etiquettes[id]==key)
This is not the right method for comparing strings. Use strcmp instead.

2) If you don't find a match the function is exited without a return value.

3) You are reading a fixed number of 12 lines. I only count 11, or is the line with code 0x03 also terminated by a newline character? Better would be to change the code and not to assume a fixed number of lines but to read until a 0x03 is found. This way you can also reduce memory consumption by not declaring all arrays as 12 but only use a single array for each type.

4)
Code:
  do
  {
    car_prec=ch;
   ch=getc();
  }
  while (!(ch==0x02 && car_prec==0x03));  // Wait for the end and begining of transmission
  do
  {
    ch=getc();
  }
  while (ch!=0x03);                      // Wait for the end of transmission.
you are waiting for a new message to start, but then you skip another whole message. Why?
morind79



Joined: 11 Apr 2008
Posts: 2

View user's profile Send private message

PostPosted: Mon May 03, 2010 1:26 am     Reply with quote

Hi,

Thank you for your answer. I rewrite this part of code completely here is the new code :

Code:

// Here is the description of a transmission :
//
// 0x02
// LF (0x0A) Label (4 to 8 characters) SP (0x20) Data (1 to 12 charaters) SP (0x20) CRC (Character control) CR (0x0D)
// ...
// 0x03

char *readSerial(char *key)
{
  char label[10];
  char data[14];
  char crc;
  int il, id;
  char ch;
  int field=0;
  // Empty strings
  label[0]='\0';
  data[0]='\0';
  crc='\0';
  // Loop waiting for the beginning of transmission (0x02)
  do
  {
    ch=getc();
  }
  while (ch!=0x02);
  // Read until end of transmission (0x03)
  do
  {
    ch=getc();
    // End of field line 0x0D
    if (ch==0x0D)
    {
      field=0;
      if (!checksum_ok(label, data, crc))
       {
        // Test if this is the required key
        if (strcmp(label, key)==0)
        {
          return(data);
        }
      }   
    }
    // Get field 1 (Label)
    if ((field==1) && (ch!=0x20))
    {
      label[il]=ch;
      il++;   
    }
    // Get field 2 (Data)
    if ((field==2) && (ch!=0x20))
    {
      data[id]=ch;
      id++;   
    }
    // Get field 3 (CRC)
    if ((field==3) && (ch!=0x20))
    {
      crc=ch;
      label[il]='\0';
      data[id]='\0';   
    }
    // First field after 0x0A
    if (ch==0x0A)
    {
      field=1;
      il=0;
      id=0;
    }
    // Each 0x20 is a separator for a new field
    if(ch==0x20) field++;
  }while (ch!=0x03);
   return('\0');
}


I think this will be better handled like this. I do not use gets anymore.
Hope it is the right way.

Br,
Denis
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon May 03, 2010 1:55 pm     Reply with quote

Be careful, the first iteration of the loop has the variables 'field', 'il' and 'id' not initialised. This can lead to data loss and/or memory corruption by writing out of array bounds.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group