Receiving multiple SMS not working properly

Hello everyone!

I am trying to use Arduino to receive many SMS messages to unsubscribe from a feature.

But whenever it receives too many(10 or so +) it stops working.
By that I mean that the device doesn't send any more messages trough the serial port.

I am clueless if it could be a problem with the network provider or Arduino itself, so I am looking for help here.

Here is the code that manages received SMS messages and sends them trough serial port to a program.

void setup(){

Serial.begin(9600);
while (!Serial) {}

boolean notConnected = true;
Serial.println("pin");
readSerial(pinNumber); 

while(notConnected)
{
if(gsm.begin(pinNumber) == GSM_READY)          
{
 notConnected = false; 
}

else{delay(1000);}
}

char receivedSms[30];

 while(sms.available()) 
  {    
    int count = 0;
    char receivedSms[160];
    sms.remoteNumber(nbr, 20);

    while (c = sms.read()) 
    {
      receivedSms[count++] = c;
      receivedSms[count] = '\0';
    }

count = 0;   
Serial.print(receivedSms);
Serial.print(" ");
Serial.println(nbr);

sms.flush();

  }
Serial.println("connected");      
}

EDIT:

I just tested again. Receiving 5 SMS works perfectly fine.

Then I sent 10 SMS and none were received - the device froze or something.

Any ideas?

Then I sent 10 SMS and none were received - the device froze or something.

When you create an array of 30 elements, how many elements can you write to the array? How many DO you write to the array?

Why do you have two arrays with the same name but different sizes?

To what array are you referring?

About the two same arrays: Didn't notice, thanks. I removed the redundant one.

To what array are you referring?

receivedSms

You have NO checking that will prevent you from writing beyond the end of the array, whatever size you ended up making it. Do NOT expect your program to behave properly without array bounds checking.

A SMS cannot be longer than 160 characters(in my country), if it is, it's send insplit. Thats why I didn't use any checkings.

Or should I do it nevertheless? I just can't figure out how this could contribute to the receiving SMS problem.

Something I forgot to mention: If the device is plugged in and reading SMS it worksed fine since it receives one by one.

The problem is only when the device is getting plugged after there are many received SMS.(~5 still work fine though)

I suggest that you pay the fine folks at http://snippets-r-us.com a visit. They can help you with your snippets.

Well played, PaulS :slight_smile: Okay, here is the whole code.

First some desciption on how it works:

When the device is started the setup() searches for any received SMS and sends them trought the port. It loops as long as there are messages in the buffer.(I used the example code for receiving SMS and added some needed functionality)

After no more SMS are available it gives an "ok" trought the port letting the frontend know that it is ready to send SMS. those are sent in loop(), which works fine.

readSerial() is also from code example and wasn't modified at all.

#include <GSM.h>
char pinNumber[10];

GSM gsm;
GSM_SMS sms;

char msg[320];
char odjava[90];
char nbr[20];
char c;


void setup(){


Serial.begin(9600);
while (!Serial) {}

boolean notConnected = true;
Serial.println("pin");      

readSerial(pinNumber); 


while(notConnected)
{
if(gsm.begin(pinNumber) == GSM_READY)          
{
 notConnected = false; 
}
else{delay(1000);}
}


 while(sms.available()) 
  {    
    int count = 0;
    char receivedSms[160];
    sms.remoteNumber(nbr, 20);
    while (c = sms.read()) 
    {
      receivedSms[count++] = c;
      receivedSms[count] = '\0';
    }
    count = 0;   

Serial.print(receivedSms);
Serial.print(" ");
Serial.println(nbr);

sms.flush();
  }

Serial.println("connected");      
}



void loop(){                            

int count;
char c;
char counts[10];


readSerial(msg);
readSerial(odjava);

Serial.println("ok");

readSerial(nbr);



while(strcmp(nbr, "done") != 0){
sms.beginSMS(nbr);

if(odjava[0] == NULL)
{
  sms.print(msg);
}
else
{
  sms.print(msg);
  sms.print("\n");
  sms.print(odjava);
}


sms.endSMS();
Serial.println("ok");
readSerial(nbr);
}
}



int readSerial(char result[200]) {
  int i = 0;
  while (1) {
    while (Serial.available() > 0) {
      char inChar = Serial.read();
      if (inChar == '\n') {
        result[i] = '\0';
        Serial.flush();
        return 0;
      }
      if (inChar != '\r') {
        result[i] = inChar;
        i++;
      }
    }
  }
}

EDIT:
After some more testing I found out that when Arduino is not responding due to too many SMS at once it doesn't even go past the gsm ready. I tested this with the example SMS receive; where I should get the "Not connected" or "GSM initialized" message, I get nothing.

Does anyone have any possible solution perhaps?

When you call readSerial(), you pass it three different arrays. NONE of them are 200 elements long. Why does readSerial() assume a 200 element array?

Why does readSerial() block until all outgoing serial data has been sent? Specifically, why does it do that when it outputs no data? That is what flush() does. Seems completely useless.

Which Arduino are you using? I'm beginning to suspect that you are running out of memory.

Thank you for your answer.

I made readSerial() 200 elements long because the application can send up to 200 characters per SMS message. More did cause it to send slower and less could cause shortage of text content.

I don't understand what you mean by blocking data. readSerial() was used in the Arduino example for sending SMS messages, so I used it for my own.

I am using Arduino Uno(from China) and a Arduino GSM Shield 2.

I am starting to think that the SIM card became corrupt, because if I am trying it out in my phone, I cannot send a SMS message to myself. Which is odd, since the card is 2 days old.

** INDENT YOUR CODE **

Press control-T in the IDE editor to auto-format your code. Ick.

Totally forgot about this feature, thank you!

I made readSerial() 200 elements long because the application can send up to 200 characters per SMS message.

You need to declare readSerial() to take a pointer to a char (array) and a length. You need to make sure that readSerial() does not write beyond the end of the array.

When you pass a 20 element array to the function, the function can only write 20 characters to the array. It does NOT matter that the function thinks it has a 200 element array to deal with.

Where are you located? Text messages are usually limited to 160 characters (at least in the US).

I am from Slovenia, Europe.

Yes SMS messages are 160 here aswell, but it is possible to send more than 160 characters, it just makes 2 messages instead.

I tested it with 200 chars and more and it worked fine.

I am not quiet understanding what you are telling. Am I correct taht pointers work the same as references to variables?

readSerial() cannot go beyond 200 characters because there is char[] in code that is longer than 200(yes msg is 320 but the application doesn't send beyond 200 characters).

Your readSerial() function declaration should look like:

void readSerial(char *pMemory, int memSize)
{
}

In the function, you can store data in pMemory[n], as long as you assure that n is less than memSize.

You can then call readSerial() with any array, as long as you tell the function how big the array is.

char phone[20];

readSerial(phone, sizeof(phone)/sizeof(phone[0]));

Now, readSerial() will not try to write 200 characters into the 20 element array.

Sounds great. But how can I manage the array size if I get it from the desktop application?

I would have to send a parameter with the size before the actual string.

But how can I manage the array size if I get it from the desktop application?

You can't get the array from the PC. You create the array on the Arduino. You might populate the array with data from the serial port. If that is the case, you have two choices. You can make the array as large as reasonable, and throw away data that won't fit, or you can use dynamic memory allocation to handle any amount of data.

Given the limited amount of memory on the Arduino, the first option is a better choice, most of the time.

So you mean receiving data and then filtering out all indexes that contain characters?

Could I perhaps add a nullterminator to the string that is sent from the desktop app?