I tried this code and it works fine for handling timeouts during connecting. I used an Electron with a u.fl to SMA connector on the antenna, so I could easily disconnect the antenna and it seems to work fine for me.
#include "Particle.h"
SYSTEM_MODE(MANUAL);
SYSTEM_THREAD(ENABLED);
// How often to check in milliseconds
const int CONNECT_CHECK_PERIOD_MS = 120000;
// How long to wait before considering a connect to have failed
const int CONNECT_TIMEOUT = 60000;
// How long to stay connected once we successfully connect
const int STAY_CONNECTED_TIME_MS = 2000;
// Finite state machine states
enum {
STATE_START,
STATE_CONNECTING,
STATE_READY,
STATE_DISCONNECT_WAIT,
STATE_DISCONNECT,
STATE_RETRY_WAIT
};
//
int state = STATE_START;
unsigned long stateTime = 0;
unsigned long startTime = 0;
void setup() {
Serial.begin(9600);
// This waits 10 seconds before doing the first connect so you have time to enable the serial monitor
state = STATE_RETRY_WAIT;
stateTime = CONNECT_CHECK_PERIOD_MS - 10000;
}
void loop() {
switch(state) {
case STATE_START:
Serial.println("connecting...");
startTime = stateTime = millis();
Cellular.on();
Cellular.connect();
state = STATE_CONNECTING;
break;
case STATE_CONNECTING:
if (Cellular.ready()) {
// Cellular connection established and have an IP address
state = STATE_READY;
}
else
if (Cellular.connecting()) {
if (millis() - stateTime >= CONNECT_TIMEOUT) {
Serial.println("timeout connecting");
state = STATE_DISCONNECT;
}
}
else
if (Cellular.listening()) {
// This usually happens if you have no SIM card
Serial.println("listening mode");
state = STATE_DISCONNECT;
}
break;
case STATE_READY:
Serial.printlnf("connected successfully %lu", (millis() - startTime));
state = STATE_DISCONNECT_WAIT;
stateTime = millis();
break;
case STATE_DISCONNECT_WAIT:
// In this state, the cellular connection is up, you can do IP stuff here
if (millis() - stateTime >= STAY_CONNECTED_TIME_MS) {
state = STATE_DISCONNECT;
}
break;
case STATE_DISCONNECT:
Serial.println("disconnecting...");
Cellular.disconnect();
Cellular.off();
state = STATE_RETRY_WAIT;
stateTime = millis();
break;
case STATE_RETRY_WAIT:
if (millis() - stateTime >= CONNECT_CHECK_PERIOD_MS) {
state = STATE_START;
}
break;
}
}