diff --git a/code/espurna/config/general.h b/code/espurna/config/general.h index 0a0e5512..357db0f2 100644 --- a/code/espurna/config/general.h +++ b/code/espurna/config/general.h @@ -57,6 +57,14 @@ #define TERMINAL_SUPPORT 1 // Enable terminal commands #endif +//------------------------------------------------------------------------------ +// CRASH +//------------------------------------------------------------------------------ + +#define CRASH_SAFE_TIME 60000 // The system is considered stable after these many millis +#define CRASH_COUNT_MAX 5 // After this many crashes on boot + // the system is flagged as unstable + //------------------------------------------------------------------------------ // EEPROM //------------------------------------------------------------------------------ @@ -65,7 +73,8 @@ #define EEPROM_RELAY_STATUS 0 // Address for the relay status (1 byte) #define EEPROM_ENERGY_COUNT 1 // Address for the energy counter (4 bytes) #define EEPROM_CUSTOM_RESET 5 // Address for the reset reason (1 byte) -#define EEPROM_DATA_END 6 // End of custom EEPROM data block +#define EEPROM_CRASH_COUNTER 6 // Address for the crash counter (1 byte) +#define EEPROM_DATA_END 7 // End of custom EEPROM data block //------------------------------------------------------------------------------ // HEARTBEAT diff --git a/code/espurna/debug.ino b/code/espurna/debug.ino index 0610096e..128c357c 100644 --- a/code/espurna/debug.ino +++ b/code/espurna/debug.ino @@ -33,13 +33,15 @@ void debugSend(const char * format, ...) { #endif #if DEBUG_UDP_SUPPORT - udpDebug.beginPacket(DEBUG_UDP_IP, DEBUG_UDP_PORT); - udpDebug.write(buffer); - if (len > DEBUG_MESSAGE_MAX_LENGTH) { - udpDebug.write(" (...)\n"); + if (systemCheck()) { + udpDebug.beginPacket(DEBUG_UDP_IP, DEBUG_UDP_PORT); + udpDebug.write(buffer); + if (len > DEBUG_MESSAGE_MAX_LENGTH) { + udpDebug.write(" (...)\n"); + } + udpDebug.endPacket(); + delay(1); } - udpDebug.endPacket(); - delay(1); #endif } @@ -64,13 +66,15 @@ void debugSend_P(PGM_P format, ...) { #endif #if DEBUG_UDP_SUPPORT - udpDebug.beginPacket(DEBUG_UDP_IP, DEBUG_UDP_PORT); - udpDebug.write(buffer); - if (len > DEBUG_MESSAGE_MAX_LENGTH) { - udpDebug.write(" (...)\n"); + if (systemCheck()) { + udpDebug.beginPacket(DEBUG_UDP_IP, DEBUG_UDP_PORT); + udpDebug.write(buffer); + if (len > DEBUG_MESSAGE_MAX_LENGTH) { + udpDebug.write(" (...)\n"); + } + udpDebug.endPacket(); + delay(1); } - udpDebug.endPacket(); - delay(1); #endif } diff --git a/code/espurna/espurna.ino b/code/espurna/espurna.ino index c1ffdd92..0609d56c 100644 --- a/code/espurna/espurna.ino +++ b/code/espurna/espurna.ino @@ -47,6 +47,14 @@ void hardwareSetup() { void hardwareLoop() { + // System check + static bool checked = false; + if (!checked && (millis() > CRASH_SAFE_TIME)) { + // Check system as stable + systemCheck(true); + checked = true; + } + // Heartbeat static unsigned long last_uptime = 0; if ((millis() - last_uptime > HEARTBEAT_INTERVAL) || (last_uptime == 0)) { @@ -198,15 +206,29 @@ void welcome() { void setup() { + // Init EEPROM, Serial and SPIFFS hardwareSetup(); + + // Question system stability + systemCheck(false); + + // Show welcome message and system configuration welcome(); + // Init persistance and terminal features settingsSetup(); if (getSetting("hostname").length() == 0) { setSetting("hostname", getIdentifier()); saveSettings(); } + delay(500); + wifiSetup(); + otaSetup(); + + // Do not run the next services if system is flagged stable + if (!systemCheck()) return; + #if WEB_SUPPORT webSetup(); #endif @@ -217,11 +239,6 @@ void setup() { relaySetup(); buttonSetup(); ledSetup(); - - delay(500); - - wifiSetup(); - otaSetup(); mqttSetup(); #ifdef ITEAD_SONOFF_RFBRIDGE @@ -276,13 +293,17 @@ void setup() { void loop() { hardwareLoop(); + settingsLoop(); + wifiLoop(); + otaLoop(); + + // Do not run the next services if system is flagged stable + if (!systemCheck()) return; + buttonLoop(); relayLoop(); ledLoop(); - wifiLoop(); - otaLoop(); mqttLoop(); - settingsLoop(); #ifdef ITEAD_SONOFF_RFBRIDGE rfbLoop(); diff --git a/code/espurna/utils.ino b/code/espurna/utils.ino index c8428cb0..505ca907 100644 --- a/code/espurna/utils.ino +++ b/code/espurna/utils.ino @@ -122,6 +122,8 @@ void heartbeat() { } +// ----------------------------------------------------------------------------- + void customReset(unsigned char status) { EEPROM.write(EEPROM_CUSTOM_RESET, status); EEPROM.commit(); @@ -137,6 +139,39 @@ unsigned char customReset() { return status; } +// ----------------------------------------------------------------------------- + +// Call this method on boot with start=true to increase the crash counter +// Call it again once the system is stable to decrease the counter +// If the counter reaches CRASH_COUNT_MAX then the system is flagged as unstable +// setting _systemOK = false; +// +// An unstable system will only have serial access, WiFi in AP mode and OTA + +bool _systemStable = true; + +void systemCheck(bool stable) { + unsigned char value = EEPROM.read(EEPROM_CRASH_COUNTER); + if (stable) { + value = 0; + DEBUG_MSG_P(PSTR("[MAIN] System OK\n")); + } else { + if (++value > CRASH_COUNT_MAX) { + _systemStable = false; + value = 0; + DEBUG_MSG_P(PSTR("[MAIN] System UNSTABLE\n")); + } + } + EEPROM.write(EEPROM_CRASH_COUNTER, value); + EEPROM.commit(); +} + +bool systemCheck() { + return _systemStable; +} + +// ----------------------------------------------------------------------------- + char * ltrim(char * s) { char *p = s; while ((unsigned char) *p == ' ') ++p; diff --git a/code/espurna/wifi.ino b/code/espurna/wifi.ino index 68968113..931baa10 100644 --- a/code/espurna/wifi.ino +++ b/code/espurna/wifi.ino @@ -59,6 +59,9 @@ void wifiConfigure() { jw.setAPMode(WIFI_AP_MODE); jw.cleanNetworks(); + // If system is flagged unstable we do not init wifi networks + if (!systemCheck()) return; + int i; for (i = 0; i< WIFI_MAX_NETWORKS; i++) { if (getSetting("ssid" + String(i)).length() == 0) break;