Unable to read complete response in the buffer.

Hi,

I am totally new to arduino. I can't get the complete output while reading from serial pin RX1 on arduino.
In this particular case, my Arduino Mega 2560 is connected to SIM808 GSM Shield through PIN TX1,RX1 (18,19).
I am able to send SMS but unable to read received SMS because the string read from the shield is not complete.

Following is my code and it will be followed by my input and the output I am getting.

#define BAUD_RATE 9600


void setup() {
  Serial1.begin(BAUD_RATE);  // the GPRS shield baud rate
  Serial.begin(BAUD_RATE);    // Arduino baud rate
  delay(200);
}

void loop() {
  String output = "";
  while (Serial.available() > 0) output = output + Serial.read(); //clear buffer;
  Serial.print(output);
  unsigned long inTime = millis();
  while (Serial.available() == 0 && inputTimeout(inTime, 5000)) ; //wait for input
  if (Serial.available() > 0) {
    char option = Serial.read();
    String command;
    unsigned long wait;
    switch (option) {
      case 'a':
        while (Serial.available() > 0) Serial.read(); //clear buffer;
        Serial.println(F("Type your AT command:"));
        while (Serial.available() == 0);//Busy wait for input
        command = Serial.readString();
        sendAT(command);
        break;
      case 't':
        sendSMS("--deliberately ommitted--", "An SMS string.");
        break;
      case 'r':
        //intended for receive sms
        break;
      case 'z':
        sendAT(String((char)26)); //send CTRL+Z
        break;
      default:
        break;
    }
    Serial.println(F("Waiting..."));
  }
  else{
    //do something else
  }
  while (Serial1.available())    Serial.write(Serial1.read()); // relay everything from GSM Shield to PC via board;
}

void sendAT(String command) {
  Serial1.println(command);
  delay(200);
  String response = "";
  char responseBuffer[200];
  memset(responseBuffer,'\0',200);
  int i=0;
  delay (200);
  while (Serial1.available() > 0 && i<200) {
    responseBuffer[i++]=Serial1.read();
  }
  delay(100);
  Serial.println(responseBuffer);
  char *ptr=NULL;
  ptr=strtok(responseBuffer,",");
  while(ptr != NULL)
    {
        Serial.println(ptr);
        //response = response+ptr;
        ptr = strtok(NULL, ",");  // takes a list of delimiters
    }
  //response = responseBuffer;
  //Serial.print("Response: " + response);
}

void sendSMS(String msisdn, String text) {
  Serial.println(msisdn + ": " + text);
  sendAT("AT+CMGF=1");    //Because I want to send the SMS in text mode
  sendAT("AT+CMGS=\"" + msisdn + "\",145\r"); //AT+CMGS="<MSISDN>",145
  delay(1000);
  sendAT(text);//the content of the message
  delay(1000);

  sendAT(String((char)26));//the ASCII code of the ctrl+z is 26
  //*/
  delay(100);
}

The terminal output:
--Start of output--
<input=a>
Type your AT command: <input=AT+CPMS="SM","SM","SM">
AT+CPMS="SM","SM","SM"
AT+CPMS="SM","SM","SM"

+CPMS: 16,40,1
AT+CPMS="SM"
"SM"
"SM"
AT+CPMS="SM"
"SM"
"SM"

+CPMS: 16
40
1
Waiting...<input=a>
Type your AT command: <input=AT+CMGR=1>
AT+CMGR=1
AT+CMGR=1

+CMGR: "REC READ","53030303","","17/03/2
AT+CMGR=1
AT+CMGR=1

+CMGR: "REC READ"
"53030303"
""
"17/03/2
Waiting...

--End of output--

My problem:

  1. In the case of input AT+CPMS="SM","SM","SM" , the output was incomplete +CPMS: 16,40,1
    There should have been something more as the output is of the format
    +CPMS: ,,,,,

  2. In the case of input AT+CMGR=1 , the output is also incomplete +CMGR: "REC READ","53030303","","17/03/2
    It should be of the format +CMGR: ,[,],[,,,,
    ,,,]

Reference: http://www.cika.com/soporte/Information/GSMmodules/SIM808/SIM800_Series_AT_Command_Manual_V1.09.pdf

Can anyone help me get the complete response for the AT commands?
I have done a lot of reading but I can't figure out what's wrong here. Have I missed something?

Thanks in advance!

In sendAT(), you print the string to the device.

Then, you stick your head in the sand for a while. Why do you do that?

Then, you define an array, and set it all to nulls.

Then, you stick your head in the sand for a while. Why do you do that?

Then, you expect the complete response to have been received. Why do you do that?

Then, you stick your head in the sand for a while. Why do you do that?

You need to determine when the response is complete, and keep twiddling your thumbs until you have received the complete response OR you've waited long enough that you can be sure that data got lost.

You need to ditch the String class. NOW!

mihafiz:
I am totally new to arduino.

First learn the lesson here: Gammon Forum : Electronics : Microprocessors : How to do multiple things at once ... like cook bacon and eggs --- do multiple things at once
Then this one: Gammon Forum : Electronics : Microprocessors : How to process incoming serial data without blocking --- process serial without blocking

Nick gives good complete lessons with easy common sense explanations.

These will show you how to get rid of the delays and read the text completely.

And some time do quit using String if you want to quit wasting RAM and CPU cycles.
Learn about C strings (char arrays) instead.

mihafiz:
I am totally new to arduino. I can't get the complete output while reading from serial pin RX1 on arduino.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. In the examples the receive buffer is set at 32 chars but you can easily change that.

...R

Thanks everyone who responded. Your responses gave me enough clue and advice to move on. I definitely have to quit String. The delay had a purpose: to do something else in that gap. Alas, it seems non-busy wait isn't possible here (until a timeout). I hope to be wrong.

mihafiz:
Thanks everyone who responded. Your responses gave me enough clue and advice to move on. I definitely have to quit String. The delay had a purpose: to do something else in that gap. Alas, it seems non-busy wait isn't possible here (until a timeout). I hope to be wrong.

Look at the code(s) that Robin2 linked to.

You call one of his receive functions numerous times from loop() till you have all data. Next you can process the data. While the data is not complete, you can do other things.

Slightly modified loop (from example 2) to make it more obvious how it's handled; note that showNewData already does this work.

void loop()
{
    // read some serial data; this function sets newData to true when if data is complete but does not wait for the complete data
    recvWithEndMarker();
    // if received data complete
    if (newData == true)
    {
      // process the received data
      showNewData();
      // data processed, clear flag
      newData = false;
    }

    // do 'something' that does not block
    ...
    ...

    // and do another 'something else' that does not block
    ...
    ...
}

Thanks a lot! That's easy to comprehend.

mihafiz:
The delay had a purpose: to do something else in that gap. Alas, it seems non-busy wait isn't possible here (until a timeout). I hope to be wrong.

The links I gave you show how to do "the impossible" then. But the lessons take some time to grasp at all so you run the examples and trace the code and modify what you do understand to see what happens to gain more insight.

Robin gave you a link too.

What you want is really the main specialty of the house of Arduino Forum. We have tried to guide you there.

GoForSmoke:
What you want is really the main specialty of the house of Arduino Forum. We have tried to guide you there.

Thanks to everyone! I am truly grateful! The clues and advices were very useful in understanding the AT response parsing. Although I have not grasped everything yet, I will keep trying and may bother you guys as often as necessary.

Blink the leds, it's the easiest way to start.