serial communication lost characters

Hello all!

I have been fighting with a problem of lost characters in serial communication that is not constant, some times it works OK but most of time do not receive the complete response (set of characters) from the GSM Modem. In the parameters sent to the functio I am not using the ‘time_out’ value to free time for readins the data.

The code is below:

#include <string.h>

boolean newData = false;
char x = 1;
const uint8_t power_pin = 7;
const uint8_t reset_pin = 8;

char SendATCmdWaitResp(char const *AT_cmd_string, uint16_t time_out, char const *response_string, byte lenght);

byte receiv_comp_string(char const *response_string, uint16_t time_out, byte lenght);


void setup() {
  // put your setup code here, to run once:
 Serial.begin(9600);
  pinMode(power_pin, OUTPUT);  // Switch ON the GSM Module
  pinMode(reset_pin, OUTPUT);  // Reset the GSM Module
 char input_buf[buf_len];
}

void loop()
{
  // put your main code here, to run repeatedly:
digitalWrite(power_pin, HIGH); // Switch ON the GSM module

delay(2000);

         x = SendATCmdWaitResp("AT+CREG?", 1000, "\r\n+CREG: 1,1\r\n\r\nOK\r\n\0", 21);

  Serial.println(x,DEC);
  
  
   //while(1);
}


char SendATCmdWaitResp(char const *AT_cmd_string, uint16_t time_out, char const *response_string, byte lenght)
               
{
  
  char ret_val = 0; 
  Serial.println(AT_cmd_string);
   
  char receivedChars[lenght];
  char rx =0;
  static byte num_chr = 0;
  newData = false;
 
 
 while (Serial.available() > 0 && newData == false)
               {
		rx = Serial.read();
               		
			receivedChars[num_chr] = rx;
			num_chr++;
                        
			if (num_chr >= lenght)
                            {
                             num_chr = lenght - 1;
                            // Serial.println(num_chr); // to test the loop
                             receivedChars[num_chr] = '\0'; // terminate the string
			      num_chr = 0;
			      newData = true;
			    }
                   }
 
             Serial.println(receivedChars); // test for right characters
 
 
       
            if ((receivedChars == response_string) == true)
                 {
                    ret_val = 1;
                 }
                else
                 {        
                 ret_val = 0;
                 }
           
              Serial.println(ret_val);// to test the return value
                return (ret_val);
                
        }

Also when I receive the correct data and do the strings compare always have the ‘false’ return.

Your hel is appreciated.

Thanks,
Manuel

I have been fighting with a problem of lost characters in serial communication that is not constant, some times it works OK but most of time do not receive the complete response (set of characters) from the GSM Modem.

And yet you have a 2 second delay in EVERY iteration of loop(). Get rid of that, and we'll talk.

            if ((receivedChars == response_string) == true)

By the way, it is impossible for the addresses to be equal, so this test will never return true.

PaulS,

Thanks for your inputs. The "Serial.reading" was made according one example I read in this forum as an example lesson on "how to read a 'char' and a 'string'". It was written by an expert in this forum.

Any way I am going to try to eliminate one of the loops.

I am trying to learn C and Arduino language I am not an expert, if was I would not ask for help.

Thanks and regards. Manuel

Hello PaulS!

Can you please comment now the code below?

It is running OK, it doesn't miss characters and the compare strings is working.

Can it be improved? Your comments will be appreciated.

void loop()
{
  // put your main code here, to run repeatedly:
digitalWrite(power_pin, HIGH); // Switch ON the GSM module

delay(2000);

         x = SendATCmdWaitResp("AT+CREG?", 1000, "\r\n+CREG: 1,1\r\n\r\nOK\r\n\0", 21);

  Serial.println(x,DEC);
  
  
   //while(1);
}


char SendATCmdWaitResp(char const *AT_cmd_string, uint16_t time_out, char const *response_string, byte lenght)
               
{
  
  char ret_val = 0; 
  Serial.println(AT_cmd_string);
   
  char receivedChars[lenght];
  char rx =0;
  byte num_chr = 0;
  newData = false;
  unsigned long lastTime = millis(); 
  
   
 while (Serial.available() > 0 )//&& newData == false)
               {
        receivedChars[num_chr] = Serial.read();
                 num_chr++;
               
                 if( millis() - lastTime > time_out) 
                   break;  
                               
                 if (num_chr >= lenght)
                     break;
                }
              
                     num_chr = lenght - 1;
                     receivedChars[num_chr] = '\0'; // terminate the string
                     
             Serial.println(receivedChars); // test for right characters


       
            if ((*receivedChars == *response_string) == true)
                 {
                    ret_val = 1;
                 }
                else
                 {        
                 ret_val = 0;
                 }
           
             // Serial.println(ret_val);
                return (ret_val);
                
        }

Thanks and regards, Manuel

Have a look at the examples in serial input basics - simple, reliable and non-blocking.

…R

            if ((*receivedChars == *response_string) == true)

?

Read a C programming tutorial. Look up how strings work.

Your code doth not compile, oh varlet. Please visit: http://snippets-r-us.com/

Hello Robin2,

The first code I wrote was exactly as the "serial input basics" the only difference was that your code is looking for a NULL cahracter, but, the string I receive from has several '\n' and '\r' and so, I can not look for those, I have to count the characters. You can give a look at the code I wrote (2 posts below and) and I will appreciate your comments.

