Compare commits

..

No commits in common. "724f8f42e9cece5b763407415971d8481b135449" and "c635427d64399814e77a6d44bd8d7ace0e87603c" have entirely different histories.

11 changed files with 188 additions and 158 deletions

View File

@ -5,11 +5,10 @@ AnalogCard::AnalogCard() : dac0(DAC0_ADDRESS),
dac1(DAC1_ADDRESS), dac1(DAC1_ADDRESS),
dac2(DAC2_ADDRESS), dac2(DAC2_ADDRESS),
dac3(DAC3_ADDRESS), dac3(DAC3_ADDRESS),
analogInputBankA(), analogInputBankA(),
analogInputBankB(), analogInputBankB(),
dac_change_callbacks() dac_change_callbacks()
{ {
this->handler_count = 0;
} }
void AnalogCard::dacWrite(uint8_t pin, uint16_t value) void AnalogCard::dacWrite(uint8_t pin, uint16_t value)
@ -23,10 +22,10 @@ void AnalogCard::setDACState(uint8_t pin, bool state)
{ {
ESP_LOGD("AnalogCard", "Setting DAC state: %d, %d", pin, state); ESP_LOGD("AnalogCard", "Setting DAC state: %d, %d", pin, 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);
for (const auto& callback : this->dac_change_callbacks) for (int i = 0; i < this->dac_change_callbacks.size(); i++)
{ {
callback.second(pin, state, this->dac_value[pin]); this->dac_change_callbacks[i](pin, state, this->dac_value[pin]);
} }
} }
@ -34,13 +33,12 @@ void AnalogCard::setDACValue(uint8_t pin, uint16_t value)
{ {
ESP_LOGD("AnalogCard", "Setting DAC value: %d, %d", pin, value); ESP_LOGD("AnalogCard", "Setting DAC value: %d, %d", pin, 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]);
for (const auto& callback : this->dac_change_callbacks) for (int i = 0; i < this->dac_change_callbacks.size(); i++)
{ {
callback.second(pin, this->dac_state[pin], value); this->dac_change_callbacks[i](pin, this->dac_state[pin], value);
} }
} }
uint16_t AnalogCard::getDACValue(uint8_t pin) uint16_t AnalogCard::getDACValue(uint8_t pin)
{ {
@ -126,13 +124,20 @@ uint8_t AnalogCard::getType()
return CARD_TYPE_ANALOG; return CARD_TYPE_ANALOG;
} }
uint8_t 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_callbacks[this->handler_count] = callback; this->dac_change_callbacks.push_back(callback);
return this->handler_count++;
} }
void AnalogCard::deregisterDACChangeCallback(uint8_t handler) // void AnalogCard::deregisterDACChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback)
{ // {
this->dac_change_callbacks.erase(handler); // 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

@ -3,7 +3,6 @@
#include <Adafruit_ADS1X15.h> #include <Adafruit_ADS1X15.h>
#include <MCP4725.h> #include <MCP4725.h>
#include <vector> #include <vector>
#include <map>
#define CARD_TYPE_ANALOG 0x02 #define CARD_TYPE_ANALOG 0x02
@ -26,12 +25,11 @@ class AnalogCard : public ExpansionCard {
uint16_t getDACValue(uint8_t pin); uint16_t getDACValue(uint8_t pin);
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);
uint8_t registerDACChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback); void registerDACChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback);
void deregisterDACChangeCallback(uint8_t handler); //void deregisterDACChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback);
uint8_t getType(); uint8_t getType();
private: private:
uint8_t handler_count; std::vector<std::function<void(uint8_t, bool, uint16_t)>> dac_change_callbacks;
std::map<uint8_t, 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

