comparing answer from serial device

Hello
(I know I have ask many question here about this subject -and I’m sorry ,but i want it to work)

My code need to do simple thing

  1. press a button.
  2. send “AT” to serial device(modem)
  3. get and print the all response from him.
  4. see if the answer is OK - yes or not.

the main problem is that i get “true” answer once every 7 pressing
I can really use help and guidance

this is the code :

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
int test=7;

void setup()  
{
  pinMode(test,INPUT);
  pinMode(13,OUTPUT);
  Serial.begin(19200); // Open serial communications and wait for port to open:
  delay(1500);
  Serial.println("Ready to work!");
  mySerial.begin(19200);
  delay(1500);

}

void loop() 
{
  if (digitalRead(test)==HIGH)
  {

    char response[10];
    char finalPart[2];
    mySerial.println("AT");
    delay(2000); //
    if (mySerial.available() >8)
    {
      for (int i=0;i<9;i++)
      {
        response[i]=mySerial.read();
      }//end for i
      
      Serial.print(millis() /1000);
      Serial.print("   -   this is the full respons: ");
      Serial.println(response);
      finalPart[0]=response[6];
      finalPart[1]=response[7];
      //finalPart[2]=('\0');
      Serial.print("this is final - ");
      Serial.print(finalPart[0]);
      Serial.println(finalPart[1]);
      Serial.println(finalPart);
    }
    if ((finalPart[0]=='O')||(finalPart[1]=='K'))
    {//what to do answer OK
      digitalWrite (13,HIGH);
      Serial.print(millis() /1000);
      Serial.println("Modem is working!!!!");
      delay (1500);
      digitalWrite(13,LOW);
      Serial.println("******************");
    }// end answer OK
    else
    {//what to do if modem not ready
      Serial.print(millis() /1000);
      Serial.println ("  -Modem not ready yet......");
      Serial.println("******************");

    } //end modem not ready

  }//end if

}//end loop

in the file you can see what happens when I press 3 time the push button

    if (mySerial.available() >8)
    {
      for (int i=0;i<9;i++)
      {
        response[i]=mySerial.read();
      }//end for i

If you are expecting “OK” to come back, why are you waiting for 9 or more characters? Even with my shoes on, I can tell that “OK” is less than 9 characters.

let me explain: when I send "AT" this is the answer I get AT newline (CR,LF,CR,LF) OK newline (CR,LF)

There’s a pattern there that you should recognize. “AT”, “”, “OK”.

You should read each character, as soon as it arrives. Store the character if it is not a or . The is a trigger, then, to use the stored data. What you should have stored, then, is “AT”, “”, or “OK” (or something else if the response was not OK).

You need to understand that serial communication is NOT synchronous. You send a command. Some time later, the device responds.

You can force the process to be synchronous, by blocking in a getResponse() function (possibly three times) until the arrives. That involves a while loop that spins until there is a character to read AND the character is .

Here’s a handy little “readline” function. It will return -1 until it has a string ending in a character. characters are ignored and thrown away. When it has a string it returns the number of characters in that string.

int readline(int readch, char *buffer, int len)
{
  static int pos = 0;
  int rpos;
  
  if (readch > 0) {
    switch (readch) {
      case '\n': // Ignore new-lines
        break;
      case '\r': // Return on CR
        rpos = pos;
        pos = 0;  // Reset position index ready for next time
        return rpos;
      default:
        if (pos < len-1) {
          buffer[pos++] = readch;
          buffer[pos] = 0;
        }
    }
  }
  // No end of line has been found, so return -1.
  return -1;
}

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  static char buffer[80];
  if (readline(Serial.read(), buffer, 80) > 0) {
    Serial.print("You entered: >");
    Serial.print(buffer);
    Serial.println("<");
  }
}

o.k. so let me see if I understand correctly - I need to ignore the CR and LF
so can I do something like this:

if (mySerial.available() >8)
    {
      for (int i=0;i<9;i++)
      {
        if ((mySerial.read()==\n)||(mySerial.read()==\r))
        break;
        else
        response[i]=mySerial.read();
      }//end for i

I’m sure I have mistake in the comparing part ,and how to make it ASCII - but the question is if the logic is good?

Thanks ,

if ((mySerial.read()==\n)||(mySerial.read()==\r))

Single quotes for single characters.

Also, don't do serial reads like that - if the left side is true, the right side won't get called. Put the character in a variable, then compare.

OK but I don't care if the left side or the right side is true - for me both of them are not good. - so when when one of them is bad - go out no?

No.

You're doing 2 reads, which will consume 2 characters from the input buffer. You only want to compare 1 character - the "current" one.

Do a read as the first thing into a variable, then do all your comparisons and operations using that variable.

Your device is sending 3 strings. You should NOT expect a fixed number of characters comprising all three strings. Deal with the 3 possibly variable length strings independently.

majenko

OK
and how do I do this ?

this is what I have done ,but now I get nothing

 char response[6];
    char n[4];
    char r[4];
    char finalPart[2];
    mySerial.println("AT");
    delay(800); //
    if (mySerial.available() >8)
    {
      if (mySerial.read()=='\n')
      {for (int t=0;t<3;t++)
        n[t]=mySerial.read();
      }
      else if (mySerial.read()=='\r')
      {for (int y=0;y<3;y++)
       r[y]=mySerial.read();
      }
      
      else  for (int i=0;i<5;i++)
      {
        response[i]=mySerial.read();
        }
      }//end for if

again - maybe my logic is wrong …

again - maybe my logic is wrong .....

Yes, it is. As is your ability to read the posts that said to store the character that was read, not read each time you want to see what a character is.

      if (mySerial.read()=='\n')

If it isn't a carriage return, that character is lost forever.

sorry(again......) but when I do this

if (mySerial.read()=='\n')

and the read give my 'K' he need to past to next step , to see else if (mySerial.read()=='\r') no?

If you want to pick out a red or blue shirt from your closet, and the first one is blue, do you throw it away because it is not red? That is what you are doing with your serial data.

Compare this:

shirt = pickOne();
if(shirt.color == red)
  wearIt();
else if(shirt.color == blue)
  wearIt();

to this:

if(pickOne().color == red)
   wearIt();
else if(pickOne().color == blue)
  wearIt();

Now, think about what happens if there is only one shirt in the closet, and it is blue. In the first block of code, the shirt is removed from the closet (leaving it empty), and then the color is compared to red. The shirt isn't red, so you don't put it on. Then, the color is compared to blue. The shirt is blue, so you put it on.

In the second block of code, the shirt is removed from the closet (leaving it empty), and then the color is compared to red. The shirt isn't red, so you don't put it on. Instead, you throw it away. Then, you get another shirt from the closet, in the hopes that you get a blue one. There is no shirt in the closet, so you are out of luck.

not so out of luck - maybe it very hot outside :) thank you - now I understand the different .