The problem now is string compare it is returning a 'true' but it is false, I changes one of the strings and it continues given a 'true'.

I have been reading about pointers and string compare within functions but I didn't understand it well. The examples I found in Arduino are all out of functions. I think also that I have lack of basic knowledge or I am not smart enought to understand it or it may be want to learn C with 66 year old.

if ((*receivedChars == *response_string) == true)

If you can help I will appreciate.

Any way thanks for your reply and advise.

Regards, Manuel

You compare strings using strcmp(), not by comparing the addresses of the pointers or by comparing the addresses that the pointers point to.

PaulS, thanks!

I went read again arrays and string pointers and changed the code to the code below and its working, but I have to understand better the pointers, functions and arrays.

Thans for the clue. Manuel

if(!strcmp(receivedChars,response_string))

[quote author=Manuel Silva date=1431168492 link=msg=2224456] You can give a look at the code I wrote (2 posts below and) and I will appreciate your comments.[/quote] I don't know which Reply you refer to because it is clearly not the one 2 posts earlier - i.e it is not Reply #5 which is 7 - 2.

...R

strcmp() returns 0 if the strings are the same, +1 if the first string comes first, and -1 if the second string comes first.

It is much clearer to test for a match using if(strcmp() == 0). In my opinion...

PaulS, thanks for your reply and suggestion. I am going to follow it.

Regards,
Manuel

Hello all!

First of all I want to apologize for my ignorance.

I have the below function call to read 20 char and put a 'null' in the 21th char. The reading of the serial port some times works and some times not. Another thing that I do not understand is (again, forgive my ignorance) independently of RX input receive or not chars, or independently of connect to ground or 5V the loop for reading the characters complete the 20 cycles before the time_out ends. Is it some thing wrong with the code? Another thing that I notice is I have more problems with the IDE version 1.6.4 than the 1.0.5, does it makes any sense?

Your help is appreciated, because the code some times work some times not.

oid setup() {
  // put your setup code here, to run once:
 Serial.begin(9600);
  pinMode(power_pin, OUTPUT);  // Switch ON the GSM Module
  pinMode(reset_pin, OUTPUT);  // Reset the GSM Module
 char input_buf[buf_len];
}

void loop()
{
  // put your main code here, to run repeatedly:
digitalWrite(power_pin, HIGH); // Switch ON the GSM module

delay(2000);

         x = SendATCmdWaitResp("AT+CREG?", 4000, "\r\n+CREG: 1,1\r\n\r\nOK\r\n\0", 21);
         
         if (x==1) Serial.println("Modem ligada a rede");

  
  
   //while(1);
}


char SendATCmdWaitResp(char const *AT_cmd_string, uint16_t time_out, char const *response_string, byte lenght)
               
{
  
  char ret_val = 0; 
  Serial.println(AT_cmd_string);
  //Serial.println(response_string); 
  char receivedChars[lenght];
  char rx =1;
  byte num_chr = 0;
  newData = false;
  unsigned long lastTime = millis(); 
  
   
 while (Serial.available() > 0 )//&& newData == false)
               {
        receivedChars[num_chr] = Serial.read();
                 num_chr++;
               
                 if( millis() - lastTime > time_out) 
                   break;  
                               
                 if (num_chr >= lenght)
                     break;
                }
              
                     num_chr = lenght - 1;
                     receivedChars[num_chr] = '\0'; // terminate the string
                     
             Serial.println(num_chr); // test for right characters


                 if(strcmp(receivedChars,response_string) == 0)
              //if ((*receivedChars == *response_string) == true)
                 {
                 ret_val = 1;
                 }
                else
                 {        
                 ret_val = 0;
                 }
           
                Serial.println(ret_val);
                return (ret_val);
                
        }

Thanks in advane for your help. Manuel

If your code works it is by accident because you do not check that you have received 20 characters and characters arrive much slower than the Arduino works.

Is there any reason not to use one of the simple examples I gave you in serial input basics ? If it does not do what you want tell me and I may be able to suggest a simple adjustment.

...R

http://www.gammon.com.au/serial

Robin2 thanks!

Do you think the code below is Ok?

while (Serial.available() > 0 && (num_chr < lenght - 1))
            {
                receivedChars[num_chr] = Serial.read();
               	num_chr++;
               
                 if( millis() - lastTime > time_out) 
                   break;  
                               
                 if (num_chr >= lenght)
                     break;
               
           } 
                     num_chr = lenght - 1;
                     receivedChars[num_chr] = '\0'; // terminate the string

thanks,
Manuel

No, because you assume the serial data will arrive really quickly, which it won’t. See my link above, please.

[quote author=Manuel Silva date=1431378103 link=msg=2227961] Robin2 thanks!

Do you think the code below is Ok?[/quote] It is not the code I proposed. You can't seriously expect me to write a second version when I have already provided a working example ?

...R

Robin2 and Nick Gammon,

Thanks for being patience with me. I found the problem, it was in front of my eyes and I was not seeing it.

I know a little of AVR assembly and also a little of C and used the UART several times to decod chars and strings and I do not know why I didn't remember that I should look for the string start. I was making always the same mistake.

I apologize to give you so much work.

Thanks and regards, Manuel