@ -5,7 +5,6 @@ AnalogIoT::AnalogIoT() : adc_conversion_callbacks() {
adc_publish_enabled[i] = false; adc_publish_enabled[i] = false;
adc_conversion_interval[i] = 1000; adc_conversion_interval[i] = 1000;
} }
this->adc_conversion_callback_index = 0;
} }
AnalogIoT::~AnalogIoT() { AnalogIoT::~AnalogIoT() {
@ -50,8 +49,8 @@ void AnalogIoT::publishADC(uint8_t pin) {
delete[] topic; delete[] topic;
delete[] payload; delete[] payload;
// Call all callbacks // Call all callbacks
for (auto& callback : this->adc_conversion_callbacks) { for (int i = 0; i < this->adc_conversion_callbacks.size(); i++) {
callback.second(pin, value); this->adc_conversion_callbacks[i](pin, value);
} }
} }
} }
@ -65,13 +64,17 @@ void AnalogIoT::setADCsPublishEnabled(bool enabled) {
adc_publish_enabled[i] = enabled; adc_publish_enabled[i] = enabled;
} }
} }
uint8_t AnalogIoT::registerADCConversionCallback(std::function<void(uint8_t, uint16_t)> callback) { void AnalogIoT::registerADCConversionCallback(std::function<void(uint8_t, uint16_t)> callback) {
this->adc_conversion_callbacks[this->adc_conversion_callback_index] = callback; this->adc_conversion_callbacks.push_back(callback);
return this->adc_conversion_callback_index++;
}
void AnalogIoT::deregisterADCConversionCallback(uint8_t handler) {
this->adc_conversion_callbacks.erase(handler);
} }
// 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,7 +1,7 @@
#pragma once #pragma once
#include <IoTComponent.hpp> #include <IoTComponent.hpp>
#include <AnalogCard.hpp> #include <AnalogCard.hpp>
#include <map> #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"
@ -25,8 +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);
uint8_t registerADCConversionCallback(std::function<void(uint8_t, uint16_t)> callback); void registerADCConversionCallback(std::function<void(uint8_t, uint16_t)> callback);
void deregisterADCConversionCallback(uint8_t handler); // 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);
@ -39,7 +39,6 @@ class AnalogIoT : public IoTComponent {
void loop(); void loop();
uint8_t getType(); uint8_t getType();
private: private:
uint8_t adc_conversion_callback_index = 0;
uint8_t dac_set_state_length; uint8_t dac_set_state_length;
uint8_t dac_set_value_length; uint8_t dac_set_value_length;
uint8_t dac_state_length; uint8_t dac_state_length;
@ -51,5 +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::map<uint8_t, std::function<void(uint8_t, uint16_t)>> adc_conversion_callbacks; std::vector<std::function<void(uint8_t, uint16_t)>> adc_conversion_callbacks;
}; };

View File

