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:
Maurice Makaay 2020-07-15 16:03:16 +02:00
parent 578c0aa626
commit 7f5f60a6ac
8 changed files with 112 additions and 108 deletions

View File

@ -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();
@ -64,59 +61,3 @@ namespace Dough
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.
}

View File

@ -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

57
src/App/callbacks.cpp Normal file
View File

@ -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.
}

24
src/App/callbacks.h Normal file
View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -2,8 +2,10 @@
namespace Dough
{
UI::UI() : onoffButton(ONOFF_BUTTON_PIN),
setupButton(SETUP_BUTTON_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),

View File

@ -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();