This works a treat using Rikkas Electronsample
I modified the checks it carries out to see if the AT / OK stops coming back, (and got rid of the PING as it doesn’t work)
void ConnectionCheck::loop() {
#define MODEM_POLL_FOR_OK_MSEC 10000
// Check cellular status - used for event logging mostly
bool temp = Cellular.ready();
if (temp != isCellularReady) {
// Cellular state changed
isCellularReady = temp;
Log.info("cellular %s", isCellularReady ? "up" : "down");
}
if (millis() - listenWaitForOK >= MODEM_POLL_FOR_OK_MSEC) {
listenWaitForOK = millis();
if (!CheckForModemResponseOK()){
Log.info("Modem didn't respond, rebooting modem (not rebooting processor)");
fullModemReset();
}
}
if (Cellular.listening()) {
// Entered listening mode (blinking blue). Could be from holding down the MODE button, or
// by repeated connection failures, see: https://github.com/spark/firmware/issues/687
if (listeningStart == 0) {
listeningStart = millis();
Log.info("entered listening mode");
}
else {
if (listenWaitForReboot != 0 && millis() - listeningStart >= listenWaitForReboot) {
// Reboot
fullModemReset();
}
}
}
}
bool ConnectionCheck::CheckForModemResponseOK(){
if (RESP_OK == Cellular.command("AT\r\n")){
return true;
}
return false;
}
Then if anything goes wrong I simply wiggle the pins on the reset line of the Modem, clear the state, and reconnect.
void ConnectionCheck::fullModemReset() {
Log.info("fullModemReset - resetting modem");
// Reset the modem and SIM card
// 16:MT silent reset (with detach from network and saving of NVM parameters), with reset of the SIM card
//Cellular.command(30000, "AT+CFUN=16\r\n");
ModemHardReset();
delay(1000);
//tell the processor to clear any state.
Cellular.disconnect();
cloud_connect();
}
//firmware\hal\src\electron\modem\mdm_hal.cpp
void ConnectionCheck::ModemHardReset(){
Log.info("[ Modem Hard reset ]");
const unsigned delay = 100;
HAL_GPIO_Write(RESET_UC, 0);
HAL_Delay_Milliseconds(delay);
HAL_GPIO_Write(RESET_UC, 1);
}