Just recently I did something like that for another project
SYSTEM_MODE(SEMI_AUTOMATIC)
SYSTEM_THREAD(ENABLED)
STARTUP(cellular_credentials_set("yourAPN", "", "", NULL))
SerialLogHandler serlog;
#define RADIO Cellular
int placeCall(const char* telNr, uint32_t duration = 30000);
int sendMessage(const char* telNr, const char* msg);
void setup() {
RADIO.on();
RADIO.connect();
Particle.connect();
}
void loop() {
static uint32_t ms = 0;
if (millis() - ms > 60000) {
ms = millis();
placeCall("+##########"); // target phone number international format
sendMessage("+########", "Hi there, I'm Electron!");
}
}
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");
case RESP_OK:
Log.info("Sent: '%s' to %s", msg, telNr);
break;
default:
Log.warn("Message not sent (%d)", ret);
break;
}
return ret;
}
int placeCall(const char* telNr, uint32_t duration)
{
int ret;
if (!RADIO.ready())
{
RADIO.on();
RADIO.connect();
if (!waitFor(RADIO.ready, 300000))
{
Log.warn("no radio connection");
return -1;
}
}
if ((ret = Cellular.command("ATD%s;\r\n", telNr)) == RESP_OK)
{
Log.info("Call pending");
softDelay(duration);
Cellular.command("AT+CHUP\r\n");
Log.info("Hung up");
}
else
{
Log.warn("Call not possible (%d)", ret);
}
return ret;
}
inline void softDelay(uint32_t msDelay)
{
for (uint32_t ms=millis(); millis()-ms < msDelay; Particle.process());
}