but I still don't get the right answer what did I miss this time (if I understand you correct )

void loop() 
{
  if (digitalRead(test)==HIGH)
  {
   char in_char;
   char response[6];
   int c=0;
   int i=0;
    char finalPart[2];
    mySerial.println("AT");
    delay(800); //
    if (mySerial.available() >9)
   {//start of reading answer
     
     in_char=mySerial.read();
     if ((in_char=='\n')||(in_char=='r'))
     {//waht to do with '\n' or '\r'
       c++;
     }
     else      
      
      {
             response[i]=in_char;
             i++;
   
      }//end for i
      
      Serial.print(millis() /1000);
      Serial.print("   -   this is the full respons: ");
      Serial.println(response);
      Serial.print("   - how many 'c' and 'r'  : ");
      Serial.println(c);
      finalPart[0]=response[2];
      finalPart[1]=response[3];
      //finalPart[2]=('\0');
      Serial.print("this is final - ");
      Serial.print(finalPart[0]);
      Serial.println(finalPart[1]);
      Serial.println(finalPart);
    }//end of reading answer
    if ((finalPart[0]=='O')&&(finalPart[1]=='K'))
    {//what to do answer OK
      digitalWrite (13,HIGH);
      Serial.print(millis() /1000);
      Serial.println("Modem is working!!!!");
      delay (1500);
      digitalWrite(13,LOW);
      Serial.println("******************");
    }// end answer OK
    else
    {//what to do if modem not ready
      Serial.print(millis() /1000);
      Serial.println ("  -Modem not ready yet......");
      Serial.println("******************");

    } //end modem not ready

  }//end when press 

}//end loop

I can't see how you're looping through the characters there...

I can see what you mean - every press I get only 1 char why is it ? why he doesn't read the all answer (10 chars) ?

what do I need to fix ?

never mind
you made me to think -again and again ,
and at the end I understand what was wrong
Thank you for this!!!

now it’s working

I have change the if\else - so take a look and see what we all made together here

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
int test=7;

void setup()  
{
  pinMode(test,INPUT);
  pinMode(13,OUTPUT);
  Serial.begin(19200); // Open serial communications and wait for port to open:
  delay(1500);
  Serial.println("Ready to work!");
  mySerial.begin(19200);
  delay(1500);

}

void loop() 
{
  if (digitalRead(test)==HIGH)
  {
   char in_char;
   char response[10];
   int c=0;
   int i=0;
    char finalPart[2];
    mySerial.println("AT");
    delay(800); //
    if (mySerial.available() >8)
   {//start of reading answer
     for (int num=0;num<9;num++)
     {//start of reading 10 char
     in_char=mySerial.read();
     if (in_char=='O')
     {//waht to do with '\n' or '\r'
       response[i]=in_char;
       i++;
     }
     else if (in_char=='K') 
     {
      response[i]=in_char;
      i++;
     }
     else      
      
      {
             c++;
   
      }//end for i
     }//end of reading 10 char
      Serial.print(millis() /1000);
      Serial.print("   -   this is the full respons: ");
      Serial.println(response);
      Serial.print("   - how many 'c' and 'r'  : ");
      Serial.println(c);
      finalPart[0]=response[0];
      finalPart[1]=response[1];
      //finalPart[2]=('\0');
      Serial.print("this is final - ");
      Serial.print(finalPart[0]);
      Serial.println(finalPart[1]);
      Serial.println(finalPart);
    }//end of reading answer
    if ((finalPart[0]=='O')&&(finalPart[1]=='K'))
    {//what to do answer OK
      digitalWrite (13,HIGH);
      Serial.print(millis() /1000);
      Serial.println("Modem is working!!!!");
      delay (1500);
      digitalWrite(13,LOW);
      Serial.println("******************");
    }// end answer OK
    else
    {//what to do if modem not ready
      Serial.print(millis() /1000);
      Serial.println ("  -Modem not ready yet......");
      Serial.println("******************");

    } //end modem not ready

  }//end when press 

}//end loop