@ -22,6 +22,8 @@ ClimateCard::ClimateCard(uint8_t ir_pin, AirConditioner ac, uint8_t sensor_type,
this->state.ac_temperature = 25; this->state.ac_temperature = 25;
this->state.ac_mode = 0; this->state.ac_mode = 0;
this->state.ac_fan_speed = 0; this->state.ac_fan_speed = 0;
// Initialize callbacks
this->callbacks = std::vector<std::function<void(uint8_t, uint8_t, uint8_t)>>();
} }
ClimateCard::ClimateCard(uint8_t ir_pin, AirConditioner ac) : ClimateCard(ir_pin, ac, AC_SENSOR_TYPE_NONE, 0) ClimateCard::ClimateCard(uint8_t ir_pin, AirConditioner ac) : ClimateCard(ir_pin, ac, AC_SENSOR_TYPE_NONE, 0)
@ -87,24 +89,46 @@ void ClimateCard::saveStateToFRAM()
fram->write8(fram_address, state.ac_temperature); fram->write8(fram_address, state.ac_temperature);
fram->write8(fram_address + 1, state.ac_mode); fram->write8(fram_address + 1, state.ac_mode);
fram->write8(fram_address + 2, state.ac_fan_speed); fram->write8(fram_address + 2, state.ac_fan_speed);
Serial.println("Saved state to FRAM");
Serial.write(0xFF);
Serial.write(0xFF);
Serial.write(0xFF);
} }
void ClimateCard::loadStateFromFRAM() void ClimateCard::loadStateFromFRAM()
{ {
if (state.ac_temperature > ac.max_temperature) Serial.print("Loading temperature from FRAM at address ");
state.ac_temperature = ac.max_temperature; Serial.print(fram_address);
else if (state.ac_temperature < ac.min_temperature) Serial.print(": ");
state.ac_temperature = ac.min_temperature; Serial.println(fram->read8(fram_address));
// If mode is out of range, set to 0 state.ac_temperature = fram->read8(fram_address);
if (state.ac_mode > ac.modes) Serial.print("Loading mode from FRAM at address ");
state.ac_mode = 0; Serial.print(fram_address + 1);
// If fan speed is out of range, set to 0 Serial.print(": ");
if (state.ac_fan_speed > ac.fan_speeds) Serial.println(fram->read8(fram_address + 1));
state.ac_fan_speed = 0; state.ac_mode = fram->read8(fram_address + 1);
Serial.print("Loading fan speed from FRAM at address ");
Serial.print(fram_address + 2);
Serial.print(": ");
Serial.println(fram->read8(fram_address + 2));
state.ac_fan_speed = fram->read8(fram_address + 2);
Serial.write(0xFF);
Serial.write(0xFF);
Serial.write(0xFF);
// if (state.ac_temperature > ac.max_temperature)
// state.ac_temperature = ac.max_temperature;
// else if (state.ac_temperature < ac.min_temperature)
// state.ac_temperature = ac.min_temperature;
// // If mode is out of range, set to 0
// if (state.ac_mode > ac.modes)
// state.ac_mode = 0;
// // If fan speed is out of range, set to 0
// if (state.ac_fan_speed > ac.fan_speeds)
// state.ac_fan_speed = 0;
updateAirConditioner(); updateAirConditioner();
for (const auto& callback : callbacks) for (uint8_t i = 0; i < callbacks.size(); i++)
{ {
callback.second(this->state.ac_mode, this->state.ac_fan_speed, this->state.ac_temperature); callbacks[i](this->state.ac_mode, this->state.ac_fan_speed, this->state.ac_temperature);
} }
} }
@ -137,10 +161,13 @@ void ClimateCard::setFanSpeed(uint8_t fan_speed)
saveStateToFRAM(); saveStateToFRAM();
} }
uint8_t ClimateCard::registerChangeCallback(std::function<void(uint8_t, uint8_t, uint8_t)> callback) void ClimateCard::registerChangeCallback(std::function<void(uint8_t, uint8_t, uint8_t)> callback)
{ {
callbacks[callbacks_handler_count] = callback; Serial.print("Registering callback");
return callbacks_handler_count++; Serial.write(0xFF);
Serial.write(0xFF);
Serial.write(0xFF);
callbacks.push_back(callback);
} }
uint8_t ClimateCard::getType() uint8_t ClimateCard::getType()
@ -175,9 +202,9 @@ void ClimateCard::updateSensor()
room_temperature = ds18b20->getTempC(); room_temperature = ds18b20->getTempC();
break; break;
} }
for (const auto& callback : sensor_callbacks) for (uint8_t i = 0; i < sensor_callbacks.size(); i++)
{ {
callback.second(room_temperature, humidity); sensor_callbacks[i](room_temperature, humidity);
} }
} }
@ -202,9 +229,14 @@ void ClimateCard::updateAirConditioner()
// rmt_write_items(RMT_TX_CHANNEL, items, itemCount, true); // rmt_write_items(RMT_TX_CHANNEL, items, itemCount, true);
// rmt_wait_tx_done(RMT_TX_CHANNEL, portMAX_DELAY); // rmt_wait_tx_done(RMT_TX_CHANNEL, portMAX_DELAY);
// // Publish state // // Publish state
for (const auto& callback : callbacks) Serial.print("Callbacks: ");
Serial.println(callbacks.size());
Serial.write(0xFF);
Serial.write(0xFF);
Serial.write(0xFF);
for (uint8_t i = 0; i < callbacks.size(); i++)
{ {
callback.second(this->state.ac_mode, this->state.ac_fan_speed, this->state.ac_temperature); callbacks[i](this->state.ac_mode, this->state.ac_fan_speed, this->state.ac_temperature);
} }
} }
@ -238,18 +270,8 @@ uint8_t ClimateCard::getFanSpeed()
return state.ac_fan_speed; return state.ac_fan_speed;
} }
uint8_t ClimateCard::registerSensorCallback(std::function<void(float, float)> callback) void ClimateCard::registerSensorCallback(std::function<void(float, float)> callback)
{ {
sensor_callbacks[sensor_callbacks_handler_count] = callback; sensor_callbacks.push_back(callback);
return sensor_callbacks_handler_count++;
} }
void ClimateCard::unregisterChangeCallback(uint8_t handler)
{
callbacks.erase(handler);
}
void ClimateCard::unregisterSensorCallback(uint8_t handler)
{
sensor_callbacks.erase(handler);
}

View File

