Electron Simple SMS

I’m stuck on something, hopefully simple…
If I was not interested in receiving SMS’s or responses, but just wanted to to send an sms from my Electron to my phone (using a 3rd party SIM), what would be the simplest code?
From krvarma’s post, the simple format for a direct sms should be “AT+CMGS=”"<129/145><ctrl+z>"

As a noob, I’m guessing that the implementation might look like this:
const char* phNum = “0427473xxx”;

void setup() {
Cellular.command ("AT+CMGS=",phNum,"129\r\n","Hello world",0x1A);
}

void loop() {
}

It compiles ok, but unfortunately it doesn’t work. Can someone please put me straight, or am i barking up the wrong tree?

Try prefixing the number with your country code +61 and drop the leading zero +61427473xxx

Thanks for the quick response! I tried the country code and dropping the leading zero, both with the “129” local formatted number and the “145” ISDN international formatted number. Neither work. I also tried replacing the \r\n carriage return for the ascii equivalent (0x0D), but also no result. Any other ideas?

I forgot to mention that I tried krvarma’s full code (with ‘local’ number format) and it works fine.

You need to set the operating mode first (AT+CMGF=1)

This is how I do send SMS

int sendMessage(const char* telNr, const char* msg)
{
  int  ret;
  char cmd[64];

  if (!RADIO.ready())
  {
    RADIO.on();
    RADIO.connect();
    if (!waitFor(RADIO.ready, 300000))
    {
      Log.warn("no radio connection");
      return -1;
    }
  }

  ret = Cellular.command("AT+CMGF=1\r\n");
  ret = Cellular.command("AT+CMGS=\"%s%s\",145\r\n", (telNr[0] != '+') ? "+" : "", telNr);
  ret = Cellular.command("%s\x1a", msg);
  switch (ret)
  {
    case WAIT:
      Log.info("WAITING, but probably sent");
    case RESP_OK:
      Log.info("Sent: '%s' to %s", msg, telNr);
      break;
    default:
      Log.warn("Message not sent (%d)", ret);
      break;
  }

  return ret;
}
1 Like

Thanks heaps! That was very helpful and with a little experimentation, it works! For anyone else interested, my slightly simpler implementation is:

const char* phNum = "0427473xxx";
const char* msg = "Test message";
int  ret;

void setup() {
Serial.begin(115200);
ret = Cellular.command("AT+CMGF=1\r\n");
Serial.print("Return from message format = ");
Serial.println(ret);
ret = Cellular.command("AT+CMGS=\"%s%s\",129\r\n",(phNum[0] != '+') ? "+" : "", phNum); //
Serial.print("Return from phNum send = ");
Serial.println(ret);
ret = Cellular.command("%s\x1a", msg);
Serial.print("Return from message send = ");
Serial.println(ret);

}


void loop() {

}

I now know Cellular.command returns a response (whether I like it or not!) and this has to be anticipated in the code. Also, after playing with the formatting inside the Cellular.command brackets it is clear to me that the formatting requirement is VERY particular. All those funny characters do seem to be necessary.
I’ve been trying to understand what they do, esp in the line:

ret = Cellular.command("AT+CMGS=\"%s%s\",129\r\n",(phNum[0] != '+') ? "+" : "", phNum);

I haven’t found any answers yet. Can anyone give me some pointers?

1 Like

These “funny” characters are well known to people familiar with printf()
If you want to successfully understand the syntax of that you need to look at this
http://www.cplusplus.com/reference/cstdio/printf/

You may also be stumpted by the use of the ternary operator (condition ? then : else).

I guess escaped characters ( \r, \n, \", \x1a) are nothing new tho’?

If you want to see what commands are actually sent to the module you could just use

  Serial.printlnf("AT+CMGS=\"%s%s\",129\r\n",(phNum[0] != '+') ? "+" : "", phNum);

to get the string returned via USB (mark the f in printlnf() which uses the printf formatting).

BTW, one thing your inital attempt was missing were the embedded double quotes (\") in the string - they are required. The code highliting of the snippets wrapped in the proper formating tags ( ``` ) does reveal which double quotes are embedded and which are delimiting the string.

2 Likes