GSM String gets cut off

I have a GSM module and that recieves an sms and responds based on the content of the sms. I've based my code off this instructible (http://www.instructables.com/id/How-to-make-a-Mobile-Cellular-Location-Logger-with/?ALLSTEPS) that uses strings to store the incoming data. I've noticed my string gets cut off all the time and I miss critical information in the sms. After reading up on it, it appears a lot of people recommend not using strings at all due to memory problems. Instead I should use character arrays.

I'm trying to adapt this bit of code but I don't really understand how it works. It appears to take one character at a time and then add it to the content string. If I were to allocate this to a character array do I need to assign it to assign the character to a specific spot in the array or is there a similar concat type function for characters? I'm a little confused because some articles talk about strings and character arrays as if they're the same thing. Does defining the length of a character array (even if it's longer than the string would be when it gets cut off) really save that much memory?

String content = "";
    
char c;

        while(GSM.available()) {   // if there is data to read...
            c = GSM.read();
            if(c == 0x0A || c == 0x0D) {
            } else {
                content.concat(c);
            }
        }

The important distinction is between a small-s string and a capital-S String. Don't use String, if you can avoid it.

That snippet of code is useless without the declaration of the object called content. I'm guessing it's a String, but that's only a guess. If it is, then you should read the reference to find out what concat() does.

You have a delay(1000) somewhere in your code. That's what is causing this to miss characters.

Sorry, you're correct, content is String. I'm not missing characters as in skipping intermittent characters, (I guess that's the link to the delay function) it just reaches a limit of around 20 characters in the string and then wont store any more. It prints the cut off string to serial and actually cuts off halfway through the variable I need to store so I know it's not just a printing to serial error.

Well, if the rest of the code must be kept secret, then you won't get any more answers.

Use [ code ] tags.

You really have to show all the code, we can’t comment much on stuff we can’t see.

So the code below uses identifiers in received text messages to store values in eeprom memory. Everything works fine except the returned AT command for a recieved sms cuts off after about 20-30 characters. When I print to serial I see the time and date recieved, number of sender and then part of the sms. When I recall the eeprom value I see the updated value, but only up until the message was cut off.

#include <EEPROM.h>

#include <SoftwareSerial.h>
SoftwareSerial GPRS(2, 3);
unsigned char buffer[100];
int count = 0;
int b;
char inchar;
String content = "";
char c;
String IDnew;
int stringstart;
int stringend;
char chararray[180];
int i;

//EEPROM Locations
int IDLoc = 1; //needs 2 locations (up to 9999)
char SleepLoc = 3;
char onTimeLoc = 4;
char offTimeLoc = 5;
char calLoc = 6;

//Set variables
int ID = 9999;
int sleeptime = 15;
int onTime = 6;
int offTime = 19;
int cal = 2700;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  GPRS.begin(9600);
  Serial.println("TEST EPROMM");
  GPRS.println("AT+CMGR=1");
  GPRSRespond();
delay(100);
  GPRS.println("ATE0");
  GPRSRespond();
  delay(200);
}

void loop() {
  GPRS.println("AT + CMGL = \"ALL\"");

  delay(1000);
  while (GPRS.available()) { 
    c = GPRS.read();
    if (c == 0x0A || c == 0x0D) {
    } else {
      content.concat(c);
    }
  }
  Serial.print("Content is:");
Serial.print(content);
  delay(1000);
  SMSCheck();

//  GPRS.println("AT + CMGD = \"ALL\"");
  delay(500);
  GPRSRespond();
  delay(200);

content = "";
delay(10000);



}

void SMSCheck() {
  Serial.println("Check content of SMS");
  if (content.indexOf("ID=") >= 0 ) SMSUpdate("ID=", IDLoc);
  if (content.indexOf("ST=") >= 0 ) SMSUpdate("ST=", SleepLoc);
  if (content.indexOf("ON=") >= 0 ) SMSUpdate("ON=", onTimeLoc);
  if (content.indexOf("OF=") >= 0 ) SMSUpdate("OF=", offTimeLoc);
  if (content.indexOf("CA=") >= 0 ) SMSUpdate("CA=", calLoc);

}
//checks information between 2 char info and . eg "ID=290."
void SMSUpdate(String stringCheck, int EEPROMLoc) {
  if (content.indexOf(stringCheck) >= 0 ) {
    int newValue = (content.substring(content.indexOf(stringCheck) + 3, content.indexOf('.', content.indexOf(stringCheck) + 3))).toInt();

    Serial.println(stringCheck + "    " + newValue);
    delay(100);

    updateEepromInt(newValue, EEPROMLoc);
  }
}

void writeEepromInt(int value, int location) {
  EEPROM.write(location, value);
  EEPROM.write(location + 1, value >> 8);
}

int readEepromInt(int location) {
  int val;

  val = (EEPROM.read(location + 1) << 8);
  val |= EEPROM.read(location);

  return val;
}

void updateEepromInt(int value, int location) {
  if (value == readEepromInt(location))
    Serial.println("EEPROM is the same");
  else
    writeEepromInt(value, location);
}

void clearBufferArray()
{
  for (int i = 0; i < count; i++)
  {
    buffer[i] = NULL;
  }
}

void GPRSRespond()
{

  while (count == 0)
  {
    //  Serial.println(count);
    while (GPRS.available())
    {
      buffer[count++] = GPRS.read();
      if (count == 120) break;
    }
  }
  Serial.write(buffer, count);
  delay(100);
  clearBufferArray();
  count = 0;
}

What does GPRS.available() do exactly?

Never mind, I see it's just a SS call.

So now I'm worried about this

 GPRS.println("AT + CMGL = \"ALL\"");

  delay(1000);
  while (GPRS.available()) {
    c = GPRS.read();
    if (c == 0x0A || c == 0x0D) {
    } else {
      content.concat(c);
    }
  }

How long would you expect it to take for the GPS module to respond? What if it takes 900mS for the first char, 100mS later you see that something is available and blat, you read everything that is there but the GPS is still adding bytes to the output queue.

One way to check is to increase that delay to say 2000 and see what happens.

If you know it's all done before the 1000mS is up then forget this.

Ahhh good point. I believe it should have printed by 1000ms, normally a delay of 100ms is more than enough unless it's connecting to the network but I'll try that out when I get home! Thanks

Unfortunately that made no difference Graynomad. Any other thoughts?

I found the result! Softwareserial buffer cuts off after 64 bytes, I needed to edit the arduino library buffer size.

Thank you for your time guys!

I knew that, but

it just reaches a limit of around 20 characters in the string and then wont store any more.

So I didn't think that was the problem :)

Anyway it's working, that's good.