@ -5,7 +5,7 @@
#include <OneWire.h> #include <OneWire.h>
#include <DS18B20.h> #include <DS18B20.h>
#include <dhtnew.h> #include <dhtnew.h>
#include <map> #include <vector>
#define RMT_TX_CHANNEL RMT_CHANNEL_0 #define RMT_TX_CHANNEL RMT_CHANNEL_0
@ -58,10 +58,8 @@ class ClimateCard : public ExpansionCard {
float getRoomTemperature(); float getRoomTemperature();
float getHumidity(); float getHumidity();
uint8_t getSensorType(); uint8_t getSensorType();
uint8_t registerChangeCallback(std::function<void(uint8_t, uint8_t, uint8_t)> callback); void registerChangeCallback(std::function<void(uint8_t, uint8_t, uint8_t)> callback);
uint8_t registerSensorCallback(std::function<void(float, float)> callback); void registerSensorCallback(std::function<void(float, float)> callback);
void unregisterChangeCallback(uint8_t handler);
void unregisterSensorCallback(uint8_t handler);
uint8_t getType(); uint8_t getType();
private: private:
// Sensor objects // Sensor objects
@ -69,10 +67,8 @@ class ClimateCard : public ExpansionCard {
DHTNEW *dht; DHTNEW *dht;
DS18B20 *ds18b20; DS18B20 *ds18b20;
// Callbacks // Callbacks
uint8_t callbacks_handler_count = 0; std::vector<std::function<void(uint8_t, uint8_t, uint8_t)>> callbacks;
uint8_t sensor_callbacks_handler_count = 0; std::vector<std::function<void(float, float)>> sensor_callbacks;
std::map<uint8_t,std::function<void(uint8_t, uint8_t, uint8_t)>> callbacks;
std::map<uint8_t,std::function<void(float, float)>> sensor_callbacks;
// Update functions // Update functions
void updateSensor(); void updateSensor();
void updateAirConditioner(); void updateAirConditioner();

View File

@ -5,7 +5,6 @@ DigitalInputCard::DigitalInputCard(uint8_t address_a, uint8_t address_b) : callb
{ {
this->address_a = address_a; this->address_a = address_a;
this->address_b = address_b; this->address_b = address_b;
this->callbacks_handler_index = 0;
} }
// Instantiate the card with the specified position on the dip switch // Instantiate the card with the specified position on the dip switch
// Bit 0,1,2 are for bank A // Bit 0,1,2 are for bank A
@ -96,8 +95,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));
for(const auto& callback : callbacks) for (int i = 0; i < callbacks.size(); i++)
callback.second(virtualPin, ((currentBuffer >> (7 - pin)) & 1)); callbacks[i](virtualPin, ((currentBuffer >> (7 - pin)) & 1));
} }
} }
// Handle Bank B // Handle Bank B
@ -107,8 +106,8 @@ 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));
for (const auto& callback : callbacks) for (int i = 0; i < callbacks.size(); i++)
callback.second(virtualPin, ((currentBuffer >> (15 - pin)) & 1)); callbacks[i](virtualPin, ((currentBuffer >> (15 - pin)) & 1));
} }
} }
} }
@ -157,10 +156,11 @@ uint8_t DigitalInputCard::getInputBufferB()
return inputBufferB_rearranged; return inputBufferB_rearranged;
} }
// Register a callback function to be called when a pin changes // Register a callback function to be called when a pin changes
uint8_t DigitalInputCard::registerCallback(std::function<void(uint8_t, bool)> callback) void DigitalInputCard::registerCallback(std::function<void(uint8_t, bool)> callback)
{ {
callbacks[this->callbacks_handler_index] = callback; ESP_LOGD("DigitalInputCard", "Registering callback");
return this->callbacks_handler_index++; callbacks.push_back(callback);
ESP_LOGD("DigitalInputCard", "Callback registered");
} }
// Refresh the input buffer for bank A // Refresh the input buffer for bank A
@ -180,10 +180,17 @@ void DigitalInputCard::setDebounceTime(uint8_t pin, uint32_t debounceTime)
this->debounceTime[pin] = debounceTime; this->debounceTime[pin] = debounceTime;
} }
void DigitalInputCard::unregisterCallback(uint8_t handler) // void DigitalInputCard::unregisterCallback(std::function<void(uint8_t, bool)> callback)
{ // {
callbacks.erase(handler); // 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,7 +1,7 @@
#pragma once #pragma once
#include <ExpansionCard.hpp> #include <ExpansionCard.hpp>
#include <PCF8574.h> #include <PCF8574.h>
#include <map> #include <vector>
#define CARD_TYPE_DIGITAL_INPUT 0x01 #define CARD_TYPE_DIGITAL_INPUT 0x01
@ -26,9 +26,9 @@ class DigitalInputCard : public ExpansionCard {
// Set the debounce time for the specified pin // Set the debounce time for the specified pin
void setDebounceTime(uint8_t pin, uint32_t debounceTime); void setDebounceTime(uint8_t pin, uint32_t debounceTime);
// Register a callback function to be called when a pin changes // Register a callback function to be called when a pin changes
uint8_t 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(uint8_t handler); //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
@ -48,8 +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];
uint8_t callbacks_handler_index = 0; std::vector<std::function<void(uint8_t, bool)>> callbacks;
std::map<uint8_t, 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

@ -7,15 +7,16 @@ DigitalOutputCard::DigitalOutputCard(uint8_t address) : change_callbacks(){
this->pinMap[i] = i; this->pinMap[i] = i;
this->virtualPinMap[i] = i; this->virtualPinMap[i] = i;
} }
this->framBinded = false;
this->callbacks_handler_index = 0;
} }
// Instantiate the card with the specified position on the dip switch // Instantiate the card with the specified position on the dip switch
DigitalOutputCard::DigitalOutputCard(bool bit0, bool bit1, bool bit2, bool bit3, bool bit4) : DigitalOutputCard::DigitalOutputCard(bool bit0, bool bit1, bool bit2, bool bit3, bool bit4) {
DigitalOutputCard(0x20+bit0+bit1*2+bit2*4+bit3*8+bit4*16) this->address = 0x20;
{ if (bit0) this->address += 1;
if (bit1) this->address += 2;
if (bit2) this->address += 4;
if (bit3) this->address += 8;
if (bit4) this->address += 16;
} }
// Initialize the card // Initialize the card
bool DigitalOutputCard::begin() { bool DigitalOutputCard::begin() {
@ -35,9 +36,8 @@ void DigitalOutputCard::digitalWrite(uint8_t pin, bool state) {
this->saveStateToFRAM(); this->saveStateToFRAM();
this->savePinValueToFRAM(pin); this->savePinValueToFRAM(pin);
} }
for (const auto& callback : change_callbacks) for (int i = 0; i < change_callbacks.size(); i++) {
{ change_callbacks[i](pin, state, state ? 4095 : 0);
callback.second(pin, state, state ? 4095 : 0);
} }
} }
// Set the output to the specified pwm value // Set the output to the specified pwm value
@ -52,9 +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;
for (const auto& callback : change_callbacks) for (int i = 0; i < change_callbacks.size(); i++) {
{ change_callbacks[i](pin, value > 0, value);
callback.second(pin, value > 0, value);
} }
} }
@ -83,8 +82,8 @@ void DigitalOutputCard::setState(uint8_t pin, bool state) {
if(this->framAutoSave) { if(this->framAutoSave) {
this->saveStateToFRAM(); this->saveStateToFRAM();
} }
for(const auto& callback : change_callbacks) { for(int i = 0; i < change_callbacks.size(); i++) {
callback.second(pin, state, value_buffer[pin]); change_callbacks[i](pin, state, value_buffer[pin]);
} }
} }
@ -96,20 +95,23 @@ void DigitalOutputCard::setValue(uint8_t pin, uint16_t value) {
if (this->framAutoSave) { if (this->framAutoSave) {
this->savePinValueToFRAM(pin); this->savePinValueToFRAM(pin);
} }
for (const auto& callback : change_callbacks) for (int i = 0; i < change_callbacks.size(); i++) {
{ change_callbacks[i](pin, state_buffer[pin], value);
callback.second(pin, state_buffer[pin], value);
} }
} }
uint8_t 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_callbacks[this->callbacks_handler_index] = callback; this->change_callbacks.push_back(callback);
return this->callbacks_handler_index++;
} }
void DigitalOutputCard::deregisterChangeCallback(uint8_t handler) { // void DigitalOutputCard::deregisterChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback) {
this->change_callbacks.erase(handler); // 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,7 +2,7 @@
#include <ExpansionCard.hpp> #include <ExpansionCard.hpp>
#include <Adafruit_PWMServoDriver.h> #include <Adafruit_PWMServoDriver.h>
#include <FRAM.h> #include <FRAM.h>
#include <map> #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
@ -48,9 +48,9 @@ public:
// Get the pwm value of the specified pin // Get the pwm value of the specified pin
uint16_t getValue(uint8_t pin); uint16_t getValue(uint8_t pin);
// 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
uint8_t 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(uint8_t handler); // 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
@ -90,8 +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
uint8_t callbacks_handler_index = 0; std::vector<std::function<void(uint8_t, bool, uint16_t)>> change_callbacks;
std::map<uint8_t, 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

@ -52,37 +52,37 @@ void setup() {
espmega.enableIotModule(); espmega.enableIotModule();
ETH.begin(); ETH.begin();
espmega.iot->bindEthernetInterface(&ETH); espmega.iot->bindEthernetInterface(&ETH);
// NetworkConfig config = { NetworkConfig config = {
// .ip = {192, 168, 0, 11}, .ip = {192, 168, 0, 11},
// .gateway = {192, 168, 0, 1}, .gateway = {192, 168, 0, 1},
// .subnet = {255, 255, 255, 0}, .subnet = {255, 255, 255, 0},
// .dns1 = {192, 168, 0, 1}, .dns1 = {192, 168, 0, 1},
// .dns2 = {192, 168, 0, 1}, .dns2 = {192, 168, 0, 1},
// .useStaticIp = true, .useStaticIp = true,
// .useWifi = false, .useWifi = false,
// .wifiUseAuth = false, .wifiUseAuth = false,
// }; };
// strcpy(config.ssid, "ssid"); strcpy(config.ssid, "ssid");
// strcpy(config.password, "password"); strcpy(config.password, "password");
// strcpy(config.hostname, "espmega"); strcpy(config.hostname, "espmega");
// Serial.println("Setting network config"); Serial.println("Setting network config");
// espmega.iot->setNetworkConfig(config); espmega.iot->setNetworkConfig(config);
// espmega.iot->saveNetworkConfig(); espmega.iot->saveNetworkConfig();
espmega.iot->loadNetworkConfig(); // espmega.iot->loadNetworkConfig();
Serial.println("Connecting to network"); Serial.println("Connecting to network");
espmega.iot->connectNetwork(); espmega.iot->connectNetwork();
Serial.println("Begin MQTT Modules"); Serial.println("Begin MQTT Modules");
// MqttConfig mqtt_config = { MqttConfig mqtt_config = {
// .mqtt_port = 1883, .mqtt_port = 1883,
// .mqtt_useauth = false .mqtt_useauth = false
// }; };
// Serial.println("Setting MQTT Server"); Serial.println("Setting MQTT Server");
// strcpy(mqtt_config.mqtt_server, "192.168.0.26"); strcpy(mqtt_config.mqtt_server, "192.168.0.26");
// strcpy(mqtt_config.base_topic, "/espmegaoop"); strcpy(mqtt_config.base_topic, "/espmegaoop");
// Serial.println("Loading MQTT Config Struct to IoT Module"); Serial.println("Loading MQTT Config Struct to IoT Module");
// espmega.iot->setMqttConfig(mqtt_config); espmega.iot->setMqttConfig(mqtt_config);
// espmega.iot->saveMqttConfig(); espmega.iot->saveMqttConfig();
espmega.iot->loadMqttConfig(); // espmega.iot->loadMqttConfig();
Serial.println("Connecting to MQTT"); Serial.println("Connecting to MQTT");
espmega.iot->connectToMqtt(); espmega.iot->connectToMqtt();
Serial.println("Registering Output Card"); Serial.println("Registering Output Card");
@ -112,13 +112,13 @@ void setup() {
// Every 20 seconds, dump FRAM 0-500 to serial // Every 20 seconds, dump FRAM 0-500 to serial
void loop() { void loop() {
espmega.loop(); espmega.loop();
// static uint32_t last_fram_dump = 0; static uint32_t last_fram_dump = 0;
// if (millis() - last_fram_dump >= 20000) { if (millis() - last_fram_dump >= 20000) {
// last_fram_dump = millis(); last_fram_dump = millis();
// Serial.println("Dumping FRAM"); Serial.println("Dumping FRAM");
// espmega.dumpFRAMtoSerial(0, 500); espmega.dumpFRAMtoSerial(0, 500);
// Serial.println("Dumping FRAM ASCII"); Serial.println("Dumping FRAM ASCII");
// espmega.dumpFRAMtoSerialASCII(0, 500); espmega.dumpFRAMtoSerialASCII(0, 500);
// } }
} }