MKR GSM1400 storing SMS to memory

Dear All please can you offer some advice relating to storage on the MKR1400

I wish to send a text message to the board containing a phone number and have the MKR1400 use that number to make a number of outgoing calls

I have been reading through some post here but there is not a great deal of information on the subject

someone suggested saving to EEPROM but I get and error "nrf.h no such file or directory" upon further investigation it seems that the MKR1400 does not have EEPROM and the only solution I can find is to save to flash memory but that has a restriction of 10,000 flashes, although this will provide quite a lot of changes I really do not want to be restricted or damage the boards

can the SMS in the format "+447771871234" be stored to an array and then used as the number to call?

and here is where I am going to get such a lot of criticism....I need to tell the sending MKR1400 how many calls to make, until now I have been running the system right in front of me but I wish to run this remotely so wish to tell the remote MKR1400 how many calls to make ie "+447771871234, 20" (call that number 20 times)

whilst running in front of me I used the following which I know is horrific, this enables me to make sometimes thousands of calls back to back, I am braced for the backlash....

 if (inChar == '\n') {
      
        // let the user know you're calling:
        Serial.print("Calling to : ");
        Serial.println(inChar);
        Serial.println();
bookmark:
 delay(500);
        // Call the remote number

 
        // Check if the receiving end has picked up the call
        if (vcs.voiceCall(charbuffer)) {
          Serial.println("Call Established.");
          // hang up
          vcs.hangCall();
         
        }
        Serial.println("Redial");
goto bookmark;    }
    }

as I have said before this may detect a certain type of fraud but it needs more finesse to be more efficient and effective

thanks and dont be too hard on me

You can see this coming indeed :slight_smile:

Would be best to explain what’s the legitimate use... let us know your number and we will ask your board to call itself 1000000 times.. :slight_smile:

(there is no technical issue parsing the sms and extracting the data and keep it in memory - as long as your board does not crash and you have enough memory , it will be there for you)

I see goto in that code. My eyes burn.

Op, why in the world are you wanting something that spams calls?

ok I thought I would get jip for using "goto" in the sketch not the legitimate use of it,

so let me explain, I am the Fraud (and Revenue Assurance) Director for a large telecoms group, I have been using this system/method to detect a certain type of fraud, it is very effective, all calls are to and from my own SIMs,

there is no arbitrage occurring and its not used for fraud or other types of scam, there are plenty of those out there, it could be used for that but it would be picked up by other Fraud Management Systems very quickly

you state

J-M-L:
(there is no technical issue parsing the sms and extracting the data and keep it in memory - as long as your board does not crash and you have enough memory , it will be there for you)

when you say memory do you mean string? I find the examples/reference of strig/char/array all that very confusing (and not very detailed)

thanks

Dan

Romonaga:
I see goto in that code. My eyes burn.

Op, why in the world are you wanting something that spams calls?

it makes my eyes burn also and I wrote it! cant wait until PaulS sees it, I expect a colourful response...

I don't really understand why calling 20 times your own SIM helps with Fraud... would be interesting to share!

if you handle your module through AT commands, you can use Robins' Serial Input Basics to read what's coming from the SMS and then parse it and store the phone number in a cString. (use function from stdlib.h and string.h to parse and copy the data)

great thanks for the reply, I will research those areas

if you want more details on the specifics you can PM me, discussing the details on an open forum would be reckless

regards

Dan

J-M-L I am not sure how AT commands are going to simplify things, are they not for manual input into the serial monitor? can I not just read the memory and make the voice call from that?

I will try to represent the objective in a diagram, I have added AT commands as I understand them, currently the sketch I use to make the calls reads the serial input where I enter a phone number and it calls to that number until I terminate it, I am trying to automate this by sending the transmit arduino an SMS with the number to call and how many times to call it

I am trying to automate this by sending the transmit arduino an SMS with the number to call and how many times to call it

Where in the diagram is the problem are you having?

Can you receive an SMS? Can you store the message you receive? Can you parse the number and times from the message?

Have you read the recommended tutorial by Robin2 on Serial Input Basics?

The question on AT commands is more to know if you plan to use a high level library to access SMS or handle things at lower level. Basically to know which API you’ll be using

cattledog:
Can you store the message you receive? Can you parse the number and times from the message?

