Print to serial monitor fonction: amazing error

Hi all,

I'm having a pretty weird issue with the code that you'll find attached.
This program is supposed to forward any received SMS.

I developped this code using the documentation of the GSM modem, and instead of using libraries like AltSoftSerial (as SoftwareSerial can't be used with GSM.h library), I'm sending AT commands directly through the theGSM3ShieldV1ModemCore command, which actually achieves the same results without the extra step of loading another library.

DEVICES USED

  • Arduino Uno R3
  • Official GSM Shield

WHAT I DID
I was having issues with my code.
Instead of receiving a SMS on my phone with the whole content of the forwarded SMS, I was only getting the first letter of each text sent to the arduino.

Here is an extract of the ReadAndFormat fonction from my code (attached):

void ReadAndFormat(){
 // Lire le SMS reçu
 char characters_Received;
 char sms_Received[] = "";
 
 int position = 0;
    
    // Read the SMS and store it into the sms_Received array
    while (characters_Received = sms.read()){
 sms_Received[position] = characters_Received;
 position++;
 }

 // Add a null character (\0) at the en of the array
 // sms_Received[position++] = '\0';

 sprintf(text_toBeSent, "Text received from %s : \n\"%s\"", sender_Number, sms_Received);
}

Well, as I was only getting the first letter of a SMS forwared, I tried to debug it and added Serial.print commands. So here is the same function with a few more line of code:

void ReadAndFormat(){
 // Lire le SMS reçu
 char characters_Received;
 char sms_Received[] = "";
 
 int position = 0;
    
    // Read the SMS and store it into the sms_Received array
    while (characters_Received = sms.read()){
 sms_Received[position] = characters_Received;
 /*DEBUG*/ Serial.print(F("\n** characters_Received = "));
 /*DEBUG*/ Serial.print(characters_Received);
 /*DEBUG*/ Serial.print(F(" & sms_Received["));
 /*DEBUG*/ Serial.print(position);
 /*DEBUG*/ Serial.print(F("] = "));
 /*DEBUG*/ Serial.println(sms_Received[position]);
 position++;
 }

 // Add a null character (\0) at the en of the array
 // sms_Received[position++] = '\0';

 sprintf(text_toBeSent, "Text received from %s : \n\"%s\"", sender_Number, sms_Received);
}

I really wanted to see how the char from the text were added to the array at each step.

Now this is were things go crazy...
You'll need to get a look at the entire file to get an idea of the issue I'm facing, but when I add these Serial.print instructions, I'm indeed receiving a text message with the whole forwared sms message content...
but...

I'm also getting pretty weird crashes :

  • an instruction from the DeleteSMS will be concatenated with the SMS. I mean, really :confused: >:( .
  • if the original SMS is too long, the arduino will simply reset itself, the message never being deleted, and the arduino will try to read it again and again, unable to delete it or to forward it to my phone

In both cases, the content of the SMS received is successfully read.
But, in the first case, for a SMS that contained "This is a test", the message that is being forwarded to my phone becomes:

SMS received from (phone number): "This is a test@AT+QMGDA="DEL ALL"

So, I have the original SMS content concatenated with an instruction (an AT command to delete all SMS, AT+QMGDA=DEL ALL) that is actually from another function. The whole thing is being sent to my phone... And, as the AT+QMGDA=DEL ALL command is sent to me, it does not do what it was meant to: delete all the messages... So the Arduino just gets stuck, rebooting, sending me this weird SMS, and rebooting, etc.

In the second case, when the Arduino receives "Another test bro", this is what I'm getting in my serial monitor :

** SMS received from (phone number)

** characters_Received = A& sms_Received[0] = A

** characters_Received = n& sms_Received[1] = n

** characters_Received = o& sms_Received[2] = o

** characters_Received = t& sms_Received[3] = t

** characters_Received = h& sms_Received[4] = h

** characters_Received = e& sms_Received[5] = e

** characters_Received = r& sms_Received[6] = r

** characters_Received =  & sms_Received[7] =  

** characters_Received = t& sms_Received[8] = t

** characters_Received = e& sms_Received[9] = e

** characters_Received = s& sms_Received[10] = s

** characters_Received = t& sms_Received[11] = t

** characters_Received =  & sms_Received[12] =  

** characters_Received = b& sms_Received[13] = b

** characters_Received = r& sms_Received[14] = rC!%%%%%%%%%%%%%%�HHII �х�с ***
***************
** Scanning network:

and then the arduino reboots itself. :o :o :o

Man, has anyone any idea of what's happening here?
How come Serial.println commands could mess the program up so much?!
Should I avoid sprintf() as it uses so much RAM (from what I observed)?

I know that I'm a noob, but I just can't figure this out by myself... :confused:

Thanks in advance for any input...

GSM_Forward.ino (3.73 KB)

 char sms_Received[] = "";

How many characters can this array hold? How useful is a bucket that can't hold anything?

How useful is a bucket that can't hold anything?

Fix it dear Erto, dear Erto, dear Erto...

PaulS:

 char sms_Received[] = "";

How many characters can this array hold? How useful is a bucket that can't hold anything?

One, the '\0'. Which is probably not useful, but not empty, either.

Can I delete this amazing discovery now?

KeithRB:
One, the '\0'. Which is probably not useful, but not empty, either.

Well, true, but there isn't any room for OP to put anything in it, and still have room for the terminating NULL.

Feeling dumb is such a delight.

PaulS:

 char sms_Received[] = "";

How many characters can this array hold? How useful is a bucket that can't hold anything?

This was it. I guess that, for reasons I can't really understand at my level, I couldn't really expect the Arduino IDE to tell me that my char function was missing some parameters at that point, and that defining the size of the array is just some basic thing that I had to know.

I'm just impressed that I ran into these two types of (kind of impressive for my point of view) bugs from a mistake like that, but again, this might just be an obvious thing for experienced programers.

Well, as we say it here, merci beaucoup !

Erto-Arduino:
for reasons I can't really understand at my level, I couldn't really expect the Arduino IDE to tell me that my char function was missing some parameters at that point,

The compiler can usually tell you if you are using the programming language incorrectly (like a school teacher correcting the grammar in your essay).

The compiler has no ability to know that the correctly used language is doing something which causes the function of the program to fail. But your teacher will be clever enough to be able to tell you that the story in your essay is rubbish.

...R

The compiler has no ability to know that the correctly used language is doing something which causes the function of the program to fail. But your teacher will be clever enough to be able to tell you that the story in your essay is rubbish.

I think of coding more like writing a recipe than writing an essay. You might well write up a recipe that sounds reasonable, to a novice, but that would cause a chef to have unkind things to say.

There is a huge difference between "a pinch of salt" and "a cup of salt". Depending on what the recipe is for, one might be more appropriate than other. A cake with a cup of salt is going to be inedible (unless its the size of a football field). A brine with a pinch of salt is going to be useless.

OP: your recipe for brine called for a pinch of salt (that is, not near enough space to hold the data you trying to store there).

PaulS:
I think of coding more like writing a recipe than writing an essay.

Showing off again :slight_smile:

I wouldn't have a clue how to write a recipe.

...R

Erto-Arduino:
this might just be an obvious thing for experienced programers.

Nothing to do with more experienced. But I think that a lot of us went through a book that explained the basics of the language. Started with chapter 1, next chapter 2 and so on. Somewhere you will encounter arrays.

It's not too late to start reading a book :wink:

Well, thanks for the essay/grammar correction & the recipe tips.
And I'll get my homework and read again.

I mixed String str = ""; and char chr[] = ""; in that same file attached above, and didn't realize that the second couldn't work.

I guess I learned that before posting I need to be more methodical, asking myself specific question to find out bugs.

Thanks for all the input that helped me solve this and get lessons out.

I guess I learned that before posting I need to be more methodical, asking myself specific question to find out bugs.

Often the reasons for problems reveal themselves when you describe them to someone else, even if it only your cat. Whilst debugging Arduino programs using Serial.print() is tedious, the process of inserting the print commands can also make you focus on how or whether the program actually reaches that point and what the value of pertinent variables should be at that point. Printing values used by while, do and if can be particularly enlightening.

There are some common mistakes that occur in code posted here, such as

Code with an array in it strays outside of the array bounds

Code that does any comparisons uses x = y instead of x == y at some point

Code that uses a for loop tests the wrong final value of the loop variable

Code with a while loop in it never changes the condition so the loop never ends

Code with a while loop in it never executes because the loop condition is immediately true

Code with Serial.begin in it sets the wrong baud rate

Code that reads digital input has the input pins floating

Code that uses serial input or output uses pins 0 and/or 1 for something else

Code that divides one number by another uses int for the result even if the result will be a float

Code that divides one number by another uses ints when a float output is expected

Code that uses int for a variable tries to use it for a number that is too big

Code that uses global variables sometimes has local variables with the same name