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(),
|
||||
ui(),
|
||||
ui(onoffButtonInterruptCallback, setupButtonInterruptCallback),
|
||||
wifi(),
|
||||
mqtt(&wifi, mqttOnConnectCallback, mqttOnMessageCallback),
|
||||
temperatureSensor(
|
||||
|
@ -32,9 +32,6 @@ namespace Dough
|
|||
void App::setup()
|
||||
{
|
||||
ui.setup();
|
||||
ui.onoffButton.onInterrupt(::onoffButtonInterruptCallback);
|
||||
ui.setupButton.onInterrupt(::setupButtonInterruptCallback);
|
||||
|
||||
wifi.setup();
|
||||
mqtt.setup();
|
||||
temperatureSensor.setup();
|
||||
|
@ -63,60 +60,4 @@ namespace Dough
|
|||
humiditySensor.clearHistory();
|
||||
distanceSensor.clearHistory();
|
||||
}
|
||||
} // 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.
|
||||
}
|
||||
} // namespace Dough
|
|
@ -4,6 +4,7 @@
|
|||
#include <Arduino.h>
|
||||
#include "UI/UI.h"
|
||||
#include "App/Configuration.h"
|
||||
#include "App/callbacks.h"
|
||||
#include "Data/SensorController.h"
|
||||
#include "Sensors/TemperatureSensor.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
|
|
@ -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
|
||||
// and linked to the button to get the interrupts working. Pattern:
|
||||
//
|
||||
// // Construct the button instance.
|
||||
// Button myButton(MYBUTTON_PIN);
|
||||
//
|
||||
// // A function for handling interrupts.
|
||||
// void myButtonISR() {
|
||||
// myButton.handleButtonState();
|
||||
// }
|
||||
//
|
||||
// // Linking the function ot button interrupts.
|
||||
// myButton.onInterrupt(myButtonISR);
|
||||
Button::Button(int pin)
|
||||
// // Construct the button instance.
|
||||
// Button myButton(MYBUTTON_PIN, myButtonISR);
|
||||
Button::Button(int pin, ButtonISR isr)
|
||||
{
|
||||
_pin = pin;
|
||||
attachInterrupt(digitalPinToInterrupt(_pin), isr, CHANGE);
|
||||
}
|
||||
|
||||
void Button::setup()
|
||||
|
@ -29,30 +27,22 @@ namespace Dough
|
|||
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.
|
||||
// When specific handlers for long and/or short presses are
|
||||
// configured as well, those have precedence over this one.
|
||||
void Button::onPress(ButtonHandler handler)
|
||||
void Button::onPress(ButtonISR handler)
|
||||
{
|
||||
_pressHandler = handler;
|
||||
}
|
||||
|
||||
// Assign an event handler for long button presses.
|
||||
void Button::onLongPress(ButtonHandler handler)
|
||||
void Button::onLongPress(ButtonISR handler)
|
||||
{
|
||||
_longPressHandler = handler;
|
||||
}
|
||||
|
||||
// Assign an event handler for short button presses.
|
||||
void Button::onShortPress(ButtonHandler handler)
|
||||
void Button::onShortPress(ButtonISR handler)
|
||||
{
|
||||
_shortPressHandler = handler;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace Dough
|
|||
READY_FOR_NEXT_PRESS
|
||||
} ButtonState;
|
||||
|
||||
typedef void (*ButtonHandler)();
|
||||
typedef void (*ButtonISR)();
|
||||
|
||||
// This class provides a simple interface for handling button presses.
|
||||
// Only a few events are supported:
|
||||
|
@ -30,21 +30,20 @@ namespace Dough
|
|||
class Button
|
||||
{
|
||||
public:
|
||||
Button(int pin);
|
||||
Button(int pin, ButtonISR isr);
|
||||
void setup();
|
||||
void loop();
|
||||
void onInterrupt(ButtonHandler isr);
|
||||
void onPress(ButtonHandler handler);
|
||||
void onShortPress(ButtonHandler handler);
|
||||
void onLongPress(ButtonHandler handler);
|
||||
void onPress(ButtonISR handler);
|
||||
void onShortPress(ButtonISR handler);
|
||||
void onLongPress(ButtonISR handler);
|
||||
void clearEvents();
|
||||
void handleButtonState();
|
||||
|
||||
private:
|
||||
int _pin;
|
||||
ButtonHandler _pressHandler = nullptr;
|
||||
ButtonHandler _shortPressHandler = nullptr;
|
||||
ButtonHandler _longPressHandler = nullptr;
|
||||
ButtonISR _pressHandler = nullptr;
|
||||
ButtonISR _shortPressHandler = nullptr;
|
||||
ButtonISR _longPressHandler = nullptr;
|
||||
bool _debounceState = false;
|
||||
unsigned long _debounceTimer = 0;
|
||||
ButtonState _state = UP;
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
|
||||
namespace Dough
|
||||
{
|
||||
UI::UI() : onoffButton(ONOFF_BUTTON_PIN),
|
||||
setupButton(SETUP_BUTTON_PIN),
|
||||
_ledBuiltin(LED_BUILTIN),
|
||||
_led1(LED1_PIN),
|
||||
_led2(LED2_PIN),
|
||||
_led3(LED3_PIN) {}
|
||||
UI::UI(
|
||||
ButtonISR onoffButtonISR,
|
||||
ButtonISR setupButtonISR) : onoffButton(ONOFF_BUTTON_PIN, onoffButtonISR),
|
||||
setupButton(SETUP_BUTTON_PIN, setupButtonISR),
|
||||
_ledBuiltin(LED_BUILTIN),
|
||||
_led1(LED1_PIN),
|
||||
_led2(LED2_PIN),
|
||||
_led3(LED3_PIN) {}
|
||||
|
||||
void UI::setup()
|
||||
{
|
||||
|
@ -116,7 +118,7 @@ namespace Dough
|
|||
_led2.off();
|
||||
_led3.off();
|
||||
}
|
||||
|
||||
|
||||
void UI::notifyConnectingToMQTT()
|
||||
{
|
||||
_led1.blink()->fast();
|
||||
|
@ -163,16 +165,16 @@ namespace Dough
|
|||
{
|
||||
_led3.off();
|
||||
delay(50);
|
||||
_led3.on();
|
||||
_led3.on();
|
||||
}
|
||||
|
||||
void UI::notifyNetworkActivity()
|
||||
{
|
||||
_led1.off();
|
||||
delay(50);
|
||||
_led1.on();
|
||||
_led1.on();
|
||||
}
|
||||
|
||||
|
||||
// Flash all LEDs, one at a time in a synchroneous manner, making
|
||||
// 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.
|
||||
|
|
|
@ -14,10 +14,8 @@ namespace Dough
|
|||
class UI
|
||||
{
|
||||
public:
|
||||
UI();
|
||||
UI(ButtonISR onoffButtonISR, ButtonISR setupButtonISR);
|
||||
void setup();
|
||||
static void onoffButtonISR();
|
||||
static void setupButtonISR();
|
||||
Button onoffButton;
|
||||
Button setupButton;
|
||||
void processButtonEvents();
|
||||
|
|
Loading…
Reference in New Issue