Hello.
I am trying to get a SIM800L reliably recalling SMS from the SIM800L using the "AT+CMGR=X" command. I understand that "AT+CNMI=X,X" can be used to change how the SMS is stored, but I want to use AT+CMGR=X to choose when I read the SMS, so I don't have to immediately capture it when it comes in.
To be clear:
- I have the power to the SIM800L working fine (I have the v2 board, and replaced the not in spec capacitor on the board) - most issues with the SIM800L can be related to this power issue but I believe I have that sorted.
- I can receive short SMS perfectly fine.
- I can send SMS perfectly fine.
I have looked over the internet a lot and ALL the use cases I can find where the SIM800L is used, only have short 1-10 strings of SMS being recalled from the SIM800L.
I am trying to reliably recall the SMS from the SIM800L no matter what length of SMS is ready to be recalled. I understand that this max length is 160, and 153 when it is a concatenated SMS over multiple index.
I am just really stuck trying to get a consistent recall of the SMS back from the SIM800L and storing it into a usable string or char array for use in a code which does not have a serial monitor such as an LCD.
To be clear, when using the serial available, serial write (like basic examples of the SIM800L use), everything works fine, every time. When writing directly to the serial monitor from the SIM800L, it works every time. I am just having issues getting the serial data, consistently into a string or char array for printing out on say a LCD. Hence I think it is an issue with my code, or how I am using SoftwareSerial and the SIM800L.read();.
if (Serial.available())
{
SIM800L.write(Serial.read());
}
I have tried to take each byte from the serial read from the SIM800L and store it. But I find that runs into issues when the SMS is longer (it just does not read the SMS after 54 characters).
I have tried other methods of reading and storing from the SIM800L. And currently I have tried to implement a, if data is available wait a bit of time to capture that data. I thought this was working well, but for longer messages I still run into a problem. This code, which contains my other commented out methods also, is shown below.
With this if data is available wait a bit of time to capture that data code, for longer SMS only, every other recall of the message has erroneous recall of the SMS, and I cannot understand why.
Please see the serial output below which shows this. I have tried another serial monitor, and I have set both the SIM800L and the serial monitor at 9600baud which has caught others out when searching online.
For the SMS, I have used a string of a's, each capital A represents a set of 10 a's (including the A), so a max 160 length message test.
Serial monitor data
09:17:17.898 -> Data: AT+CMGR=3,1
09:17:17.898 -> OK
09:17:17.898 ->
09:17:17.898 -> +CMGR: "REC READ","+44XXXXXXXXXX","","25/05/02,17:17:32+04"
09:17:17.932 -> AaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaa
09:17:18.098 ->
09:17:18.098 -> OK
09:17:18.098 ->
09:17:20.898 -> Data: AT+CMGR=3,1
09:17:20.898 -> +CMGR: "REC READ","+44XXXXXXXXXX","","25/05/02,17aaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaa
09:17:20.966 ->
09:17:21.008 -> OK
09:17:21.008 ->
09:17:23.892 -> Data: AT+CMGR=3,1
09:17:23.892 -> +CMGR: "REC READ","+44XXXXXXXXXX","","25/05/02,17:17:32+04"
09:17:23.934 -> AaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaa
09:17:24.108 ->
09:17:24.108 -> OK
09:17:24.108 ->
09:17:26.870 -> Data: AT+CMGR=3,1
09:17:26.870 -> +CMGR: "REC READ","+44XXXXXXXXXX","","25/05/02,17aaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaa
09:17:27.015 ->
09:17:27.015 -> OK
09:17:27.015 ->
Code:
#include <SoftwareSerial.h>
SoftwareSerial SIM800L(6, 7); // RX | TX
const unsigned int MAX_SIM800Ldata_LENGTH = 160;
String SIM800LdataBuf = "";
char bufChar;
char SIM800Ldata[MAX_SIM800Ldata_LENGTH];
boolean newData = false;
static unsigned long setTime = 0;
static unsigned long goTime = 0;
static const unsigned long recievePeriod = 1000; // ms
static unsigned long timeNow = 0;
boolean timerOn = true;
static const unsigned long testTime = 3000; // ms
void setup() {
setTime = millis();
// Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
Serial.begin(9600);
// Begin serial communication with SIM800L
SIM800L.begin(9600);
SIM800L.println("AT");
delay(100);
// Set SMS Message Format
SIM800L.println("AT+CMGF=1");
getData();
printData();
//Show some optional elements of responses (such as <length> in SMS read).
SIM800L.println("AT+CSDH=0");
getData();
printData();
}
void loop()
{
timeNow = millis();
//**********************
//This section of code is just to emulate the AT+CMGR= command
//being used to get the SMS from the SIM800L, as the end goal will be to
//display incoming SMS on an LCD at specified times (simplified to get the
//basics working fist - what I am having issues with).
if(timeNow - goTime > testTime)
{
goTime = millis();
SIM800L.println("AT+CMGR=3,1");
}
//**********************
//if (Serial.available()) {
// SIM800L.write(Serial.read());
//}
getData();
printData();
}
void getData()
{
/*
while (SIM800L.available())
{
bufChar = SIM800L.read();
SIM800LdataBuf.concat(bufChar);
//strcat (SIM800LdataBuf, bufChar);
if (bufChar == '\r') // line feed 0x0A 'n', carriage return 0x0D '\r'
{
newData = true;
}
}
*/
if (SIM800L.available())
{
if (timerOn != true)
{
timerOn = true;
setTime = millis();
}
if (timeNow - setTime <= recievePeriod)
{
while (SIM800L.available())
{
bufChar = SIM800L.read();
SIM800LdataBuf.concat(bufChar);
}
}
else
{
timerOn = false;
newData = true;
}
}
/*
// If there's any serial available from SIM800L, read it and send it out
// through Arduino's UART (Serial Monitor)
if (SIM800L.available()>0)
{
static unsigned int SIM800Ldata_pos = 0; //because these are static they only get set once.
while (SIM800L.available()>0)
{
char incomingByte = SIM800L.read();
if ((incomingByte != '\n') && (SIM800Ldata_pos < MAX_SIM800Ldata_LENGTH - 1)) // line feed 0x0A 'n', carriage return 0x0D '\r'
{
SIM800LdataBuf[SIM800Ldata_pos] = incomingByte;
SIM800Ldata_pos++;
}
else
{
SIM800LdataBuf[SIM800Ldata_pos] = '\0'; //terminate string
//Serial.print("Pos: ");
Serial.println(SIM800Ldata_pos);
strcpy(SIM800Ldata,SIM800LdataBuf);
SIM800Ldata_pos = 0;
newData = true;
}
}
}
*/
}
void printData()
{
if (newData == true)
{
Serial.print("Data: ");
Serial.println(SIM800LdataBuf);
SIM800LdataBuf = "";
//memset(SIM800LdataBuf,'\0',sizeof(SIM800LdataBuf));
newData = false;
}
}