diff --git a/code/espurna/alexa.ino b/code/espurna/alexa.ino
index 48a26c26..ee9a375f 100644
--- a/code/espurna/alexa.ino
+++ b/code/espurna/alexa.ino
@@ -68,6 +68,9 @@ void alexaSetup() {
return relayStatus(device_id);
});
+ // Register loop
+ espurnaRegisterLoop(alexaLoop);
+
}
void alexaLoop() {
diff --git a/code/espurna/button.ino b/code/espurna/button.ino
index e12f3119..101183c1 100644
--- a/code/espurna/button.ino
+++ b/code/espurna/button.ino
@@ -184,6 +184,9 @@ void buttonSetup() {
DEBUG_MSG_P(PSTR("[BUTTON] Number of buttons: %u\n"), _buttons.size());
+ // Register loop
+ espurnaRegisterLoop(buttonLoop);
+
}
void buttonLoop() {
diff --git a/code/espurna/config/sensors.h b/code/espurna/config/sensors.h
index 5844f2e9..beac93f0 100644
--- a/code/espurna/config/sensors.h
+++ b/code/espurna/config/sensors.h
@@ -474,7 +474,8 @@
#define I2C_CLOCK_STRETCH_TIME 200 // BRZO clock stretch time
#define I2C_SCL_FREQUENCY 1000 // BRZO SCL frequency
-#define I2C_CLEAR_BUS 0 // Clear I2C bus at boot
+#define I2C_CLEAR_BUS 0 // Clear I2C bus on boot
+#define I2C_PERFORM_SCAN 1 // Perform a bus scan on boot
//--------------------------------------------------------------------------------
// Internal power monitor
diff --git a/code/espurna/espurna.ino b/code/espurna/espurna.ino
index a6d278a3..24244b4b 100644
--- a/code/espurna/espurna.ino
+++ b/code/espurna/espurna.ino
@@ -20,10 +20,17 @@ along with this program. If not, see .
*/
#include "config/all.h"
+#include
+std::vector _loop_callbacks;
+
+// -----------------------------------------------------------------------------
+// REGISTER
// -----------------------------------------------------------------------------
-unsigned long _loopDelay = 0;
+void espurnaRegisterLoop(void (*callback)()) {
+ _loop_callbacks.push_back(callback);
+}
// -----------------------------------------------------------------------------
// BOOTING
@@ -31,13 +38,8 @@ unsigned long _loopDelay = 0;
void setup() {
- // Init EEPROM, Serial and SPIFFS
- hardwareSetup();
-
- // Question system stability
- #if SYSTEM_CHECK_ENABLED
- systemCheck(false);
- #endif
+ // Init EEPROM, Serial, SPIFFS and system check
+ systemSetup();
// Init persistance and terminal features
settingsSetup();
@@ -46,24 +48,31 @@ void setup() {
}
setBoardName();
- // Cache loop delay value to speed things (recommended max 250ms)
- _loopDelay = atol(getSetting("loopDelay", LOOP_DELAY_TIME).c_str());
-
// Show welcome message and system configuration
info();
+ // -------------------------------------------------------------------------
// Basic modules, will always run
+ // -------------------------------------------------------------------------
+
wifiSetup();
otaSetup();
#if TELNET_SUPPORT
telnetSetup();
#endif
- // Do not run the next services if system is flagged stable
+ // -------------------------------------------------------------------------
+ // Check if system is stable
+ // -------------------------------------------------------------------------
+
#if SYSTEM_CHECK_ENABLED
if (!systemCheck()) return;
#endif
+ // -------------------------------------------------------------------------
+ // Next modules will be only loaded if system is flagged as stable
+ // -------------------------------------------------------------------------
+
// Init webserver required before any module that uses API
#if WEB_SUPPORT
webSetup();
@@ -71,19 +80,23 @@ void setup() {
apiSetup();
#endif
+ // lightSetup must be called before relaySetup
#if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
lightSetup();
#endif
+
relaySetup();
buttonSetup();
ledSetup();
#if MQTT_SUPPORT
mqttSetup();
#endif
-
#if MDNS_SERVER_SUPPORT
mdnsServerSetup();
#endif
+ #if MDNS_CLIENT_SUPPORT
+ mdnsClientSetup();
+ #endif
#if LLMNR_SUPPORT
llmnrSetup();
#endif
@@ -98,12 +111,7 @@ void setup() {
#endif
#if I2C_SUPPORT
i2cSetup();
- #if I2C_CLEAR_BUS
- i2cClearBus();
- #endif
- i2cScan();
#endif
-
#ifdef ITEAD_SONOFF_RFBRIDGE
rfbSetup();
#endif
@@ -152,67 +160,9 @@ void setup() {
void loop() {
- hardwareLoop();
- settingsLoop();
- wifiLoop();
- otaLoop();
-
- #if SYSTEM_CHECK_ENABLED
- systemCheckLoop();
- // Do not run the next services if system is flagged stable
- if (!systemCheck()) return;
- #endif
-
- #if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
- lightLoop();
- #endif
- relayLoop();
- buttonLoop();
- ledLoop();
- #if MQTT_SUPPORT
- mqttLoop();
- #endif
-
- #ifdef ITEAD_SONOFF_RFBRIDGE
- rfbLoop();
- #endif
- #if SSDP_SUPPORT
- ssdpLoop();
- #endif
- #if NTP_SUPPORT
- ntpLoop();
- #endif
- #if ALEXA_SUPPORT
- alexaLoop();
- #endif
- #if NOFUSS_SUPPORT
- nofussLoop();
- #endif
- #if RF_SUPPORT
- rfLoop();
- #endif
- #if IR_SUPPORT
- irLoop();
- #endif
- #if SENSOR_SUPPORT
- sensorLoop();
- #endif
- #if THINGSPEAK_SUPPORT
- tspkLoop();
- #endif
- #if SCHEDULER_SUPPORT
- schLoop();
- #endif
- #if MDNS_CLIENT_SUPPORT
- mdnsClientLoop();
- #endif
-
- // 3rd party code hook
- #if USE_EXTRA
- extraLoop();
- #endif
-
- // Power saving delay
- delay(_loopDelay);
+ // Call registered loop callbacks
+ for (unsigned char i = 0; i < _loop_callbacks.size(); i++) {
+ (_loop_callbacks[i])();
+ }
}
diff --git a/code/espurna/hardware.ino b/code/espurna/hardware.ino
deleted file mode 100644
index b5e534e7..00000000
--- a/code/espurna/hardware.ino
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-
-HARDWARE MODULE
-
-Copyright (C) 2018 by Xose Pérez
-
-*/
-
-#include
-
-void hardwareSetup() {
-
- EEPROM.begin(EEPROM_SIZE);
-
- #if DEBUG_SERIAL_SUPPORT
- DEBUG_PORT.begin(SERIAL_BAUDRATE);
- #if DEBUG_ESP_WIFI
- DEBUG_PORT.setDebugOutput(true);
- #endif
- #elif defined(SERIAL_BAUDRATE)
- Serial.begin(SERIAL_BAUDRATE);
- #endif
-
- #if SPIFFS_SUPPORT
- SPIFFS.begin();
- #endif
-
- #if defined(ESPLIVE)
- //The ESPLive has an ADC MUX which needs to be configured.
- pinMode(16, OUTPUT);
- digitalWrite(16, HIGH); //Defualt CT input (pin B, solder jumper B)
- #endif
-
-}
-
-void hardwareLoop() {
-
- // Heartbeat
- #if HEARTBEAT_ENABLED
- static unsigned long last = 0;
- if ((last == 0) || (millis() - last > HEARTBEAT_INTERVAL)) {
- last = millis();
- heartbeat();
- }
- #endif // HEARTBEAT_ENABLED
-
-}
diff --git a/code/espurna/i2c.ino b/code/espurna/i2c.ino
index 9c396fe9..712fc209 100644
--- a/code/espurna/i2c.ino
+++ b/code/espurna/i2c.ino
@@ -196,6 +196,14 @@ void i2cSetup() {
DEBUG_MSG_P(PSTR("[I2C] Using GPIO%u for SDA and GPIO%u for SCL\n"), sda, scl);
+ #if I2C_CLEAR_BUS
+ i2cClearBus();
+ #endif
+
+ #if I2C_PERFORM_SCAN
+ i2cScan();
+ #endif
+
}
#endif
diff --git a/code/espurna/ir.ino b/code/espurna/ir.ino
index 13d23f15..ae951baf 100644
--- a/code/espurna/ir.ino
+++ b/code/espurna/ir.ino
@@ -92,8 +92,13 @@ void _irProcessCode(unsigned long code) {
// -----------------------------------------------------------------------------
void irSetup() {
+
_ir_recv = new IRrecv(IR_PIN);
_ir_recv->enableIRIn();
+
+ // Register loop
+ espurnaRegisterLoop(irLoop);
+
}
void irLoop() {
diff --git a/code/espurna/led.ino b/code/espurna/led.ino
index 86e1dbf6..412212f9 100644
--- a/code/espurna/led.ino
+++ b/code/espurna/led.ino
@@ -167,6 +167,10 @@ void ledSetup() {
DEBUG_MSG_P(PSTR("[LED] Number of leds: %d\n"), _leds.size());
+ // Register loop
+ espurnaRegisterLoop(ledLoop);
+
+
}
void ledLoop() {
diff --git a/code/espurna/light.ino b/code/espurna/light.ino
index 131c2ca7..eb05913b 100644
--- a/code/espurna/light.ino
+++ b/code/espurna/light.ino
@@ -1041,7 +1041,4 @@ void lightSetup() {
}
-void lightLoop(){
-}
-
#endif // LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
diff --git a/code/espurna/mdns.ino b/code/espurna/mdns.ino
index 24f14c8f..c82f328a 100644
--- a/code/espurna/mdns.ino
+++ b/code/espurna/mdns.ino
@@ -118,6 +118,13 @@ String mdnsResolve(String name) {
return mdnsResolve((char *) name.c_str());
}
+void mdnsClientSetup() {
+
+ // Register loop
+ espurnaRegisterLoop(mdnsClientLoop);
+
+}
+
void mdnsClientLoop() {
_mdns_resolver.loop();
}
diff --git a/code/espurna/mqtt.ino b/code/espurna/mqtt.ino
index 7ffbaa0c..a69f2da0 100644
--- a/code/espurna/mqtt.ino
+++ b/code/espurna/mqtt.ino
@@ -729,6 +729,9 @@ void mqttSetup() {
_mqttInitCommands();
#endif
+ // Register loop
+ espurnaRegisterLoop(mqttLoop);
+
}
void mqttLoop() {
diff --git a/code/espurna/nofuss.ino b/code/espurna/nofuss.ino
index dd1db595..ddeba808 100644
--- a/code/espurna/nofuss.ino
+++ b/code/espurna/nofuss.ino
@@ -153,6 +153,9 @@ void nofussSetup() {
_nofussInitCommands();
#endif
+ // Register loop
+ espurnaRegisterLoop(nofussLoop);
+
}
void nofussLoop() {
diff --git a/code/espurna/ntp.ino b/code/espurna/ntp.ino
index 97d7d39c..4332b434 100644
--- a/code/espurna/ntp.ino
+++ b/code/espurna/ntp.ino
@@ -94,6 +94,9 @@ void ntpSetup() {
wsOnAfterParseRegister(_ntpConfigure);
#endif
+ // Register loop
+ espurnaRegisterLoop(ntpLoop);
+
}
void ntpLoop() {
diff --git a/code/espurna/ota.ino b/code/espurna/ota.ino
index d1aad3ad..61886ebe 100644
--- a/code/espurna/ota.ino
+++ b/code/espurna/ota.ino
@@ -61,6 +61,9 @@ void otaSetup() {
ArduinoOTA.begin();
+ // Register loop
+ espurnaRegisterLoop(otaLoop);
+
}
void otaLoop() {
diff --git a/code/espurna/relay.ino b/code/espurna/relay.ino
index 0a1c51bd..0a500b62 100644
--- a/code/espurna/relay.ino
+++ b/code/espurna/relay.ino
@@ -728,6 +728,8 @@ void relaySetup() {
_relayBoot();
relayLoop();
+ espurnaRegisterLoop(relayLoop);
+
#if WEB_SUPPORT
relaySetupAPI();
relaySetupWS();
diff --git a/code/espurna/rf.ino b/code/espurna/rf.ino
index 34597b4c..3ae60a70 100644
--- a/code/espurna/rf.ino
+++ b/code/espurna/rf.ino
@@ -101,6 +101,9 @@ void rfSetup() {
wsOnAfterParseRegister(_rfBuildCodes);
#endif
+ // Register loop
+ espurnaRegisterLoop(rfLoop);
+
}
#endif
diff --git a/code/espurna/rfbridge.ino b/code/espurna/rfbridge.ino
index c96e646d..f90fb14f 100644
--- a/code/espurna/rfbridge.ino
+++ b/code/espurna/rfbridge.ino
@@ -505,6 +505,9 @@ void rfbSetup() {
wsOnActionRegister(_rfbWebSocketOnAction);
#endif
+ // Register oop
+ espurnaRegisterLoop(rfbLoop);
+
}
void rfbLoop() {
diff --git a/code/espurna/scheduler.ino b/code/espurna/scheduler.ino
index 8ff8a17d..5f551ce0 100644
--- a/code/espurna/scheduler.ino
+++ b/code/espurna/scheduler.ino
@@ -116,6 +116,9 @@ void schSetup() {
wsOnAfterParseRegister(_schConfigure);
#endif
+ // Register loop
+ espurnaRegisterLoop(schLoop);
+
}
void schLoop() {
diff --git a/code/espurna/sensor.ino b/code/espurna/sensor.ino
index c3b2e7ea..fd617a2c 100644
--- a/code/espurna/sensor.ino
+++ b/code/espurna/sensor.ino
@@ -619,6 +619,9 @@ void sensorSetup() {
_sensorInitCommands();
#endif
+ // Register loop
+ espurnaRegisterLoop(sensorLoop);
+
}
void sensorLoop() {
diff --git a/code/espurna/settings.ino b/code/espurna/settings.ino
index a56e7650..51e44352 100644
--- a/code/espurna/settings.ino
+++ b/code/espurna/settings.ino
@@ -416,6 +416,9 @@ void settingsSetup() {
#endif
#endif
+ // Register loop
+ espurnaRegisterLoop(settingsLoop);
+
}
void settingsLoop() {
diff --git a/code/espurna/ssdp.ino b/code/espurna/ssdp.ino
index 87f7df86..80f2817e 100644
--- a/code/espurna/ssdp.ino
+++ b/code/espurna/ssdp.ino
@@ -31,6 +31,9 @@ void ssdpSetup() {
});
#endif
+ // Register loop
+ espurnaRegisterLoop(ssdpLoop);
+
}
void ssdpLoop() {
diff --git a/code/espurna/system.ino b/code/espurna/system.ino
new file mode 100644
index 00000000..8f21c75e
--- /dev/null
+++ b/code/espurna/system.ino
@@ -0,0 +1,116 @@
+/*
+
+SYSTEM MODULE
+
+Copyright (C) 2018 by Xose Pérez
+
+*/
+
+#include
+
+// -----------------------------------------------------------------------------
+
+unsigned long _loopDelay = 0;
+
+// -----------------------------------------------------------------------------
+
+#if SYSTEM_CHECK_ENABLED
+
+// 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 SYSTEM_CHECK_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 > SYSTEM_CHECK_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;
+}
+
+void systemCheckLoop() {
+ static bool checked = false;
+ if (!checked && (millis() > SYSTEM_CHECK_TIME)) {
+ // Check system as stable
+ systemCheck(true);
+ checked = true;
+ }
+}
+
+#endif
+
+// -----------------------------------------------------------------------------
+
+void systemLoop() {
+
+ // Check system stability
+ #if SYSTEM_CHECK_ENABLED
+ systemCheckLoop();
+ #endif
+
+ #if HEARTBEAT_ENABLED
+ // Heartbeat
+ static unsigned long last = 0;
+ if ((last == 0) || (millis() - last > HEARTBEAT_INTERVAL)) {
+ last = millis();
+ heartbeat();
+ }
+ #endif // HEARTBEAT_ENABLED
+
+ // Power saving delay
+ delay(_loopDelay);
+
+}
+
+void systemSetup() {
+
+ EEPROM.begin(EEPROM_SIZE);
+
+ #if DEBUG_SERIAL_SUPPORT
+ DEBUG_PORT.begin(SERIAL_BAUDRATE);
+ #if DEBUG_ESP_WIFI
+ DEBUG_PORT.setDebugOutput(true);
+ #endif
+ #elif defined(SERIAL_BAUDRATE)
+ Serial.begin(SERIAL_BAUDRATE);
+ #endif
+
+ #if SPIFFS_SUPPORT
+ SPIFFS.begin();
+ #endif
+
+ // Question system stability
+ #if SYSTEM_CHECK_ENABLED
+ systemCheck(false);
+ #endif
+
+ #if defined(ESPLIVE)
+ //The ESPLive has an ADC MUX which needs to be configured.
+ pinMode(16, OUTPUT);
+ digitalWrite(16, HIGH); //Defualt CT input (pin B, solder jumper B)
+ #endif
+
+ // Cache loop delay value to speed things (recommended max 250ms)
+ _loopDelay = atol(getSetting("loopDelay", LOOP_DELAY_TIME).c_str());
+
+ // Register Loop
+ espurnaRegisterLoop(systemLoop);
+
+}
diff --git a/code/espurna/thinkspeak.ino b/code/espurna/thinkspeak.ino
index 294ed76f..ca3c1aa8 100644
--- a/code/espurna/thinkspeak.ino
+++ b/code/espurna/thinkspeak.ino
@@ -242,15 +242,22 @@ bool tspkEnabled() {
}
void tspkSetup() {
+
_tspkConfigure();
+
#if WEB_SUPPORT
wsOnSendRegister(_tspkWebSocketOnSend);
wsOnAfterParseRegister(_tspkConfigure);
#endif
+
DEBUG_MSG_P(PSTR("[THINGSPEAK] Async %s, SSL %s\n"),
THINGSPEAK_USE_ASYNC ? "ENABLED" : "DISABLED",
THINGSPEAK_USE_SSL ? "ENABLED" : "DISABLED"
);
+
+ // Register loop
+ espurnaRegisterLoop(tspkLoop);
+
}
void tspkLoop() {
diff --git a/code/espurna/utils.ino b/code/espurna/utils.ino
index bcfb8137..99a1ca20 100644
--- a/code/espurna/utils.ino
+++ b/code/espurna/utils.ino
@@ -489,50 +489,6 @@ void deferredReset(unsigned long delay, unsigned char reason) {
// -----------------------------------------------------------------------------
-#if SYSTEM_CHECK_ENABLED
-
-// 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 SYSTEM_CHECK_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 > SYSTEM_CHECK_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;
-}
-
-void systemCheckLoop() {
- static bool checked = false;
- if (!checked && (millis() > SYSTEM_CHECK_TIME)) {
- // Check system as stable
- systemCheck(true);
- checked = true;
- }
-}
-
-#endif
-
-// -----------------------------------------------------------------------------
-
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 bd5773c2..4c0c0266 100644
--- a/code/espurna/wifi.ino
+++ b/code/espurna/wifi.ino
@@ -447,6 +447,9 @@ void wifiSetup() {
_wifiInitCommands();
#endif
+ // Register loop
+ espurnaRegisterLoop(wifiLoop);
+
}
void wifiLoop() {