Open axwell opened 6 years ago
Did you manage to read a valid SMS? Im interested in doing the same with an A7,
@shivsey yes Add this two methods.
int getUnreadSMSLocs(int* buf)
{
String data;
int index, occurrences = 0;
sendAT(GF("+CMGL=\"REC UNREAD\""));
if(waitResponse(5000L, GF("+CMGL:"), GFP(GSM_OK), GFP(GSM_ERROR))) {
do {
data = stream.readStringUntil('\n');
int pos = data.indexOf("REC UNREAD");
if (pos > 0) {
index = data.substring(0, pos - 1).toInt();
buf[occurrences] = index;
occurrences++;
}
} while (waitResponse() == 1);
}
return occurrences;
}
SMSmessage readSMS(uint8_t i)
{
char message[300];
char number[50];
char date[50];
char type[10];
String head;
String body;
SMSmessage sms = (const struct SMSmessage) {
"", "", ""
};
sendAT(GF("+CMGR="), i);
if (waitResponse(10000L, GF(GSM_NL "+CMGR:"))) {
head = stream.readStringUntil('\n');
body = stream.readStringUntil('\n');
sscanf(head.c_str(), "\"REC %s\",\"%s\",,\"%s\"\r\n", type, number, date);
sms.number = String(number);
sms.date = String(date);
body.toCharArray(message, body.length());
sms.message = message;
}
return sms;
}
Add struct at the top next to enum things
struct SMSmessage {
String number;
String date;
String message;
};
Red messages like this in the loop
unreadSMSNum = modem.getUnreadSMSLocs(unreadSMSLocs);
for (int i = 0; i < unreadSMSNum; i++) {
Serial.print("New message at index: ");
// Serial.println(unreadSMSLocs[i], DEC);
sms = modem.readSMS(i);
}
Add method:
void prefSettings()
{
sendAT(GF("+CPMS=ME,ME,ME"));
waitResponse();
sendAT(GF("+CMGF=1"));
waitResponse();
sendAT(GF("+CNMI=1,0"));
waitResponse();
sendAT(GF("+CSCS=\"GSM\""));
waitResponse();
}
Initialize it after you have a valid operator. Initialize serial connection with a bigger buffer, like 512
I hope you understand i did not have time to make a merge request.
Thanks, got it to compile no problem, still waiting to receive the module but the code looks pretty straight forward. If you have anymore A6/A7 specific code let me know.
First, my question: I get the ### Unhandled message when several SMSs are being processed. Maybe someone can look up to this problem and propose a FIX?
Other than that, I added a couple of feautures and tested for the SIM900 chip.
There is a need to delete SMSs that have been read. Otherwise the SIM card can't hold more than X SMSs (my SIM card can hold up to 50 SMS and than I stops receiving any new messages)
So I added the followin code:
First, I modified the structs. I use these ones:
struct SMSmessage {
String number;
String message;
};
struct SMSList {
int* ids;
int count;
};
To delete a(a list of) message(s) I do the following:
void deleteAllReadSMS()
{
SMSList readSMS = getSMSs(true);
for(int i=0; i< readSMS.count; i++) {
deleteSMS(readSMS.ids[i]);
}
}
void deleteSMS(uint8_t i)
{
sendAT(GF("+CMGD="), i);
waitResponse(1000L, GFP(GSM_OK), GFP(GSM_ERROR));
}
And to read incoming SMS's IDs on the SIM card and count them I use:
/**
* Retreive all the SMSs that are read (if boolean set to true) or unread (if boolean
* set to false)
*/
SMSList getSMSs(bool isRead)
{
SMSList readSMS = (const struct SMSList) {
new int[0], 0
};
String data;
int index, occurrences = 0;
int* indexes = new int[occurrences];
sendAT(GF("+CMGL=\"REC "), isRead?GF("READ"):GF("UNREAD"), GF("\""));
if(waitResponse(5000L, GF("+CMGL:"), GFP(GSM_OK), GFP(GSM_ERROR))) {
do {
data = stream.readStringUntil('\n');
int pos = data.indexOf("REC " + isRead?"READ":"UNREAD");
if (pos > 0) {
index = data.substring(0, pos - 1).toInt();
// Resize to a +1 size
int* indexesT = new int[occurrences + 1];
for(int j=0; j < occurrences;j++){
indexesT[j] = indexes[j];
}
// Free memory
delete indexes;
indexes = indexesT;
indexes[occurrences] = index;
occurrences++;
// And skip until the end of text message
streamSkipUntil('\n');
}
} while (waitResponse() == 1);
}
readSMS.ids = indexes;
readSMS.count = occurrences;
return readSMS;
}
And finally, to read an individual SMS I do:
SMSmessage readSMS(uint8_t i)
{
char message[300];
char number[50];
char date[50];
char type[10];
String head;
String body;
SMSmessage sms = (const struct SMSmessage) {
"", ""
};
sendAT(GF("+CMGR="), i);
if (waitResponse(10000L, GF(GSM_NL "+CMGR:"))) {
head = stream.readStringUntil('\n');
body = stream.readStringUntil('\n');
int counter = 0;
int var = 0;
for(int i=0; i< head.length(); i++)
{
// There is a comma after comma or Quotes sign after comma
if(head.charAt(i) == ',')
{
// Skip , and " sign. I know what I'm doing!
i++; i++;
while(head.charAt(i) != ',') {
number[counter] = head.charAt(i);
// I know what I'm doing!
counter++;
i++;
}
number[counter-1] = '\0';
}
}
sms.number = String(number);
body.toCharArray(message, body.length());
sms.message = message;
}
return sms;
}
I get "### Unhandled" messages when several SMSs arrive at the same time.
For example: ### Unhandled: +CMGL: 3,"REC READ","+XXXXXXXXXXX","My Number","18/02/22,20:47:02+04"
Maybe someone can fixthis issue.
Otherwise, if only 1 sms is received at a time, it's a bit slow but looks OK.
@DmitriVLK
First, I modified the structs. I use these ones:
Your code is producing memory leaks.
Hello, i'm trying to implement sms reading in A6 by fetching SMS locations of unread sms with command "+CMGL=REC UNREAD"
Here is my code: sendAT(GF("+CSCS=UCS2")); waitResponse();
sendAT(GF("+CMGF=1")); waitResponse();
sendAT(GF("+CNMI=1,0")); waitResponse();
sendAT(GF("+CMGL="), GF("REC"), GF(" "), GF("UNREAD")); if(waitResponse(GF(GSM_NL "+CMGL:"), GF("OK"))) { data = stream.readString(); Serial.print("message: "); Serial.println(data); }
The issue is that i receive only garbage data and i don't know why. Library works just fine otherwise.
Example of received data:
Serial relay works just fine. Response should be like this: https://www.diafaan.com/sms-tutorials/gsm-modem-tutorial/at-cmgl-text-mode/ Can someone help me ? I'm stuck.