SIM800 AT Commands output parsing

I’ve go this code as of the moment

#include <SoftwareSerial.h>

SoftwareSerial mySerial(7, 8);

String numstr , message , inbox;

void setup()
{
Serial.begin(19200);
mySerial.begin(19200);  //Default serial port setting for the GPRS modem is 19200bps 8-N-1
mySerial.print("\r");
delay(1000);                    //Wait for a second while the modem sends an "OK"

numstr = "09778562037"; 
message = "here";

}

void sendtext( String numstr , String message )
{
mySerial.print("AT+CMGF=1\r");    //Because we want to send the SMS in text mode
delay(1000);
mySerial.print("AT+CMGS=\"" + numstr +"\"" + "\r");
delay(1000);
mySerial.print( message + "\r");   //The text for the message
delay(1000);
mySerial.write(0x1A);  //Equivalent to sending Ctrl+Z   
}

void readtext()
{
char response[255];
int i=0;
mySerial.print("AT+CMGR=1\r");
delay(1000);

while(mySerial.available()!=0 && i<255){
  response[i] = (char)mySerial.read();
  i++;
}

Serial.print(response);

if( strstr( response , "LoooooL" ) )
  Serial.print("there");
}

void loop()
{
delay(1000);
readtext();
}

It can output any command with the OK response but whenever I use it on texts or received SMS this happens

Arduino Serial Output

Imgur

It is your first post and you managed to put your code inside of code tags - well done!
Unfortunately that is where the compliments end.

  • You haven't included the serial output that you hinted at, although the code doesn't seem to be writing any anyway.
  • The code you posted doesn't compile; a #include is missing and SoftwareSerial is wrongly capitalised. Have you actually even tested using this code?
  • You are missing a mySerial.begin(...).
  • I'm pretty sure that the AT command is supposed to be terminated with \r\n and not just \r.

Restate your problem clearly. Provide the actual code that you have the problem with.

done the image wouldn’t show

The OP’s image:

k5nn.png

You haven’t really explained what you expect to happen.

In any case, the random binary data you see towards the end of each output line is due to the fact that you are not null terminating response.

This should probably fix that:

char response[256];
// ...
  while (mySerial.available() != 0 && i < (sizeof(response) - 1)) {
    response[i] = (char)mySerial.read();
    i++;
  }
  response[i] = '\0'; // null terminate C-string

You should also read Robin2’s great tutorial on reading serial.

I just need the serial to not output the garbage values then I'll substring the message contents

I have here is my current code

#include <SoftwareSerial.h>

SoftwareSerial mySerial(7, 8);

int power = 9;
int val;
String numstr , message , inbox;

void setup()
{
Serial.begin(19200);
mySerial.begin(19200);  //Default serial port setting for the GPRS modem is 19200bps 8-N-1
mySerial.print("\r");
delay(1000);                    //Wait for a second while the modem sends an "OK"

numstr = "09778562037"; 
message = "here";

readtext();
}

void readtext()
{
char response[255];
int i=0;
mySerial.print("AT+CMGF=1\r\n");    //Because we want to send the SMS in text mode
delay(1000);  
mySerial.print("AT+CMGR=1\r\n");
delay(1000);

while(mySerial.available()!=0 && i<255){
  response[i] = (char)mySerial.read();
  i++;
  if( i % 31 == 0  && i > 0 )
  {
    Serial.flush();
    mySerial.flush();
  }
}

response[255] = '\0';
Serial.print( i );
Serial.print(response);

void loop()
{

}

the problem is whenever I do the usual AT commands for the readtext function I get the result I need but whenever I make the arduino do it I end up with this

PS. posted at the wrong one apologies

readtext.png

    if ( i % 31 == 0  && i > 0 )
    {
      Serial.flush();
      mySerial.flush();
    }

Why are you flushing the output buffers ?

  while (mySerial.available() != 0 && i < 255)Do you always get 255 chars returned ?

k5nn:
PS. posted at the wrong one apologies

What does that mean?

Are you still looking for help?

Maybe have a look at the examples in Serial Input Basics - simple reliable ways to receive data. The only limit to the number of characters is how much SRAM you have available.

…R

Robin2:
Are you still looking for help?

I was supposed to post this at programming questions cause well the nature of the question is programming related

UKHeliBob:

    if ( i % 31 == 0  && i > 0 )

{
     Serial.flush();
     mySerial.flush();
   }



Why are you flushing the output buffers ?



while (mySerial.available() != 0 && i < 255)



Do you always get 255 chars returned ?

1 ) I thought that if I flushed the buffers I could make room for the next batch of characters

2 ) I don’t get 255 characters returned I only get 64 I read that the serial limits at most 64…

Thread moved. Threads merged.

1 ) I thought that if I flushed the buffers I could make room for the next batch of characters

Serial.flush() waits until all of the characters have been removed from the output buffer. Is that what you want ?

2 ) I don't get 255 characters returned I only get 64 I read that the serial limits at most 64...

Whilst it is true that the Serial input buffer can only hold 64 bytes you can remove them faster than they arrive so you can receive as many characters as you want.

Does the data that you receive have a terminating character such as Carriage Return or Linefeed ?

UKHeliBob:
Does the data that you receive have a terminating character such as Carriage Return or Linefeed ?

yeah it does and I think I found out the problem so I've been digging around the net on where the location of SoftwareSerial library and lo and behold I happen to come across this

only to find the culprit which is

#define _SS_MAX_RX_BUFF 64 // RX buffer size on line 43

and when I changed it to

 _SS_MAX_RX_BUFF 256 // RX buffer size

I got the result I wanted

result:

I got the result I wanted

Are you still using the code posted in reply #6 ?

Would it not be better to read the response and stop when you get the terminating character ?

UKHeliBob:
Would it not be better to read the response and stop when you get the terminating character ?

That’s not the solution he wanted…

UKHeliBob:
Are you still using the code posted in reply #6 ?

Would it not be better to read the response and stop when you get the terminating character ?

The original problem was I could'nt get the AT+CMGR properly because of hardcoded 64 byte limit in the software serial library hence if I stopped when I got the terminating character wouldn't that render the data incomplete?...

if I stopped when I got the terminating character wouldn't that render the data incomplete?...

No. If a character is available read it and if it is not the terminating character then put it into the array at the current position, increment the array index and put '\0' in the array at that position to terminate the string in case it is complete. Allow the loop() function to run freely in order to process characters as they arrive. When you receive the terminating character then print ot, or otherwise do what you want with the string which will already be correctly terminated.

Using this technique you will not fill the Serial buffer no matter how many characters you receive as long as you don't have blocking code in loop(). In fact, a 64 character buffer is a luxury and in most cases it could be much less but I suggest that you leave it alone.