This is a description of a bug in the Particle firmware that I found which causes Electron to not be able to wake from sleep if the network connection process is aborted.
Specs
- U260 Electron
- Firmware
release/v0.6.2
- Plugged into a breadboard with no other connections
This is related to a post I started about a bug in the Particle Firmware that seems to corrupt the Particle Network connectivity state machines when a connection process is aborted:
I have found through trying to find a workaround to the above problem that this bug corrupts the
System.sleep(uint16_t wakeUpPin, uint16_t edgeTriggerMode, long seconds)
process as well.
When this type of sleep mode is invoked while the Electron is attempting to connect to the cellular network, the Electron will not wake from sleep with either a hardware pin interrupt or a timer.
The following test program illustrates this.
#include "Particle.h"
SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);
/*=============================================>>>>>
= Function forward declarations =
===============================================>>>>>*/
// Forward declarations
void waitForSerialInput();
SerialLogHandler logHandler(LOG_LEVEL_ALL, //Default logging level for non-application messages
{
{ "app", LOG_LEVEL_ALL }, //Logging level for logs from any application .cpp file not specified below
}
);
static Logger myLog("app.main"); //Logger object used in this "main.cpp" file
/*=============================================>>>>>
= SETUP FUNCTION =
===============================================>>>>>*/
void setup() {
pinMode(D4, INPUT_PULLDOWN);
Serial.begin(115200);
//Wait for user to open the serial monitor
waitForSerialInput();
// Cellular.connect(); //<---Uncommenting this line results in Electron not waking from sleep
Particle.connect(); //<---Uncommenting this line results in Electron not waking from sleep
delay(5000);
myLog.info("Sleeping for 10 seconds");
Particle.process();
delay(1000);
System.sleep(D4, RISING , 10) ; //<--This never wakes up from sleep if Cellular.connect() or Particle.connect() are called first!
Particle.process();
Particle.connect();
}
/*=============================================>>>>>
= MAIN LOOP =
===============================================>>>>>*/
void loop() {
delay(10000);
if(Particle.connected()){
myLog.info("Connected");
}
else{
myLog.info("Connecting");
}
}
//Function that waits for user to input a character via the serial monitor
#define WAIT_FOR_SERIAL_MONITOR_TIMEOUT 10000 //Time after the Electron restarts to wait for a serial character to be entered before proceeding
void waitForSerialInput(){
unsigned long timeStart = millis();
while(!Serial.available()){
if((millis() - timeStart) > WAIT_FOR_SERIAL_MONITOR_TIMEOUT){
myLog.warn("Waiting for serial input timed out!");
return;
}
myLog.warn("Waiting for serial input before proceeding");
delay(500);
}
//Now we need to empty the serial buffer
while(Serial.available()){
/*char uselessChar = */Serial.read();
}
myLog.warn("Received serial input, now proceeding!");
// while(!Serial.isConnected())
// Particle.process();
myLog.info("Serial monitor open! Now proceeding!");
}