change callbacks to vector

This commit is contained in:
Siwat Sirichai 2023-12-30 00:49:09 +07:00
parent 71475ef2f1
commit 011710fe82
19 changed files with 207 additions and 109 deletions

View File

@ -19,9 +19,9 @@ void AnalogCard::setDACState(uint8_t pin, bool state)
{ {
this->dac_state[pin] = state; this->dac_state[pin] = state;
this->sendDataToDAC(pin, this->dac_value[pin]*state); this->sendDataToDAC(pin, this->dac_value[pin]*state);
if (this->dac_change_callback != NULL) for (int i = 0; i < this->dac_change_callbacks.size(); i++)
{ {
this->dac_change_callback(pin, state, this->dac_value[pin]); this->dac_change_callbacks[i](pin, state, this->dac_value[pin]);
} }
} }
@ -29,9 +29,9 @@ void AnalogCard::setDACValue(uint8_t pin, uint16_t value)
{ {
this->dac_value[pin] = value; this->dac_value[pin] = value;
this->sendDataToDAC(pin, value*this->dac_state[pin]); this->sendDataToDAC(pin, value*this->dac_state[pin]);
if (this->dac_change_callback != NULL) for (int i = 0; i < this->dac_change_callbacks.size(); i++)
{ {
this->dac_change_callback(pin, this->dac_state[pin], value); this->dac_change_callbacks[i](pin, this->dac_state[pin], value);
} }
} }
@ -121,10 +121,18 @@ uint8_t AnalogCard::getType()
void AnalogCard::registerDACChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback) void AnalogCard::registerDACChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback)
{ {
this->dac_change_callback = callback; this->dac_change_callbacks.push_back(callback);
} }
void AnalogCard::deregisterDACChangeCallback() // void AnalogCard::deregisterDACChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback)
{ // {
this->dac_change_callback = NULL; // for (int i = 0; i < this->dac_change_callbacks.size(); i++)
} // {
// if (this->dac_change_callbacks[i].target<void(uint8_t, bool, uint16_t)>() == callback.target<void(uint8_t, bool, uint16_t)>())
// {
// this->dac_change_callbacks.erase(this->dac_change_callbacks.begin() + i);
// break;
// }
// }
// }

View File

@ -2,6 +2,7 @@
#include <ExpansionCard.hpp> #include <ExpansionCard.hpp>
#include <Adafruit_ADS1X15.h> #include <Adafruit_ADS1X15.h>
#include <MCP4725.h> #include <MCP4725.h>
#include <vector>
#define CARD_TYPE_ANALOG 0x02 #define CARD_TYPE_ANALOG 0x02
@ -25,10 +26,10 @@ class AnalogCard : public ExpansionCard {
void setDACState(uint8_t pin, bool state); void setDACState(uint8_t pin, bool state);
void setDACValue(uint8_t pin, uint16_t value); void setDACValue(uint8_t pin, uint16_t value);
void registerDACChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback); void registerDACChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback);
void deregisterDACChangeCallback(); //void deregisterDACChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback);
uint8_t getType(); uint8_t getType();
private: private:
std::function<void(uint8_t, bool, uint16_t)> dac_change_callback; std::vector<std::function<void(uint8_t, bool, uint16_t)>> dac_change_callbacks;
bool dac_state[4]; bool dac_state[4];
uint16_t dac_value[4]; uint16_t dac_value[4];
MCP4725 dac0; MCP4725 dac0;

View File

