I am using Arduino to control an SM5100B GSM device, everything works except when I want to send an SMS after receiving another. I get this,
Error code:
O K > + C M G S : 2 5 O K + C M E E R R O R : 4
My code for handling the aforementioned received SMS:
#include <SoftwareSerial.h> //Include the NewSoftSerial library to send serial commands to the cellular module.
char inchar; //Will hold the incoming character from the Serial Port.
SoftwareSerial cell(2,3);
char mobilenumber[] = "0597010129";
void setup() {
//GSM
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
Serial.println("Initialize GSM module serial port for communication.");
cell.begin(9600);
delay(35000); // give time for GSM module to register on network etc.
Serial.println("delay off");
cell.println("AT+CMGF=1"); // set SMS mode to text
delay(200);
cell.println("AT+CNMI=3,3,0,0"); // set module to send SMS data to serial out upon receipt
delay(200);
}
void loop() {
if(cell.available() >0)//If a character comes in, from the cellular module
{
inchar=cell.read();
Serial.println(inchar);
if (inchar=='#'){ // OK - the start of our command
delay(10);
inchar=cell.read();
Serial.println(inchar);
if (inchar=='a'){
delay(10);
Serial.println("The folowing SMS : \n");
inchar=cell.read();
Serial.println(inchar);
if (inchar=='0'){ //sequance = #a0
Serial.println("#a0 was received");
}
else if (inchar=='1'){//sequance = #a1
Serial.println("#a1 was received ");
sendSms();
}
}
cell.println("AT+CMGD=1,4");// AT command to delete all msgs
Serial.println(" delete all SMS");
}
}//end of if(cell.available() >0) {...}
}
void sendSms(){
//cell.println("AT+CMGF=1"); // set SMS mode to text
cell.print("AT+CMGS="); // now send message...
cell.print((char)34); // ASCII equivalent of "
cell.print(mobilenumber);
cell.println((char)34); // ASCII equivalent of "
delay(500); // give the module some thinking time
cell.print(":D hello m3alleg :D"); // our message to send
cell.println((char)26); // ASCII equivalent of Ctrl-Z
delay(20000);
}
No, no, no! This way of doing it will never work reliably. You MUST
wait for the >
character to be be received before sending "text
to send". Or actually it is not just the >
character, it is four
characters. Quote from 3GPP specification 27.005:
- the TA shall send a four character sequence
<CR><LF><greater_than><space>
(IRA 13, 10, 62, 32) after command line is terminated with<CR>
; after that text can be entered from TE to ME/TA.
(TA (terminal adapter) here means modem and TE (terminal equipment) the sender of AT commands)
For any abortable AT command (and 27.005 clearly states for AT+CMGS
This command should be abortable.
) the sending of any character will
abort the operation of the command. To quote ITU V.250:
5.6.1 Aborting commands
...
Aborting of commands is accomplished by the transmission from the DTE to the DCE of any character.
(DCE (data communication equipment) here means modem and DTE (data terminal equipment) the sender of AT commands)
This means that when you send "text to send" before "\r\n> " is sent by the modem the command will be aborted. There is no way to wait "long enough" for expecting the response be send. You MUST read and parse the response text you get back from the modem.
The same applies for the final result code after each command (e.g. OK
,
ERROR
, CME ERROR
and a few more). For instance sending "AT+CMGF=1"
and then sending the next command without first waiting for OK is begging
for problems. So always when sending AT commands, you MUST wait
for the final result code before sending the next command.
Please never, never use delay
to wait for any AT command response. It's
as useful as kicking dogs that stand in your way in order to get them
to move. Yes it might actually work some times, but at some point you
will be sorry for taking that approach...
Based on the response you get, I can see that your problem is not command
abortion (although your parsing have serious problems as described above
that you should fix), and the CME ERROR is your best clue. From section
"9.2.1 General errors" in 27.007 it gives operation not supported
as
description for value 4.
27.005 states that:
If sending fails in a network or an ME error, final result code +CMS ERROR: is returned.
Notice that this is +CMS ERROR and not +CME ERROR, but it is applicable, see below.
I guess that sequence of actions is as following:
The AT command handling part of the SM100B GSM modem accepts the sms data
and formats it in an appropriate format and sends it of to the part of the
modem that communicates with the GSM network. It successfully send the
sms data to the network and reports this back to the AT command handling
part which then prints +CMGS: 25
and final result code OK
. However
after a short time the network sends back a rejection message for the sms,
which is then given as the +CME ERROR response.
If my guess above is correct, should the response have been delivered as +CMS ERROR instead? No, because the final response has for the AT+CMGS command has already been given (OK), and returning multiple final result codes for a command should never be done (except by mistake (note 1)). And while +CME ERROR can replace the ERROR final result code, it is not only a final result code. From the AT+CMEE command description:
Set command disables or enables the use of result code +CME ERROR: as an indication of an error relating to the functionality of the MT. When enabled, MT related errors cause +CME ERROR: final result code instead of the regular ERROR final result code. ERROR is returned normally when error is related to syntax, invalid parameters, or TA functionality.
Thus +CME ERROR can both be an final result code as well as an unsolicited result code (possibly also an intermediate result code).
But could not the AT+CMGS command have waited to receive the network rejection and returned +CMS ERROR? Probably not. Without knowing too much about the network details of sms sending, it might be the case that rejection today might occur at a much later time than before. Such changes are sometimes a problem with GSM related AT commands which have an old heritage that was originally tightly tied to GSM behaviour which some times becomes less and less true as the technology moves to GPRS, UMTS, LTE, etc.
Note 1:
One of my former colleagues used to complain about the way the standard have specified voice call handling, because after a ATD1234; command you first get the final result code OK, and then later when the call is ended you get a new final result code NO CARRIER. This just horribly bad design, the call end indication should have been a specific unsolicited response and not a final response.
Your sms seems to be rejected by the network. Try to find out why. You also have some serious problems with your AT command handling that you should fix; there is no way to handle AT commands without reading and parsing the response text from the modem.