this is the part I am finding challenging, if I knew the best/correct option I dont think I will have a problem finalising the sketch, the issue I find is I get directed to a huge, wide ranging amount of reference information which never has enough use cases or examples or is so general in nature I cannot determine if its the correct method

cattledog:
Have you read the recommended tutorial by Robin2 on Serial Input Basics?

yes and I dont see how this helps, why use serial input? I do not intend on sitting there looking at the serial monitor, the system will be remote, I will not have access to it, so why use serial when I just need to record the message and then use that to initiate the call, I thought I could do it with char but my efforts so far have failed, my sketch is not in a fit state to be posted yet

@J-M-L, did my PM clarify the use case? I think I aim to handle at a low level, I have used AT commands in the serial monitor to gain information about the network and to make calls etc but that is manual

to date I have been using something similar to this

void loop() {

// add any incoming characters to the String:
while (Serial.available() > 0) {
char inChar = Serial.read();
// if it's a newline, that means you should make the call:
if (inChar == '\n') {
// make sure the phone number is not too long:
if (remoteNumber.length() < 20) {
// let the user know you're calling:
Serial.print("Calling to : ");
Serial.println(remoteNumber);
Serial.println();
delay(500);
// Call the remote number
remoteNumber.toCharArray(charbuffer, 20);

// Check if the receiving end has picked up the call
if (vcs.voiceCall(charbuffer)) {
Serial.println("Call Established.");
// hang up
vcs.hangCall();

including the most excellent "goto" function :slight_smile:

Dan

ahhhhhh J-M-L are you suggesting sending the SMS in AT command format?

only thing is I dont want to hard code the number of calls to be made (or an endless loop) and I do not want to send an SMS for every single call

Dan

Dan0:
ahhhhhh J-M-L are you suggesting sending the SMS in AT command format?

only thing is I dont want to hard code the number of calls to be made (or an endless loop) and I do not want to send an SMS for every single call

Dan

and that works perfectly! nice one J-M-L your a genius and generous with sharing your knowledge!

now all I have to do is work out a way of repeating the calls *number of times by either the same text or new text (that I think is even more tricky)

I wonder if an AT command to stop/reset will interrupt the voice calls...

OK so not exactly perfectly...

yes sending ATH will hang the call up but sending anything else (ie a marketing SMS or spam) seems to freezer the board. I expect it is trying to write that to serial.GSM and it doesnt know what to do

needs some kind of check, does anyone happen to know if if(sms.peek()=='#') wicll check two digits or just the first? ie if(sms.peek()=='AT')

BTW does anyone else have any issues with these boards and COM ports?

thanks

Dan

Hi

No that was not what I was hinting. There are many ways to talk to the SARAU201 GSM module. Low level where you handle everything yourself, or high level using a library.

Reading from your last question, it seems you use the MKRGSM library, which includes a GSM_SMS class

The reference to the Serial tutorial was applicable if you were to read at low level the information from your modem

As when you receive an SMS, the library offers an API that is similar to the Streams (using available() and read()) so you can build a cString and then parse it.

Imagine running this:

// Array to hold the text of the SMS
const byte maxSMSLength = 100;
char smsMessageBody[maxSMSLength + 1];

void setup() {
  Serial.begin(115200);
  // simulate receiving the SMS
  strcpy(smsMessageBody, "garbage +4418779, 20 garbage");

  // parse using strtok: http://www.cplusplus.com/reference/cstring/strtok/
  strtok (smsMessageBody, "+"); // replace the + by a NULL CHAR
  const char * phoneNumberToCallPtr = strtok (NULL, ","); // replace the ',' by a NULL char, pointer after the ','
  const char * numberofCallsPtr = strtok (NULL, ""); // we just want the next pointer

  // transform the string into a number http://www.cplusplus.com/reference/cstdlib/atoi/
  const int totalNumberOfCalls = atoi(numberofCallsPtr);

  Serial.print(F("Calling [+"));
  Serial.print(phoneNumberToCallPtr); // carefull we removed the +
  Serial.print(F("] for "));
  Serial.print(totalNumberOfCalls);
  Serial.print(F(" times"));
}

void loop() {}

(typed here so not tested).

You should see in the console

[color=purple]Calling [+4418779] for 20 times[/color]

that shows you how I was able to extract from a cString the phone number and then the number of times. So if you were able to receive your SMS into a cString, you could just extract the information that way.

So now if you take the ReceiveSMS example from the documentation and inject the above code into it after building a small buffer with the SMS message, you should be able to have your info in memory as you want and able to proceed

again - I don't have an arduino with me now but that's how a simple structure could work:

#include <MKRGSM.h>
const char PINNUMBER[] = "0000";

// initialize the library instances
GSM gsmAccess;
GSM_SMS sms;

// Array to hold the number a SMS is retreived from
char senderNumber[20];

// Array to hold the text of the SMS
const byte maxSMSLength = 50;
char smsMessageBody[maxSMSLength + 1];

void setup() {
  // initialize serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) ;

  // Start GSM connectionx
  bool connected = false;
  while (!connected) {
    if (gsmAccess.begin(PINNUMBER) == GSM_READY) {
      connected = true;
    } else {
      Serial.write('.');
      delay(1000);
    }
  }

  Serial.println("GSM initialized");
  Serial.println("Waiting for messages");
}

void loop() {
  int c;

  // If there are any SMSs available()
  if (sms.available()) {
    Serial.println("Message received from:");

    // Get remote number
    sms.remoteNumber(senderNumber, 20);
    Serial.println(senderNumber);

    // Read message bytes and print them
    int i = 0;
    while (((c = sms.read()) != -1) && (i < maxSMSLength)) {
      smsMessageBody[i++] = c;
    }
    smsMessageBody[i] = '\0'; // terminate the cString correctly

    Serial.print(F("Received:"));
    Serial.println(smsMessageBody);

    // Delete message from modem memory
    sms.flush();


    // this is now where you need to parse the SMS body.
    // assume the format is "+YYxxxxxxxxxxx, 20"
    // here this is a crude parser, with no test for error

    // parse using strtok: http://www.cplusplus.com/reference/cstring/strtok/
    strtok (smsMessageBody, "+"); // replace the + by a NULL CHAR
    const char * phoneNumberToCallPtr = strtok (NULL, ","); // replace the ',' by a NULL char, pointer after the ','
    const char * totalNumberOfCallsPtr = strtok (NULL, ""); // we just want the next pointer

    // transform the string into a number http://www.cplusplus.com/reference/cstdlib/atoi/
    const int totalNumberOfCalls = atoi(totalNumberOfCallsPtr);

    Serial.print(F("Calling [+"));
    Serial.print(phoneNumberToCallPtr); // carefull we removed the +
    Serial.print(F("] for "));
    Serial.print(totalNumberOfCalls);
    Serial.print(F(" times"));

    for (int callNb = 0; callNb < totalNumberOfCalls; callNb++) {
      Serial.print(F("Call #"));
      Serial.print(callNb + 1);

      // HERE PUT THE CODE TO PLACE A CALL
      // remember to add the + in the dialing
      // (see example in https://www.arduino.cc/en/Reference/GSMVCSVoiceCall)

    }
  }

  delay(1000);

}

(to be tested, typed here)

The code to place calls should be taken from the example

hope this helps

Basically to know which API you'll be using

Reading from your last question, it seems you use the MKRGSM library, which includes a GSM_SMS class

Your crystal ball is very good. Or did I miss something in this thread? :confused:

Wells the sms.peek() thingy was the giveaway.... maybe....

J-M-L:
Hi

No that was not what I was hinting. There are many ways to talk to the SARAU201 GSM module. Low level where you handle everything yourself, or high level using a library.

Reading from your last question, it seems you use the MKRGSM library, which includes a GSM_SMS class

The reference to the Serial tutorial was applicable if you were to read at low level the information from your modem

As when you receive an SMS, the library offers an API that is similar to the Streams (using available() and read()) so you can build a cString and then parse it.

thanks J-M-L, that is certainly more elegant than sending AT commands and may solve the issue I am facing with the board hanging, I wonder if this method will actually need the error/format check, it will either work or not work is my guess which is fine , I will give it a try and report back

well its almost there

13:47:28.449 -> GSM initialized
13:47:28.449 -> Waiting for messages
13:48:05.695 -> Message received from:
13:48:05.695 -> +31620541234
13:48:05.695 -> Received:+447771871234, 5
13:48:05.741 -> Calling [+] for 0 times

dont know why its showing that last line as a bullet, in the monitor the zero follows the "for" the plus sign in brackets appears before the "for, the phone number is missing

I will have to get my head around this

Dan

Hey - post your code, hard to help ptherwise