@ -48,6 +48,10 @@ void AnalogIoT::publishADC(uint8_t pin) {
this->publishRelative(topic, payload); this->publishRelative(topic, payload);
delete[] topic; delete[] topic;
delete[] payload; delete[] payload;
// Call all callbacks
for (int i = 0; i < this->adc_conversion_callbacks.size(); i++) {
this->adc_conversion_callbacks[i](pin, value);
}
} }
} }
void AnalogIoT::setADCsPublishInterval(uint32_t interval) { void AnalogIoT::setADCsPublishInterval(uint32_t interval) {
@ -60,18 +64,17 @@ void AnalogIoT::setADCsPublishEnabled(bool enabled) {
adc_publish_enabled[i] = enabled; adc_publish_enabled[i] = enabled;
} }
} }
void AnalogIoT::registerDACChangeCallback(std::function<void(uint8_t, uint16_t)> callback) {
dac_change_callback = callback;
}
void AnalogIoT::deregisterDACChangeCallback() {
dac_change_callback = NULL;
}
void AnalogIoT::registerADCConversionCallback(std::function<void(uint8_t, uint16_t)> callback) { void AnalogIoT::registerADCConversionCallback(std::function<void(uint8_t, uint16_t)> callback) {
adc_conversion_callback = callback; this->adc_conversion_callbacks.push_back(callback);
}
void AnalogIoT::deregisterADCConversionCallback() {
adc_conversion_callback = NULL;
} }
// void AnalogIoT::deregisterADCConversionCallback(std::function<void(uint8_t, uint16_t)> callback) {
// for (int i = 0; i < this->adc_conversion_callbacks.size(); i++) {
// if (this->adc_conversion_callbacks[i].target<void(uint8_t, uint16_t)>() == callback.target<void(uint8_t, uint16_t)>()) {
// this->adc_conversion_callbacks.erase(this->adc_conversion_callbacks.begin() + i);
// break;
// }
// }
// }
void AnalogIoT::setADCConversionInterval(uint8_t pin, uint16_t interval) { void AnalogIoT::setADCConversionInterval(uint8_t pin, uint16_t interval) {
adc_conversion_interval[pin] = interval; adc_conversion_interval[pin] = interval;
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <IoTComponent.hpp> #include <IoTComponent.hpp>
#include <AnalogCard.hpp> #include <AnalogCard.hpp>
#include <vector>
#define DAC_SET_STATE_TOPIC "/set/state" #define DAC_SET_STATE_TOPIC "/set/state"
#define DAC_SET_VALUE_TOPIC "/set/value" #define DAC_SET_VALUE_TOPIC "/set/value"
@ -24,10 +25,8 @@ class AnalogIoT : public IoTComponent {
void publishDACValue(uint8_t pin); void publishDACValue(uint8_t pin);
void setADCsPublishInterval(uint32_t interval); void setADCsPublishInterval(uint32_t interval);
void setADCsPublishEnabled(bool enabled); void setADCsPublishEnabled(bool enabled);
void registerDACChangeCallback(std::function<void(uint8_t, uint16_t)> callback);
void deregisterDACChangeCallback();
void registerADCConversionCallback(std::function<void(uint8_t, uint16_t)> callback); void registerADCConversionCallback(std::function<void(uint8_t, uint16_t)> callback);
void deregisterADCConversionCallback(); // void deregisterADCConversionCallback(std::function<void(uint8_t, uint16_t)> callback);
void setADCConversionInterval(uint8_t pin, uint16_t interval); void setADCConversionInterval(uint8_t pin, uint16_t interval);
void setADCConversionEnabled(uint8_t pin, bool enabled); void setADCConversionEnabled(uint8_t pin, bool enabled);
bool processADCSetConversionIntervalMessage(char *topic, char *payload, uint8_t topic_length); bool processADCSetConversionIntervalMessage(char *topic, char *payload, uint8_t topic_length);
@ -51,6 +50,5 @@ class AnalogIoT : public IoTComponent {
bool adc_publish_enabled[8]; bool adc_publish_enabled[8];
uint16_t adc_conversion_interval[8]; uint16_t adc_conversion_interval[8];
uint32_t last_adc_conversion[8]; uint32_t last_adc_conversion[8];
std::function<void(uint8_t, uint16_t)> dac_change_callback; std::vector<std::function<void(uint8_t, uint16_t)>> adc_conversion_callbacks;
std::function<void(uint8_t, uint16_t)> adc_conversion_callback;
}; };

View File

@ -96,8 +96,8 @@ void DigitalInputCard::handlePinChange(int pin, uint8_t &currentBuffer, uint8_t
{ {
lastDebounceTime[pin] = millis(); lastDebounceTime[pin] = millis();
previousBuffer ^= (-((currentBuffer >> (7 - pin)) & 1) ^ previousBuffer) & (1UL << (7 - pin)); previousBuffer ^= (-((currentBuffer >> (7 - pin)) & 1) ^ previousBuffer) & (1UL << (7 - pin));
if (callback != NULL) for (int i = 0; i < callbacks.size(); i++)
callback(virtualPin, ((currentBuffer >> (7 - pin)) & 1)); callbacks[i](virtualPin, ((currentBuffer >> (7 - pin)) & 1));
} }
} }
// Handle Bank B // Handle Bank B
@ -107,12 +107,13 @@ void DigitalInputCard::handlePinChange(int pin, uint8_t &currentBuffer, uint8_t
{ {
lastDebounceTime[pin] = millis(); lastDebounceTime[pin] = millis();
previousBuffer ^= (-((currentBuffer >> (15 - pin)) & 1) ^ previousBuffer) & (1UL << (15 - pin)); previousBuffer ^= (-((currentBuffer >> (15 - pin)) & 1) ^ previousBuffer) & (1UL << (15 - pin));
if (callback != NULL) for (int i = 0; i < callbacks.size(); i++)
callback(virtualPin, ((currentBuffer >> (15 - pin)) & 1)); callbacks[i](virtualPin, ((currentBuffer >> (15 - pin)) & 1));
} }
} }
} }
// Preform a loop to refresh the input buffers // Preform a loop to refresh the input buffers
void DigitalInputCard::loop() void DigitalInputCard::loop()
{ {
@ -158,7 +159,7 @@ uint8_t DigitalInputCard::getInputBufferB()
// Register a callback function to be called when a pin changes // Register a callback function to be called when a pin changes
void DigitalInputCard::registerCallback(std::function<void(uint8_t, bool)> callback) void DigitalInputCard::registerCallback(std::function<void(uint8_t, bool)> callback)
{ {
this->callback = callback; callbacks.push_back(callback);
} }
// Refresh the input buffer for bank A // Refresh the input buffer for bank A
@ -178,10 +179,17 @@ void DigitalInputCard::setDebounceTime(uint8_t pin, uint32_t debounceTime)
this->debounceTime[pin] = debounceTime; this->debounceTime[pin] = debounceTime;
} }
void DigitalInputCard::unregisterCallback() // void DigitalInputCard::unregisterCallback(std::function<void(uint8_t, bool)> callback)
{ // {
this->callback = NULL; // for (int i = 0; i < callbacks.size(); i++)
} // {
// if (callbacks[i].target<void(uint8_t, bool)>() == callback.target<void(uint8_t, bool)>())
// {
// callbacks.erase(callbacks.begin() + i);
// break;
// }
// }
// }
void DigitalInputCard::loadPinMap(uint8_t pinMap[16]) void DigitalInputCard::loadPinMap(uint8_t pinMap[16])
{ {

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <ExpansionCard.hpp> #include <ExpansionCard.hpp>
#include <PCF8574.h> #include <PCF8574.h>
#include <vector>
#define CARD_TYPE_DIGITAL_INPUT 0x01 #define CARD_TYPE_DIGITAL_INPUT 0x01
@ -27,7 +28,7 @@ class DigitalInputCard : public ExpansionCard {
// Register a callback function to be called when a pin changes // Register a callback function to be called when a pin changes
void registerCallback(std::function<void(uint8_t, bool)> callback); void registerCallback(std::function<void(uint8_t, bool)> callback);
// Unregister the callback function // Unregister the callback function
void unregisterCallback(); //void unregisterCallback(std::function<void(uint8_t, bool)> callback);
// Load a new pin map // Load a new pin map
void loadPinMap(uint8_t pinMap[16]); void loadPinMap(uint8_t pinMap[16]);
// Get type of card // Get type of card
@ -47,7 +48,7 @@ class DigitalInputCard : public ExpansionCard {
uint8_t pinMap[16]; uint8_t pinMap[16];
// A map of the virtual pin to the physical pin // A map of the virtual pin to the physical pin
uint8_t virtualPinMap[16]; uint8_t virtualPinMap[16];
std::function<void(uint8_t, bool)> callback; std::vector<std::function<void(uint8_t, bool)>> callbacks;
void refreshInputBankA(); void refreshInputBankA();
void refreshInputBankB(); void refreshInputBankB();
void handlePinChange(int pin, uint8_t& currentBuffer, uint8_t& previousBuffer); void handlePinChange(int pin, uint8_t& currentBuffer, uint8_t& previousBuffer);

View File

@ -46,13 +46,6 @@ void DigitalInputIoT::handleValueChange(uint8_t pin, uint8_t value) {
if (this->digital_inputs_publish_enabled) { if (this->digital_inputs_publish_enabled) {
this->publishDigitalInput(pin); this->publishDigitalInput(pin);
} }
if (this->change_callback != NULL) {
this->change_callback(pin, value);
}
}
void DigitalInputIoT::registerChangeCallback(std::function<void(uint8_t, uint8_t)> callback) {
this->change_callback = callback;
} }
void DigitalInputIoT::publishReport() { void DigitalInputIoT::publishReport() {

View File

@ -14,12 +14,10 @@ class DigitalInputIoT : public IoTComponent {
void publishDigitalInput(uint8_t pin); void publishDigitalInput(uint8_t pin);
void setDigitalInputsPublishEnabled(bool enabled); void setDigitalInputsPublishEnabled(bool enabled);
void handleValueChange(uint8_t pin, uint8_t value); void handleValueChange(uint8_t pin, uint8_t value);
void registerChangeCallback(std::function<void(uint8_t, uint8_t)> callback);
void publishReport(); void publishReport();
void subscribe(); void subscribe();
uint8_t getType(); uint8_t getType();
private: private:
std::function<void(uint8_t, uint8_t)> change_callback;
bool digital_inputs_publish_enabled = false; bool digital_inputs_publish_enabled = false;
DigitalInputCard *card; DigitalInputCard *card;
}; };

View File

@ -36,8 +36,8 @@ void DigitalOutputCard::digitalWrite(uint8_t pin, bool state) {
this->saveStateToFRAM(); this->saveStateToFRAM();
this->savePinValueToFRAM(pin); this->savePinValueToFRAM(pin);
} }
if(change_callback != NULL) { for (int i = 0; i < change_callbacks.size(); i++) {
change_callback(pin, state, state ? 4095 : 0); change_callbacks[i](pin, state, state ? 4095 : 0);
} }
} }
// Set the output to the specified pwm value // Set the output to the specified pwm value
@ -52,8 +52,8 @@ void DigitalOutputCard::analogWrite(uint8_t pin, uint16_t value) {
} }
this->state_buffer[pin] = value > 0; this->state_buffer[pin] = value > 0;
this->value_buffer[pin] = value; this->value_buffer[pin] = value;
if(change_callback != NULL) { for (int i = 0; i < change_callbacks.size(); i++) {
change_callback(pin, value > 0, value); change_callbacks[i](pin, value > 0, value);
} }
} }
@ -82,8 +82,8 @@ void DigitalOutputCard::setState(uint8_t pin, bool state) {
if(this->framAutoSave) { if(this->framAutoSave) {
this->saveStateToFRAM(); this->saveStateToFRAM();
} }
if (change_callback != NULL) { for(int i = 0; i < change_callbacks.size(); i++) {
change_callback(pin, state, value_buffer[pin]); change_callbacks[i](pin, state, value_buffer[pin]);
} }
} }
@ -95,18 +95,23 @@ void DigitalOutputCard::setValue(uint8_t pin, uint16_t value) {
if (this->framAutoSave) { if (this->framAutoSave) {
this->savePinValueToFRAM(pin); this->savePinValueToFRAM(pin);
} }
if (change_callback != NULL) { for (int i = 0; i < change_callbacks.size(); i++) {
change_callback(pin, state_buffer[pin], value); change_callbacks[i](pin, state_buffer[pin], value);
} }
} }
void DigitalOutputCard::registerChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback) { void DigitalOutputCard::registerChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback) {
this->change_callback = callback; this->change_callbacks.push_back(callback);
} }
void DigitalOutputCard::deregisterChangeCallback() { // void DigitalOutputCard::deregisterChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback) {
this->change_callback = NULL; // for(int i = 0; i < change_callbacks.size(); i++) {
} // if(change_callbacks[i].target<void(uint8_t, bool, uint16_t)>() == callback.target<void(uint8_t, bool, uint16_t)>()) {
// change_callbacks.erase(change_callbacks.begin()+i);
// break;
// }
// }
// }
void DigitalOutputCard::loadPinMap(uint8_t pinMap[16]) { void DigitalOutputCard::loadPinMap(uint8_t pinMap[16]) {
for(int i = 0; i < 16; i++) { for(int i = 0; i < 16; i++) {

View File

@ -2,6 +2,7 @@
#include <ExpansionCard.hpp> #include <ExpansionCard.hpp>
#include <Adafruit_PWMServoDriver.h> #include <Adafruit_PWMServoDriver.h>
#include <FRAM.h> #include <FRAM.h>
#include <vector>
// Protocol for digital output card // Protocol for digital output card
// Note that pin is always 2 characters long and padded with 0 if necessary // Note that pin is always 2 characters long and padded with 0 if necessary
@ -49,7 +50,7 @@ public:
// Register a callback function that will be called when the state of a pin changes // Register a callback function that will be called when the state of a pin changes
void registerChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback); void registerChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback);
// Deregister the callback function // Deregister the callback function
void deregisterChangeCallback(); // void deregisterChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback);
// Load a new pin map // Load a new pin map
void loadPinMap(uint8_t pinMap[16]); void loadPinMap(uint8_t pinMap[16]);
// Bind the fram object to the card // Bind the fram object to the card
@ -89,7 +90,7 @@ private:
// The pwm value of the card // The pwm value of the card
uint16_t value_buffer[16]; uint16_t value_buffer[16];
// The callback function // The callback function
std::function<void(uint8_t, bool, uint16_t)> change_callback; std::vector<std::function<void(uint8_t, bool, uint16_t)>> change_callbacks;
// Physical pin to virtual pin map // Physical pin to virtual pin map
uint8_t pinMap[16]; uint8_t pinMap[16];
// Return 16 bit value representing all 16 channels // Return 16 bit value representing all 16 channels

View File

@ -109,7 +109,7 @@ void ESPMegaDisplay::jumpToPage(int page) {
* @param component The component name. * @param component The component name.
* @param value The value to set. * @param value The value to set.
*/ */
void ESPMegaDisplay::setNumber(char* component, int value) { void ESPMegaDisplay::setNumber(const char* component, int value) {
this->displayAdapter->print(component); this->displayAdapter->print(component);
this->displayAdapter->print("="); this->displayAdapter->print("=");
this->displayAdapter->print(value); this->displayAdapter->print(value);
@ -121,7 +121,7 @@ void ESPMegaDisplay::setNumber(char* component, int value) {
* @param component The component name. * @param component The component name.
* @param value The value to set. * @param value The value to set.
*/ */
void ESPMegaDisplay::setString(char* component, char* value) { void ESPMegaDisplay::setString(const char* component, const char* value) {
this->displayAdapter->print(component); this->displayAdapter->print(component);
this->displayAdapter->print("=\""); this->displayAdapter->print("=\"");
this->displayAdapter->print(value); this->displayAdapter->print(value);
@ -134,7 +134,7 @@ void ESPMegaDisplay::setString(char* component, char* value) {
* @param component The component name. * @param component The component name.
* @return The value of the number component. * @return The value of the number component.
*/ */
uint32_t ESPMegaDisplay::getNumber(char* component) { uint32_t ESPMegaDisplay::getNumber(const char* component) {
uint32_t start = millis(); uint32_t start = millis();
// Send the get command // Send the get command
this->displayAdapter->print("get "); this->displayAdapter->print("get ");
@ -162,7 +162,7 @@ uint32_t ESPMegaDisplay::getNumber(char* component) {
* @return The value of the string component. * @return The value of the string component.
* @note The returned char array must be freed after use. * @note The returned char array must be freed after use.
*/ */
char* ESPMegaDisplay::getString(char* component) { char* ESPMegaDisplay::getString(const char* component) {
uint32_t start = millis(); uint32_t start = millis();
// Send the get command // Send the get command
this->displayAdapter->print("get "); this->displayAdapter->print("get ");
@ -186,7 +186,7 @@ char* ESPMegaDisplay::getString(char* component) {
return value; return value;
} }
bool ESPMegaDisplay::getStringToBuffer(char* component, char* buffer, uint8_t buffer_size) { bool ESPMegaDisplay::getStringToBuffer(const char* component, char* buffer, uint8_t buffer_size) {
uint32_t start = millis(); uint32_t start = millis();
// Send the get command // Send the get command
this->displayAdapter->print("get "); this->displayAdapter->print("get ");

View File

@ -13,11 +13,11 @@ class ESPMegaDisplay
void setBrightness(int value); void setBrightness(int value);
void setVolume(int value); void setVolume(int value);
void jumpToPage(int page); void jumpToPage(int page);
void setString(char* component, char* value); void setString(const char* component, const char* value);
void setNumber(char* component, int value); void setNumber(const char* component, int value);
char* getString(char* component); char* getString(const char* component);
bool getStringToBuffer(char* component, char* buffer, uint8_t buffer_size); bool getStringToBuffer(const char* component, char* buffer, uint8_t buffer_size);
uint32_t getNumber(char* component); uint32_t getNumber(const char* component);
void handlePwmStateChange(uint8_t pin, uint16_t value); void handlePwmStateChange(uint8_t pin, uint16_t value);
void handleInputStateChange(uint8_t pin, bool state); void handleInputStateChange(uint8_t pin, bool state);
void registerPushCallback(std::function<void(uint8_t, uint8_t)> callback); void registerPushCallback(std::function<void(uint8_t, uint8_t)> callback);

View File

@ -369,4 +369,27 @@ void ESPMegaIoT::bindEthernetInterface(ETHClass *ethernetIface)
IoTComponent *ESPMegaIoT::getComponent(uint8_t card_id) IoTComponent *ESPMegaIoT::getComponent(uint8_t card_id)
{ {
return components[card_id]; return components[card_id];
}
NetworkConfig* ESPMegaIoT::getNetworkConfig()
{
return &network_config;
}
MqttConfig* ESPMegaIoT::getMqttConfig()
{
return &mqtt_config;
}
bool ESPMegaIoT::mqttConnected()
{
return mqtt_connected;
}
bool ESPMegaIoT::networkConnected()
{
if (network_config.useWifi)
return WiFi.status() == WL_CONNECTED;
else
return ethernetIface->linkUp();
} }

View File

@ -1,3 +1,4 @@
#pragma once
#include <ExpansionCard.hpp> #include <ExpansionCard.hpp>
#include <AnalogCard.hpp> #include <AnalogCard.hpp>
#include <AnalogIoT.hpp> #include <AnalogIoT.hpp>
@ -59,6 +60,8 @@ public:
void ethernetBegin(); void ethernetBegin();
void loadNetworkConfig(); void loadNetworkConfig();
void saveNetworkConfig(); void saveNetworkConfig();
NetworkConfig* getNetworkConfig();
MqttConfig* getMqttConfig();
void setMqttConfig(MqttConfig mqtt_config); void setMqttConfig(MqttConfig mqtt_config);
void saveMqttConfig(); void saveMqttConfig();
void loadMqttConfig(); void loadMqttConfig();
@ -67,6 +70,7 @@ public:
void connectToMqtt(); void connectToMqtt();
bool connectToMqtt(char *client_id, char *mqtt_server, uint16_t mqtt_port, char *mqtt_user, char *mqtt_password); bool connectToMqtt(char *client_id, char *mqtt_server, uint16_t mqtt_port, char *mqtt_user, char *mqtt_password);
bool connectToMqtt(char *client_id, char *mqtt_server, uint16_t mqtt_port); bool connectToMqtt(char *client_id, char *mqtt_server, uint16_t mqtt_port);
bool mqttConnected();
void disconnectFromMqtt(); void disconnectFromMqtt();
void publishToTopic(char *topic, char *payload); void publishToTopic(char *topic, char *payload);
void registerMqttCallback(void (*callback)(char *, char *)); void registerMqttCallback(void (*callback)(char *, char *));
@ -74,6 +78,7 @@ public:
void registerSubscribeCallback(void (*callback)(void)); void registerSubscribeCallback(void (*callback)(void));
void setBaseTopic(char *base_topic); void setBaseTopic(char *base_topic);
void bindEthernetInterface(ETHClass *ethernetIface); void bindEthernetInterface(ETHClass *ethernetIface);
bool networkConnected();
IoTComponent* getComponent(uint8_t card_id); IoTComponent* getComponent(uint8_t card_id);
IPAddress getETHIp(); IPAddress getETHIp();

View File

@ -89,4 +89,10 @@ void ESPMegaPRO::setTime(int hours, int minutes, int seconds, int day, int month
void ESPMegaPRO::enableIotModule() { void ESPMegaPRO::enableIotModule() {
iot.intr_begin(cards); iot.intr_begin(cards);
}
ExpansionCard* ESPMegaPRO::getCard(uint8_t slot) {
if (slot > 255) return nullptr;
if (!cardInstalled[slot]) return nullptr;
return cards[slot];
} }

View File

@ -27,6 +27,7 @@ class ESPMegaPRO {
void enableIotModule(); void enableIotModule();
rtctime_t getTime(); rtctime_t getTime();
void setTime(int hours, int minutes, int seconds, int day, int month, int year); void setTime(int hours, int minutes, int seconds, int day, int month, int year);
ExpansionCard* getCard(uint8_t slot);
FRAM fram; FRAM fram;
DigitalInputCard inputs = DigitalInputCard(INPUT_BANK_A_ADDRESS, INPUT_BANK_B_ADDRESS); DigitalInputCard inputs = DigitalInputCard(INPUT_BANK_A_ADDRESS, INPUT_BANK_B_ADDRESS);
DigitalOutputCard outputs = DigitalOutputCard(PWM_BANK_ADDRESS); DigitalOutputCard outputs = DigitalOutputCard(PWM_BANK_ADDRESS);

View File

@ -1,31 +1,39 @@
#include <InternalDisplay.hpp> #include <InternalDisplay.hpp>
void InternalDisplay::begin() { void InternalDisplay::begin(ESPMegaIoT *iot, std::function<rtctime_t()> getRtcTime) {
this->iot = iot;
this->getRtcTime = getRtcTime;
this->mqttConfig = this->iot->getMqttConfig();
this->networkConfig = this->iot->getNetworkConfig();
// Register callbacks
this->inputCard->registerCallback(std::bind(&InternalDisplay::handleInputStateChange, this, std::placeholders::_1, std::placeholders::_2));
this->outputCard->registerChangeCallback(std::bind(&InternalDisplay::handlePwmStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
} }
void InternalDisplay::loop() { void InternalDisplay::loop() {
// TODO: implementation // Keep reading the Serial Adapter
} this->recieveSerialCommand();
// Refresh the top bar every 5 seconds
void InternalDisplay::bindInputCard(uint8_t card_id) { static uint32_t lastTopBarRefresh;
this->bindedInputCard = card_id; if (millis() - lastTopBarRefresh > INTERNAL_DISPLAY_TOP_BAR_REFRESH_INTERVAL) {
if(currentPage == INTERNAL_DISPLAY_INPUT_PAGE) { this->updateStatusIcons(this->iot->networkConnected(), this->iot->mqttConnected());
refreshInput(); lastTopBarRefresh = millis();
}
// Refresh the clock every 10 seconds
static uint32_t lastClockRefresh;
if (millis() - lastClockRefresh > INTERNAL_DISPLAY_CLOCK_REFRESH_INTERVAL) {
this->updateClock();
lastClockRefresh = millis();
} }
} }
void InternalDisplay::bindOutputCard(uint8_t card_id) {
this->bindedOutputCard = card_id;
if(currentPage == INTERNAL_DISPLAY_OUTPUT_PAGE) {
refreshOutput();
}
}
void InternalDisplay::handleInputStateChange(uint8_t pin, bool state) { void InternalDisplay::handleInputStateChange(uint8_t pin, bool state) {
// If the input card is binded to the display and the current page is the input page // If the input card is binded to the display and the current page is the input page
// then update the respective input component // then update the respective input component
if (!this->bindedInputCard || this->currentPage != INTERNAL_DISPLAY_INPUT_PAGE) return; if (this->inputCard!=nullptr || this->currentPage != INTERNAL_DISPLAY_INPUT_PAGE) return;
// Update the input state // Update the input state
this->setInputMarker(pin, state); this->setInputMarker(pin, state);
} }
@ -33,7 +41,7 @@ void InternalDisplay::handleInputStateChange(uint8_t pin, bool state) {
void InternalDisplay::handlePwmStateChange(uint8_t pin, bool state, uint16_t value) { void InternalDisplay::handlePwmStateChange(uint8_t pin, bool state, uint16_t value) {
// If the output card is binded to the display and the current page is the output page // If the output card is binded to the display and the current page is the output page
// then update the respective output component // then update the respective output component
if (!this->bindedOutputCard || this->currentPage != INTERNAL_DISPLAY_OUTPUT_PAGE) return; if (this->outputCard!=nullptr || this->currentPage != INTERNAL_DISPLAY_OUTPUT_PAGE) return;
// Update the output state // Update the output state
this->setOutputBar(pin, value); this->setOutputBar(pin, value);
this->setOutputStateColor(pin, state); this->setOutputStateColor(pin, state);
@ -96,29 +104,38 @@ void InternalDisplay::refreshDashboard() {
// 2. IP Address // 2. IP Address
// 3. MQTT Server with port // 3. MQTT Server with port
// 4. MQTT Connection status // 4. MQTT Connection status
this->iot-> this->setString("hostname.txt", this->networkConfig->hostname);
// Construct the IP address string
static char ip_address[25];
sprintf(ip_address, "%d.%d.%d.%d", this->networkConfig->ip[0], this->networkConfig->ip[1], this->networkConfig->ip[2], this->networkConfig->ip[3]);
this->setString("ip_address.txt", ip_address);
// Send the MQTT server and port
this->displayAdapter->print("server_address.txt=");
this->displayAdapter->print(this->mqttConfig->mqtt_server);
this->displayAdapter->print(":");
this->displayAdapter->print(this->mqttConfig->mqtt_port);
this->sendStopBytes();
// Send the MQTT connection status
this->setString("status_txt.txt", this->iot->mqttConnected() ? MSG_MQTT_CONNECTED : MSG_MQTT_DISCONNECTED);
} }
void InternalDisplay::refreshInput() { void InternalDisplay::refreshInput() {
// TODO: implementation for (uint8_t i=0; i<16; i++) {
this->setInputMarker(i, this->inputCard->digitalRead(i));
}
} }
void InternalDisplay::refreshOutput() { void InternalDisplay::refreshOutput() {
// TODO: implementation for (uint8_t i=0; i<16; i++) {
this->setOutputBar(i, this->outputCard->getValue(i));
this->setOutputStateColor(i, this->outputCard->getState(i));
}
} }
void InternalDisplay::refreshAC() { void InternalDisplay::refreshAC() {
// TODO: implementation // TODO: implementation
} }
void InternalDisplay::setOutputBar(uint8_t pin, uint16_t value) {
// Write the value to the output bar
this->displayAdapter->print("j");
this->displayAdapter->print(pin);
this->displayAdapter->print(".val=");
this->displayAdapter->print(value);
this->sendStopBytes();
}
void InternalDisplay::setPWMAdjustmentSlider(uint16_t value) { void InternalDisplay::setPWMAdjustmentSlider(uint16_t value) {
// TODO: implementation // TODO: implementation
@ -132,16 +149,32 @@ void InternalDisplay::setPWMAdjustmentButton(bool state) {
// TODO: implementation // TODO: implementation
} }
void InternalDisplay::setOutputBar(uint8_t pin, uint16_t value) {
// Write the value to the output bar
this->displayAdapter->print("j");
this->displayAdapter->print(pin);
this->displayAdapter->print(".val=");
this->displayAdapter->print((int)(value*100/4095));
this->sendStopBytes();
}
void InternalDisplay::setOutputStateColor(uint8_t pin, bool state) { void InternalDisplay::setOutputStateColor(uint8_t pin, bool state) {
// TODO: implementation this->displayAdapter->print("j");
this->displayAdapter->print(pin);
this->displayAdapter->print(".ppic=");
this->displayAdapter->print(state ? PIC_PWM_BAR_ON : PIC_PWM_BAR_OFF);
this->sendStopBytes();
} }
void InternalDisplay::setInputMarker(uint8_t pin, bool state) { void InternalDisplay::setInputMarker(uint8_t pin, bool state) {
// TODO: implementation this->displayAdapter->print("I");
this->displayAdapter->print(pin);
this->displayAdapter->print(".val=");
this->displayAdapter->print(state ? 0:1);
this->sendStopBytes();
} }
InternalDisplay::InternalDisplay(HardwareSerial *displayAdapter) : ESPMegaDisplay(displayAdapter) { InternalDisplay::InternalDisplay(HardwareSerial *displayAdapter) : ESPMegaDisplay(displayAdapter) {
this->currentPage = INTERNAL_DISPLAY_DASHBOARD_PAGE; this->currentPage = INTERNAL_DISPLAY_DASHBOARD_PAGE;
this->bindedInputCard = 0;
this->bindedOutputCard = 0;
} }

View File

@ -1,7 +1,10 @@
#include <ESPMegaDisplay.hpp> #include <ESPMegaDisplay.hpp>
#include <TimeStructure.hpp> #include <TimeStructure.hpp>
#include <ESPMegaIoT.hpp> #include <ESPMegaIoT.hpp>
#include <DigitalInputCard.hpp>
#include <DigitalOutputCard.hpp>
// Page IDs
#define INTERNAL_DISPLAY_DASHBOARD_PAGE 0 #define INTERNAL_DISPLAY_DASHBOARD_PAGE 0
#define INTERNAL_DISPLAY_INPUT_PAGE 1 #define INTERNAL_DISPLAY_INPUT_PAGE 1
#define INTERNAL_DISPLAY_OUTPUT_PAGE 2 #define INTERNAL_DISPLAY_OUTPUT_PAGE 2
@ -12,19 +15,31 @@
#define PIC_LAN_CONNECTED 3 #define PIC_LAN_CONNECTED 3
#define PIC_MQTT_DISCONNECTED 4 #define PIC_MQTT_DISCONNECTED 4
#define PIC_MQTT_CONNECTED 5 #define PIC_MQTT_CONNECTED 5
#define PIC_PWM_BAR_ON 33
#define PIC_PWM_BAR_OFF 48
// Messages
#define MSG_MQTT_CONNECTED "BMS Managed"
#define MSG_MQTT_DISCONNECTED "Standalone"
// Refresh Interval
#define INTERNAL_DISPLAY_CLOCK_REFRESH_INTERVAL 15000
#define INTERNAL_DISPLAY_TOP_BAR_REFRESH_INTERVAL 5000
class InternalDisplay : public ESPMegaDisplay { class InternalDisplay : public ESPMegaDisplay {
public: public:
InternalDisplay(HardwareSerial *displayAdapter); InternalDisplay(HardwareSerial *displayAdapter);
void begin(ESPMegaIoT *iot, std::function<rtctime_t()> getRtcTime); void begin(ESPMegaIoT *iot, std::function<rtctime_t()> getRtcTime);
void loop(); void loop();
void bindInputCard(uint8_t card_id); void bindInputCard(DigitalInputCard *inputCard);
void bindOutputCard(uint8_t card_id); void bindOutputCard(DigitalOutputCard *outputCard);
private: private:
uint8_t bindedInputCard; DigitalInputCard *inputCard;
uint8_t bindedOutputCard; DigitalOutputCard *outputCard;
// Previously registered callbacks of input and output cards
// We need to call them when the respective card is binded to the display
// Because we will replace the callbacks with the display's own callbacks
void handleInputStateChange(uint8_t pin, bool state); void handleInputStateChange(uint8_t pin, bool state);
void handlePwmStateChange(uint8_t pin, bool state, uint16_t value); void handlePwmStateChange(uint8_t pin, bool state, uint16_t value);
void handlePageChange(uint8_t page); void handlePageChange(uint8_t page);
@ -44,6 +59,8 @@ class InternalDisplay : public ESPMegaDisplay {
void refreshInput(); void refreshInput();
void refreshOutput(); void refreshOutput();
void refreshAC(); void refreshAC();
MqttConfig *mqttConfig;
NetworkConfig *networkConfig;
// Pointers to various data // Pointers to various data
ESPMegaIoT *iot; ESPMegaIoT *iot;
std::function<rtctime_t()> getRtcTime; std::function<rtctime_t()> getRtcTime;

View File

@ -50,10 +50,7 @@ void setup() {
espmega.iot.registerCard(0); espmega.iot.registerCard(0);
espmega.iot.registerCard(1); espmega.iot.registerCard(1);
Serial.println("Initialization Routine Complete"); Serial.println("Initialization Routine Complete");
((DigitalInputIoT*)espmega.iot.getComponent(0)) -> registerChangeCallback(input_change_callback); espmega.inputs.registerCallback(input_change_callback);
} }
void loop() { void loop() {