Moved callbacks (which live in the top-level namespace) into a separate file, so I have a clear overview of all these.
This commit is contained in:
parent
578c0aa626
commit
7f5f60a6ac
|
@ -9,7 +9,7 @@ namespace Dough
|
||||||
}
|
}
|
||||||
|
|
||||||
App::App() : config(),
|
App::App() : config(),
|
||||||
ui(),
|
ui(onoffButtonInterruptCallback, setupButtonInterruptCallback),
|
||||||
wifi(),
|
wifi(),
|
||||||
mqtt(&wifi, mqttOnConnectCallback, mqttOnMessageCallback),
|
mqtt(&wifi, mqttOnConnectCallback, mqttOnMessageCallback),
|
||||||
temperatureSensor(
|
temperatureSensor(
|
||||||
|
@ -32,9 +32,6 @@ namespace Dough
|
||||||
void App::setup()
|
void App::setup()
|
||||||
{
|
{
|
||||||
ui.setup();
|
ui.setup();
|
||||||
ui.onoffButton.onInterrupt(::onoffButtonInterruptCallback);
|
|
||||||
ui.setupButton.onInterrupt(::setupButtonInterruptCallback);
|
|
||||||
|
|
||||||
wifi.setup();
|
wifi.setup();
|
||||||
mqtt.setup();
|
mqtt.setup();
|
||||||
temperatureSensor.setup();
|
temperatureSensor.setup();
|
||||||
|
@ -63,60 +60,4 @@ namespace Dough
|
||||||
humiditySensor.clearHistory();
|
humiditySensor.clearHistory();
|
||||||
distanceSensor.clearHistory();
|
distanceSensor.clearHistory();
|
||||||
}
|
}
|
||||||
} // namespace Dough
|
} // namespace Dough
|
||||||
|
|
||||||
Dough::Logger callbackLogger("CALLBACK");
|
|
||||||
|
|
||||||
void mqttOnConnectCallback(Dough::MQTT *mqtt)
|
|
||||||
{
|
|
||||||
callbackLogger.log("s", "MQTT connection establish, subscribing to topics");
|
|
||||||
mqtt->subscribe("container_height");
|
|
||||||
mqtt->subscribe("temperature_offset");
|
|
||||||
}
|
|
||||||
|
|
||||||
void mqttOnMessageCallback(String &topic, String &payload)
|
|
||||||
{
|
|
||||||
callbackLogger.log("ssss", "MQTT message received: ", topic.c_str(), " = ", payload.c_str());
|
|
||||||
|
|
||||||
if (topic.endsWith("/container_height"))
|
|
||||||
{
|
|
||||||
Dough::App::Instance()->config.setContainerHeight(payload.toInt());
|
|
||||||
}
|
|
||||||
else if (topic.endsWith("/temperature_offset"))
|
|
||||||
{
|
|
||||||
Dough::App::Instance()->config.setTemperatureOffset(payload.toInt());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
callbackLogger.log("ss", "ERROR - Unhandled MQTT message, topic = ", topic.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void onoffButtonInterruptCallback()
|
|
||||||
{
|
|
||||||
Dough::App::Instance()->ui.onoffButton.handleButtonState();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setupButtonInterruptCallback()
|
|
||||||
{
|
|
||||||
Dough::App::Instance()->ui.setupButton.handleButtonState();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sensorOnMeasureCallback()
|
|
||||||
{
|
|
||||||
Dough::App::Instance()->ui.notifySensorActivity();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sensorOnPublishCallback()
|
|
||||||
{
|
|
||||||
Dough::App::Instance()->ui.notifyNetworkActivity();
|
|
||||||
}
|
|
||||||
|
|
||||||
// This callback is called when the TC4 timer from the UI code hits an overflow
|
|
||||||
// interrupt. It is defined outside the Dough namespace, because TC4_Handler is
|
|
||||||
// a hard-coded root namespace function name.
|
|
||||||
void TC4_Handler()
|
|
||||||
{
|
|
||||||
Dough::App::Instance()->ui.updateLEDs();
|
|
||||||
REG_TC4_INTFLAG = TC_INTFLAG_OVF; // Clear the OVF interrupt flag.
|
|
||||||
}
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "UI/UI.h"
|
#include "UI/UI.h"
|
||||||
#include "App/Configuration.h"
|
#include "App/Configuration.h"
|
||||||
|
#include "App/callbacks.h"
|
||||||
#include "Data/SensorController.h"
|
#include "Data/SensorController.h"
|
||||||
#include "Sensors/TemperatureSensor.h"
|
#include "Sensors/TemperatureSensor.h"
|
||||||
#include "Sensors/HumiditySensor.h"
|
#include "Sensors/HumiditySensor.h"
|
||||||
|
@ -34,12 +35,4 @@ namespace Dough
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback functions that need to live in the global namespace.
|
|
||||||
void mqttOnConnectCallback(Dough::MQTT *mqtt);
|
|
||||||
void mqttOnMessageCallback(String &topic, String &payload);
|
|
||||||
void onoffButtonInterruptCallback();
|
|
||||||
void setupButtonInterruptCallback();
|
|
||||||
void sensorOnMeasureCallback();
|
|
||||||
void sensorOnPublishCallback();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -0,0 +1,57 @@
|
||||||
|
#include "App/callbacks.h"
|
||||||
|
|
||||||
|
Dough::Logger callbackLogger("CALLBACK");
|
||||||
|
|
||||||
|
void mqttOnConnectCallback(Dough::MQTT *mqtt)
|
||||||
|
{
|
||||||
|
callbackLogger.log("s", "MQTT connection establish, subscribing to topics");
|
||||||
|
mqtt->subscribe("container_height");
|
||||||
|
mqtt->subscribe("temperature_offset");
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqttOnMessageCallback(String &topic, String &payload)
|
||||||
|
{
|
||||||
|
callbackLogger.log("ssss", "MQTT message received: ", topic.c_str(), " = ", payload.c_str());
|
||||||
|
|
||||||
|
if (topic.endsWith("/container_height"))
|
||||||
|
{
|
||||||
|
Dough::App::Instance()->config.setContainerHeight(payload.toInt());
|
||||||
|
}
|
||||||
|
else if (topic.endsWith("/temperature_offset"))
|
||||||
|
{
|
||||||
|
Dough::App::Instance()->config.setTemperatureOffset(payload.toInt());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
callbackLogger.log("ss", "ERROR - Unhandled MQTT message, topic = ", topic.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onoffButtonInterruptCallback()
|
||||||
|
{
|
||||||
|
Dough::App::Instance()->ui.onoffButton.handleButtonState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupButtonInterruptCallback()
|
||||||
|
{
|
||||||
|
Dough::App::Instance()->ui.setupButton.handleButtonState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sensorOnMeasureCallback()
|
||||||
|
{
|
||||||
|
Dough::App::Instance()->ui.notifySensorActivity();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sensorOnPublishCallback()
|
||||||
|
{
|
||||||
|
Dough::App::Instance()->ui.notifyNetworkActivity();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This callback is called when the TC4 timer from the UI code hits an overflow
|
||||||
|
// interrupt. It is defined outside the Dough namespace, because TC4_Handler is
|
||||||
|
// a hard-coded root namespace function name.
|
||||||
|
void TC4_Handler()
|
||||||
|
{
|
||||||
|
Dough::App::Instance()->ui.updateLEDs();
|
||||||
|
REG_TC4_INTFLAG = TC_INTFLAG_OVF; // Clear the OVF interrupt flag.
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef DOUGH_APP_CALLBACKS_H
|
||||||
|
#define DOUGH_APP_CALLBACKS_H
|
||||||
|
|
||||||
|
#include "Network/MQTT.h"
|
||||||
|
#include "UI/Logger.h"
|
||||||
|
#include "App/App.h"
|
||||||
|
|
||||||
|
// This header file defines various callback functions that
|
||||||
|
// live in the global namespace. All callbacks are bundled here
|
||||||
|
// to have a clear overview of them.
|
||||||
|
|
||||||
|
// Callbacks from the Dough::MQTT module.
|
||||||
|
void mqttOnConnectCallback(Dough::MQTT *mqtt);
|
||||||
|
void mqttOnMessageCallback(String &topic, String &payload);
|
||||||
|
|
||||||
|
// Callbacks from the Dough::UI module.
|
||||||
|
void onoffButtonInterruptCallback();
|
||||||
|
void setupButtonInterruptCallback();
|
||||||
|
|
||||||
|
// Callbacks from the Dough::SensorController module.
|
||||||
|
void sensorOnMeasureCallback();
|
||||||
|
void sensorOnPublishCallback();
|
||||||
|
|
||||||
|
#endif
|
|
@ -9,19 +9,17 @@ namespace Dough
|
||||||
// working. An interrupt service routine (ISR) function must be created
|
// working. An interrupt service routine (ISR) function must be created
|
||||||
// and linked to the button to get the interrupts working. Pattern:
|
// and linked to the button to get the interrupts working. Pattern:
|
||||||
//
|
//
|
||||||
// // Construct the button instance.
|
|
||||||
// Button myButton(MYBUTTON_PIN);
|
|
||||||
//
|
|
||||||
// // A function for handling interrupts.
|
// // A function for handling interrupts.
|
||||||
// void myButtonISR() {
|
// void myButtonISR() {
|
||||||
// myButton.handleButtonState();
|
// myButton.handleButtonState();
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// // Linking the function ot button interrupts.
|
// // Construct the button instance.
|
||||||
// myButton.onInterrupt(myButtonISR);
|
// Button myButton(MYBUTTON_PIN, myButtonISR);
|
||||||
Button::Button(int pin)
|
Button::Button(int pin, ButtonISR isr)
|
||||||
{
|
{
|
||||||
_pin = pin;
|
_pin = pin;
|
||||||
|
attachInterrupt(digitalPinToInterrupt(_pin), isr, CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::setup()
|
void Button::setup()
|
||||||
|
@ -29,30 +27,22 @@ namespace Dough
|
||||||
pinMode(_pin, INPUT_PULLUP);
|
pinMode(_pin, INPUT_PULLUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign an interrupt service routine (ISR) for handling button
|
|
||||||
// interrupts. The provided isr should relay interrupts to the
|
|
||||||
// handleButtonState() method of this class (see constructor docs).
|
|
||||||
void Button::onInterrupt(ButtonHandler isr)
|
|
||||||
{
|
|
||||||
attachInterrupt(digitalPinToInterrupt(_pin), isr, CHANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign an event handler for short and long button presses.
|
// Assign an event handler for short and long button presses.
|
||||||
// When specific handlers for long and/or short presses are
|
// When specific handlers for long and/or short presses are
|
||||||
// configured as well, those have precedence over this one.
|
// configured as well, those have precedence over this one.
|
||||||
void Button::onPress(ButtonHandler handler)
|
void Button::onPress(ButtonISR handler)
|
||||||
{
|
{
|
||||||
_pressHandler = handler;
|
_pressHandler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign an event handler for long button presses.
|
// Assign an event handler for long button presses.
|
||||||
void Button::onLongPress(ButtonHandler handler)
|
void Button::onLongPress(ButtonISR handler)
|
||||||
{
|
{
|
||||||
_longPressHandler = handler;
|
_longPressHandler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign an event handler for short button presses.
|
// Assign an event handler for short button presses.
|
||||||
void Button::onShortPress(ButtonHandler handler)
|
void Button::onShortPress(ButtonISR handler)
|
||||||
{
|
{
|
||||||
_shortPressHandler = handler;
|
_shortPressHandler = handler;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace Dough
|
||||||
READY_FOR_NEXT_PRESS
|
READY_FOR_NEXT_PRESS
|
||||||
} ButtonState;
|
} ButtonState;
|
||||||
|
|
||||||
typedef void (*ButtonHandler)();
|
typedef void (*ButtonISR)();
|
||||||
|
|
||||||
// This class provides a simple interface for handling button presses.
|
// This class provides a simple interface for handling button presses.
|
||||||
// Only a few events are supported:
|
// Only a few events are supported:
|
||||||
|
@ -30,21 +30,20 @@ namespace Dough
|
||||||
class Button
|
class Button
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Button(int pin);
|
Button(int pin, ButtonISR isr);
|
||||||
void setup();
|
void setup();
|
||||||
void loop();
|
void loop();
|
||||||
void onInterrupt(ButtonHandler isr);
|
void onPress(ButtonISR handler);
|
||||||
void onPress(ButtonHandler handler);
|
void onShortPress(ButtonISR handler);
|
||||||
void onShortPress(ButtonHandler handler);
|
void onLongPress(ButtonISR handler);
|
||||||
void onLongPress(ButtonHandler handler);
|
|
||||||
void clearEvents();
|
void clearEvents();
|
||||||
void handleButtonState();
|
void handleButtonState();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _pin;
|
int _pin;
|
||||||
ButtonHandler _pressHandler = nullptr;
|
ButtonISR _pressHandler = nullptr;
|
||||||
ButtonHandler _shortPressHandler = nullptr;
|
ButtonISR _shortPressHandler = nullptr;
|
||||||
ButtonHandler _longPressHandler = nullptr;
|
ButtonISR _longPressHandler = nullptr;
|
||||||
bool _debounceState = false;
|
bool _debounceState = false;
|
||||||
unsigned long _debounceTimer = 0;
|
unsigned long _debounceTimer = 0;
|
||||||
ButtonState _state = UP;
|
ButtonState _state = UP;
|
||||||
|
|
|
@ -2,12 +2,14 @@
|
||||||
|
|
||||||
namespace Dough
|
namespace Dough
|
||||||
{
|
{
|
||||||
UI::UI() : onoffButton(ONOFF_BUTTON_PIN),
|
UI::UI(
|
||||||
setupButton(SETUP_BUTTON_PIN),
|
ButtonISR onoffButtonISR,
|
||||||
_ledBuiltin(LED_BUILTIN),
|
ButtonISR setupButtonISR) : onoffButton(ONOFF_BUTTON_PIN, onoffButtonISR),
|
||||||
_led1(LED1_PIN),
|
setupButton(SETUP_BUTTON_PIN, setupButtonISR),
|
||||||
_led2(LED2_PIN),
|
_ledBuiltin(LED_BUILTIN),
|
||||||
_led3(LED3_PIN) {}
|
_led1(LED1_PIN),
|
||||||
|
_led2(LED2_PIN),
|
||||||
|
_led3(LED3_PIN) {}
|
||||||
|
|
||||||
void UI::setup()
|
void UI::setup()
|
||||||
{
|
{
|
||||||
|
@ -116,7 +118,7 @@ namespace Dough
|
||||||
_led2.off();
|
_led2.off();
|
||||||
_led3.off();
|
_led3.off();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI::notifyConnectingToMQTT()
|
void UI::notifyConnectingToMQTT()
|
||||||
{
|
{
|
||||||
_led1.blink()->fast();
|
_led1.blink()->fast();
|
||||||
|
@ -163,16 +165,16 @@ namespace Dough
|
||||||
{
|
{
|
||||||
_led3.off();
|
_led3.off();
|
||||||
delay(50);
|
delay(50);
|
||||||
_led3.on();
|
_led3.on();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI::notifyNetworkActivity()
|
void UI::notifyNetworkActivity()
|
||||||
{
|
{
|
||||||
_led1.off();
|
_led1.off();
|
||||||
delay(50);
|
delay(50);
|
||||||
_led1.on();
|
_led1.on();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flash all LEDs, one at a time in a synchroneous manner, making
|
// Flash all LEDs, one at a time in a synchroneous manner, making
|
||||||
// this work when the UI timer interrupt is inactive. This is used
|
// this work when the UI timer interrupt is inactive. This is used
|
||||||
// as a "Hey, I'm awake!" signal from the device after booting up.
|
// as a "Hey, I'm awake!" signal from the device after booting up.
|
||||||
|
|
|
@ -14,10 +14,8 @@ namespace Dough
|
||||||
class UI
|
class UI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UI();
|
UI(ButtonISR onoffButtonISR, ButtonISR setupButtonISR);
|
||||||
void setup();
|
void setup();
|
||||||
static void onoffButtonISR();
|
|
||||||
static void setupButtonISR();
|
|
||||||
Button onoffButton;
|
Button onoffButton;
|
||||||
Button setupButton;
|
Button setupButton;
|
||||||
void processButtonEvents();
|
void processButtonEvents();
|
||||||
|
|
Loading…
Reference in New Issue