From 19f754b577c037b7f97167187cef158f2ac3530b Mon Sep 17 00:00:00 2001 From: Maurice Makaay Date: Tue, 14 Jul 2020 15:28:20 +0200 Subject: [PATCH] Okay, got some things working again. At least the device doesn't crash anymore :-) The sensors need some work to give correct readings in the new setup. It looks like I'm initializing them twice or so. Fix will follow in the next commit. --- src/App/App.cpp | 22 ++++++++++-------- src/App/App.h | 5 +++-- src/App/Configuration.cpp | 2 +- src/Network/MQTT.cpp | 4 ++-- src/Network/MQTT.h | 2 +- src/Network/WiFi.cpp | 5 ++++- src/Sensors/DistanceSensor.cpp | 12 ---------- src/Sensors/HumiditySensor.cpp | 12 ---------- src/Sensors/TemperatureSensor.cpp | 8 ------- src/UI/Button.cpp | 2 +- src/UI/LED.cpp | 2 +- src/UI/Logger.cpp | 13 ++--------- src/UI/Logger.h | 34 ++++++++++++++++++++++++++++ src/UI/UI.cpp | 8 +++---- src/config.h | 2 +- src/main.cpp | 37 ++++++++++++++----------------- 16 files changed, 84 insertions(+), 86 deletions(-) diff --git a/src/App/App.cpp b/src/App/App.cpp index 56e8b3b..62d235b 100644 --- a/src/App/App.cpp +++ b/src/App/App.cpp @@ -10,7 +10,10 @@ namespace Dough App::App() : config(), wifi(), - mqtt(&wifi, mqttOnConnect, mqttOnMessage), + mqtt( + &wifi, + mqttOnConnectCallback, + mqttOnMessageCallback), temperatureSensor( &mqtt, "temperature", @@ -31,9 +34,8 @@ namespace Dough DistanceSensor::Instance(), DISTANCE_AVERAGE_STORAGE, DISTANCE_MEASURE_INTERVAL, - MINIMUM_PUBLISH_INTERVAL) - { - } + MINIMUM_PUBLISH_INTERVAL), + _logger("APP") {} void App::setup() { @@ -62,14 +64,16 @@ namespace Dough } } // namespace Dough -void mqttOnConnect(Dough::MQTT *mqtt) +Dough::Logger callbackLogger("CALLBACK"); + +void mqttOnConnectCallback(Dough::MQTT *mqtt) { - Serial.println("Subscribe to required incoming MQTT topics"); + callbackLogger.log("s", "MQTT connection establish, subscribing to topics"); mqtt->subscribe("container_height"); - mqtt->subscribe("temperature_offset"); + mqtt->subscribe("temperature_offset"); } -void mqttOnMessage(String &topic, String &payload) +void mqttOnMessageCallback(String &topic, String &payload) { - Serial.println("Handle message"); + callbackLogger.log("s", "MQTT message received"); } \ No newline at end of file diff --git a/src/App/App.h b/src/App/App.h index 68adef7..7597307 100644 --- a/src/App/App.h +++ b/src/App/App.h @@ -28,11 +28,12 @@ namespace Dough private: App(); + Logger _logger; }; } // Callback functions that need to live in the global namespace. -void mqttOnConnect(Dough::MQTT*); -void mqttOnMessage(String &topic, String &payload); +void mqttOnConnectCallback(Dough::MQTT* mqtt); +void mqttOnMessageCallback(String &topic, String &payload); #endif \ No newline at end of file diff --git a/src/App/Configuration.cpp b/src/App/Configuration.cpp index 5a97d12..7982459 100644 --- a/src/App/Configuration.cpp +++ b/src/App/Configuration.cpp @@ -36,7 +36,7 @@ namespace Dough // } // else // { - // App::Instance()->config._logger.log("sS", "ERROR - Unhandled MQTT message, key = ", key); + // App::Instance()->config._logger.log("ss", "ERROR - Unhandled MQTT message, key = ", key.c_str()); // } // } diff --git a/src/Network/MQTT.cpp b/src/Network/MQTT.cpp index a874224..b523cd4 100644 --- a/src/Network/MQTT.cpp +++ b/src/Network/MQTT.cpp @@ -3,11 +3,11 @@ namespace Dough { MQTT::MQTT( - WiFi *network, + WiFi *wifi, MQTTConnectHandler onConnect, MQTTMessageHandler onMessage) : _logger("MQTT") { - _wifi = network; + _wifi = wifi; _onConnect = onConnect; _onMessage = onMessage; } diff --git a/src/Network/MQTT.h b/src/Network/MQTT.h index a831792..3625c00 100644 --- a/src/Network/MQTT.h +++ b/src/Network/MQTT.h @@ -20,7 +20,7 @@ namespace Dough class MQTT { public: - MQTT(WiFi *network, MQTTConnectHandler onConnect, MQTTMessageHandler onMessage); + MQTT(WiFi *wifi, MQTTConnectHandler onConnect, MQTTMessageHandler onMessage); void setup(); bool isConnected(); bool connect(); diff --git a/src/Network/WiFi.cpp b/src/Network/WiFi.cpp index ae14b6d..13019db 100644 --- a/src/Network/WiFi.cpp +++ b/src/Network/WiFi.cpp @@ -58,7 +58,10 @@ namespace Dough // Check if the connection attempt was successful. if (status == WL_CONNECTED) { - _logger.log("sa", "IP-Address = ", ::WiFi.localIP()); + char buf[50]; // this will also fit IPv6 addresses + auto printer = StringPrinter(buf, 50); + printer.print(::WiFi.localIP()); + _logger.log("ss", "IP-Address = ", buf); _logger.log("sis", "Signal strength = ", ::WiFi.RSSI(), " dBm"); return true; } diff --git a/src/Sensors/DistanceSensor.cpp b/src/Sensors/DistanceSensor.cpp index 3f6b020..be2d732 100644 --- a/src/Sensors/DistanceSensor.cpp +++ b/src/Sensors/DistanceSensor.cpp @@ -2,10 +2,6 @@ namespace Dough { - // ---------------------------------------------------------------------- - // Constructor - // ---------------------------------------------------------------------- - DistanceSensor *DistanceSensor::Instance() { static DistanceSensor *_instance = new DistanceSensor(); @@ -17,10 +13,6 @@ namespace Dough _hcsr04 = new SensorHCSR04(HCSR04_TRIG_PIN, HCSR04_ECHO_PIN); } - // ---------------------------------------------------------------------- - // setup - // ---------------------------------------------------------------------- - void DistanceSensor::setup() { _hcsr04->setup(); @@ -36,10 +28,6 @@ namespace Dough _hcsr04->setHumidity(humidity); } - // ---------------------------------------------------------------------- - // loop - // ---------------------------------------------------------------------- - Measurement DistanceSensor::read() { int d = _hcsr04->readDistance(); diff --git a/src/Sensors/HumiditySensor.cpp b/src/Sensors/HumiditySensor.cpp index 89ac573..f64fb01 100644 --- a/src/Sensors/HumiditySensor.cpp +++ b/src/Sensors/HumiditySensor.cpp @@ -2,10 +2,6 @@ namespace Dough { - // ---------------------------------------------------------------------- - // Constructor - // ---------------------------------------------------------------------- - HumiditySensor *HumiditySensor::Instance() { static HumiditySensor *_instance = new HumiditySensor(); @@ -14,19 +10,11 @@ namespace Dough HumiditySensor::HumiditySensor() : _logger("HUMIDITY") {} - // ---------------------------------------------------------------------- - // setup - // ---------------------------------------------------------------------- - void HumiditySensor::setup() { SensorDHT11::Instance()->begin(); } - // ---------------------------------------------------------------------- - // loop - // ---------------------------------------------------------------------- - Measurement HumiditySensor::read() { float t = SensorDHT11::Instance()->readHumidity(); diff --git a/src/Sensors/TemperatureSensor.cpp b/src/Sensors/TemperatureSensor.cpp index 7cdeb83..19704c1 100644 --- a/src/Sensors/TemperatureSensor.cpp +++ b/src/Sensors/TemperatureSensor.cpp @@ -2,10 +2,6 @@ namespace Dough { - // ---------------------------------------------------------------------- - // Constructor - // ---------------------------------------------------------------------- - TemperatureSensor *TemperatureSensor::Instance() { static TemperatureSensor *_instance = new TemperatureSensor(); @@ -14,10 +10,6 @@ namespace Dough TemperatureSensor::TemperatureSensor() : _logger("TEMPERATURE") {} - // ---------------------------------------------------------------------- - // setup - // ---------------------------------------------------------------------- - void TemperatureSensor::setup() { SensorDHT11::Instance()->begin(); diff --git a/src/UI/Button.cpp b/src/UI/Button.cpp index ab2d2ff..d10a175 100644 --- a/src/UI/Button.cpp +++ b/src/UI/Button.cpp @@ -144,4 +144,4 @@ namespace Dough _state = UP_AFTER_LONG; } } -} \ No newline at end of file +} // namespace Dough \ No newline at end of file diff --git a/src/UI/LED.cpp b/src/UI/LED.cpp index 555448a..b1ec9da 100644 --- a/src/UI/LED.cpp +++ b/src/UI/LED.cpp @@ -173,4 +173,4 @@ namespace Dough { return _pinState == LOW; } -} \ No newline at end of file +} // namespace Dough \ No newline at end of file diff --git a/src/UI/Logger.cpp b/src/UI/Logger.cpp index 4b824a1..66f9968 100644 --- a/src/UI/Logger.cpp +++ b/src/UI/Logger.cpp @@ -55,26 +55,17 @@ namespace Dough float f = va_arg(args, double); Serial.print(f); } - else if (*fmt == 'a') - { - IPAddress a = va_arg(args, IPAddress); - Serial.print(a); - } else if (*fmt == 's') { const char *s = va_arg(args, const char *); Serial.print(s); } - else if (*fmt == 'S') - { - String S = va_arg(args, String); - Serial.print(S); - } else { Serial.print(""); + Serial.println("'>"); + return; } fmt++; } diff --git a/src/UI/Logger.h b/src/UI/Logger.h index 94d8367..99d0e23 100644 --- a/src/UI/Logger.h +++ b/src/UI/Logger.h @@ -26,6 +26,40 @@ namespace Dough const char *_section; bool _suspended = false; }; + + // This class allows printing to a char*, so we can leverage standard + // Printable support for classes. It's up to the caller to provide a + // buffer that is large enough to hold the results. When the printed + // output is larger than the provided buffer, the overflow is silently + // ignored. + class StringPrinter : public Print + { + public: + StringPrinter(char *buffer, int buflen) : _buf(buffer), _pos(0), _len(buflen) + { + if (_len > 0) + { + _buf[0] = '\0'; + } + } + + virtual size_t write(uint8_t c) + { + // Silently ignore buffer overflows. + if ((_pos + 1) < _len) + { + _buf[_pos] = c; + _pos++; + _buf[_pos] = '\0'; + } + return 1; + } + + private: + char *_buf; + size_t _pos; + size_t _len; + }; } #endif \ No newline at end of file diff --git a/src/UI/UI.cpp b/src/UI/UI.cpp index fecd904..c75fe1b 100644 --- a/src/UI/UI.cpp +++ b/src/UI/UI.cpp @@ -47,7 +47,7 @@ namespace Dough // This allows for example to have a flashing LED, during the // wifi connection setup. _setupTimerInterrupt(); - + // Notify the user that we're on a roll! _flash_all_leds(); @@ -95,7 +95,8 @@ namespace Dough TC_CTRLA_ENABLE; // Enable TC4 REG_TC4_INTENSET = TC_INTENSET_OVF; // Enable TC4 overflow (OVF) interrupts REG_TC4_COUNT8_CC0 = 1; // Set the CC0 as the TOP value for MFRQ (1 => 50ms per pulse) - while (TC4->COUNT8.STATUS.bit.SYNCBUSY); // Wait for synchronization + while (TC4->COUNT8.STATUS.bit.SYNCBUSY) + ; // Wait for synchronization } // ---------------------------------------------------------------------- @@ -160,7 +161,7 @@ namespace Dough delay(100); led3.off(); } -} +} // namespace Dough // This callback is called when the TC4 timer hits an overflow interrupt. // Defined outside the Dough namespace, because TC4_Handler is a hard-coded @@ -170,4 +171,3 @@ void TC4_Handler() Dough::UI::Instance()->updatedLEDs(); REG_TC4_INTFLAG = TC_INTFLAG_OVF; // Clear the OVF interrupt flag. } - diff --git a/src/config.h b/src/config.h index 4c01f6b..9a6f6db 100644 --- a/src/config.h +++ b/src/config.h @@ -6,7 +6,7 @@ // serial messages to appear in the serial monitor. // Without this, some of the initial serial messages might // be missing from the output. -#undef LOG_WAIT_SERIAL +//#define LOG_WAIT_SERIAL // The digital pins to which the push buttons are connected. #define ONOFF_BUTTON_PIN 2 diff --git a/src/main.cpp b/src/main.cpp index f104861..e7d5113 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,14 +1,10 @@ #include "main.h" -// TODO: move code to Dough namespace -// TODO: move config to a separate class -// TODO: see if I can give each sensor its own built-in loop schedule for sampling, the DoughData class might be overkill in the latest setup. // TOOD: implement the calibration logic // TODO: see what more stuff can be moved to the UI code. Maybe state to UI state translation ought to be there as well -// TODO: make significantChange part of sensor class? DoughBoyState state = CONFIGURING; -auto logger = Dough::Logger("MAIN"); +Dough::Logger logger("MAIN"); void setup() { @@ -25,7 +21,6 @@ void setup() void loop() { auto app = Dough::App::Instance(); - auto mqtt = app->mqtt; auto ui = Dough::UI::Instance(); ui->processButtonEvents(); @@ -34,12 +29,15 @@ void loop() { return; } - - mqtt.procesIncomingsMessages(); - - if (state == CONFIGURING && app->config.isOk()) + + app->mqtt.procesIncomingsMessages(); + + if (state == CONFIGURING) { - setStateToMeasuring(); + if (app->config.isOk()) + { + setStateToMeasuring(); + } } else if (state == MEASURING && !app->config.isOk()) { @@ -69,10 +67,8 @@ bool setupNetworkConnection() auto app = Dough::App::Instance(); auto ui = Dough::UI::Instance(); - auto network = app->wifi; - auto mqtt = app->mqtt; - if (!network.isConnected()) + if (!app->wifi.isConnected()) { if (connectionState == CONNECTED) { @@ -86,9 +82,9 @@ bool setupNetworkConnection() ui->led1.blink()->slow(); ui->led2.off(); ui->led3.off(); - network.connect(); + app->wifi.connect(); } - if (network.isConnected() && !mqtt.isConnected()) + if (app->wifi.isConnected() && !app->mqtt.isConnected()) { if (connectionState == CONNECTED) { @@ -99,12 +95,13 @@ bool setupNetworkConnection() logger.log("s", "Connecting to the MQTT broker ..."); } connectionState = CONNECTING_MQTT; - ui->led1.on(); - ui->led2.blink()->slow(); + ui->led1.blink()->fast(); + ui->led2.off(); ui->led3.off(); - mqtt.connect(); + app->mqtt.connect(); + delay(1000); // purely costmetic, to make the faster LED blinking noticable } - if (network.isConnected() && mqtt.isConnected()) + if (app->wifi.isConnected() && app->mqtt.isConnected()) { if (connectionState != CONNECTED) {