Hi,
We went on to further investigate this issue but weren’t able to reproduce the problem, even though three other Electrons exhibited the same behaviour. Funny enough, after a reset, they went back to working properly and didn’t have this “getting stuck” problem anymore (for now).
A few days ago we were trying to obtain cell environment information by means of AT commands. AT+CGED=3 (serving cell) always returned the expected result but AT+CGED=0 or 5 (serving and neighbour cells) rarely returned anything at all. Most of the time it would just timeout.
The interesting part (where we got really lucky) is that if we would try to do a Cellular.disconnect() or Cellular.off() after such a timeout, the Electron would just go into that weird state of looking connected but actually being dead.
So we got to a point where we could consistently reproduce the problem. Here is the code we’re using:
CellLocation.h
#ifndef CellLocation_H
#define CellLocation_H
#include "string.h"
using namespace std;
void setupSerial() {
Serial.begin(9600);
while(!Serial.available()) {
Particle.process();
}
while(Serial.available()) {
Serial.read();
}
Serial.println("Serial start.");
}
void fullReset() {
Particle.disconnect();
Cellular.disconnect();
Cellular.off();
System.reset();
}
int getCellInfoCallback(int type, const char* response, int responseLength, string* const cellInfo) {
int returnValue = RESP_ERROR;
/* Debugging */
// string resp;
// resp.append(response, 2, responseLength - 4);
// Serial.printlnf("t: %d. l: %d. r: %s.", type, responseLength, resp.c_str());
switch (type) {
case TYPE_UNKNOWN:
case TYPE_TEXT:
case TYPE_PLUS:
cellInfo->append(response, 2, responseLength - 4);
returnValue = WAIT;
break;
case TYPE_OK:
returnValue = RESP_OK;
break;
case TYPE_ERROR:
returnValue = RESP_ERROR;
break;
default:
returnValue = RESP_ERROR;
break;
}
return returnValue;
}
string getCellInfo() {
int retries = 0, result;
string cellInfo;
while (retries < 3
&& (result = Cellular.command(getCellInfoCallback, &cellInfo, 10000, "AT+CGED=5\r\n")) != RESP_OK) {
delay(30);
retries++;
Particle.process();
Serial.printlnf("Retry. Result: %d.", result);
}
if (retries >= 3) {
fullReset();
}
return cellInfo;
}
#endif
CellLocation.cpp
#include "application.h"
#include "CellLocation.h"
SYSTEM_MODE(SEMI_AUTOMATIC);
STARTUP(cellular_credentials_set("our.own.apn", "", "", NULL));
int ledPin = D7;
string info;
void setup() {
pinMode(ledPin, OUTPUT);
setupSerial();
Cellular.connect();
while(!Cellular.ready()) {
Particle.process();
}
//Particle.connect();
}
void loop() {
digitalWrite(ledPin, HIGH);
delay(500);
info = getCellInfo();
Serial.printlnf("Cell info: %s.", info.c_str());
fullReset();
digitalWrite(ledPin, LOW);
delay(500);
}
We’ve experimented with different timeout values and number of retries but the result is the same: when CGED times out, the fullReset function will just get stuck at Cellular.off(). If we changed CGED=5 to CGED=3 (which never times out) everything works fine.