From 2fd37fe66da88a1370faf87f2c159aa7f8fc573d Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Thu, 28 Dec 2023 19:01:37 +0700 Subject: [PATCH] add digital output pinmap support --- Template Project/.vscode/settings.json | 3 +- .../lib/ESPMegaPRO/DigitalInputCard.cpp | 2 +- .../lib/ESPMegaPRO/DigitalInputCard.hpp | 4 +- .../lib/ESPMegaPRO/DigitalOutputCard.cpp | 53 ++++++++++++------- .../lib/ESPMegaPRO/DigitalOutputCard.hpp | 16 ++++++ .../lib/ESPMegaPRO/DigitalOutputIoT.cpp | 9 ++-- .../lib/ESPMegaPRO/DigitalOutputIoT.hpp | 6 +-- 7 files changed, 63 insertions(+), 30 deletions(-) diff --git a/Template Project/.vscode/settings.json b/Template Project/.vscode/settings.json index 2da7432..9d43f7f 100644 --- a/Template Project/.vscode/settings.json +++ b/Template Project/.vscode/settings.json @@ -12,7 +12,8 @@ "adafruit_ads1x15.h": "c", "*.tcc": "cpp", "memory": "cpp", - "random": "cpp" + "random": "cpp", + "functional": "cpp" }, "cmake.configureOnOpen": true, "cmake.sourceDirectory": "D:/Git/ESPMegaPRO-v3-SDK/Template Project/.pio/libdeps/wt32-eth01/Adafruit BusIO" diff --git a/Template Project/lib/ESPMegaPRO/DigitalInputCard.cpp b/Template Project/lib/ESPMegaPRO/DigitalInputCard.cpp index 8ebdec5..fcc5e92 100644 --- a/Template Project/lib/ESPMegaPRO/DigitalInputCard.cpp +++ b/Template Project/lib/ESPMegaPRO/DigitalInputCard.cpp @@ -156,7 +156,7 @@ uint8_t DigitalInputCard::getInputBufferB() return inputBufferB_rearranged; } // Register a callback function to be called when a pin changes -void DigitalInputCard::registerCallback(void (*callback)(uint8_t, bool)) +void DigitalInputCard::registerCallback(std::function callback) { this->callback = callback; } diff --git a/Template Project/lib/ESPMegaPRO/DigitalInputCard.hpp b/Template Project/lib/ESPMegaPRO/DigitalInputCard.hpp index 86b6be1..54caf91 100644 --- a/Template Project/lib/ESPMegaPRO/DigitalInputCard.hpp +++ b/Template Project/lib/ESPMegaPRO/DigitalInputCard.hpp @@ -25,7 +25,7 @@ class DigitalInputCard : public ExpansionCard { // Set the debounce time for the specified pin void setDebounceTime(uint8_t pin, uint32_t debounceTime); // Register a callback function to be called when a pin changes - void registerCallback(void (*callback)(uint8_t, bool)); + void registerCallback(std::function callback); // Unregister the callback function void unregisterCallback(); // Load a new pin map @@ -47,7 +47,7 @@ class DigitalInputCard : public ExpansionCard { uint8_t pinMap[16]; // A map of the virtual pin to the physical pin uint8_t virtualPinMap[16]; - void (*callback)(uint8_t, bool); + std::function callback; void refreshInputBankA(); void refreshInputBankB(); void handlePinChange(int pin, uint8_t& currentBuffer, uint8_t& previousBuffer); diff --git a/Template Project/lib/ESPMegaPRO/DigitalOutputCard.cpp b/Template Project/lib/ESPMegaPRO/DigitalOutputCard.cpp index 71414a6..741ee2a 100644 --- a/Template Project/lib/ESPMegaPRO/DigitalOutputCard.cpp +++ b/Template Project/lib/ESPMegaPRO/DigitalOutputCard.cpp @@ -2,7 +2,11 @@ DigitalOutputCard::DigitalOutputCard(uint8_t address) { this->address = address; - + // load default pin map + for (int i = 0; i < 16; i++) { + this->pinMap[i] = i; + this->virtualPinMap[i] = i; + } } // Instantiate the card with the specified position on the dip switch DigitalOutputCard::DigitalOutputCard(bool bit0, bool bit1, bool bit2, bool bit3, bool bit4) { @@ -25,18 +29,24 @@ bool DigitalOutputCard::begin() { } // Set the output to the specified state void DigitalOutputCard::digitalWrite(uint8_t pin, bool state) { - this->pwm.setPin(pin, state ? 4095 : 0); + this->pwm.setPin(virtualPinMap[pin], state ? 4095 : 0); this->state_buffer[pin] = state; this->value_buffer[pin] = state ? 4095 : 0; + if(change_callback != NULL) { + change_callback(pin, state, state ? 4095 : 0); + } } // Set the output to the specified pwm value void DigitalOutputCard::analogWrite(uint8_t pin, uint16_t value) { // If value is greater than 4095, set it to 4095 if (value > 4095) value = 4095; // Set the pwm value - this->pwm.setPin(pin, value); + this->pwm.setPin(virtualPinMap[pin], value); this->state_buffer[pin] = value > 0; this->value_buffer[pin] = value; + if(change_callback != NULL) { + change_callback(pin, value > 0, value); + } } // Dummy loop function @@ -59,29 +69,34 @@ uint8_t DigitalOutputCard::getType() { } void DigitalOutputCard::setState(uint8_t pin, bool state) { - Serial.print("Setting state of pin "); - Serial.print(pin); - Serial.print(" to "); - Serial.println(state); this-> state_buffer[pin] = state; - Serial.print("New state of pin "); - Serial.print(pin); - Serial.print(" is "); - Serial.println(state_buffer[pin]*value_buffer[pin]); this->pwm.setPin(pin, state*value_buffer[pin]); + if (change_callback != NULL) { + change_callback(pin, state, value_buffer[pin]); + } } void DigitalOutputCard::setValue(uint8_t pin, uint16_t value) { - Serial.print("Setting value of pin "); - Serial.print(pin); - Serial.print(" to "); - Serial.println(value); // If value is greater than 4095, set it to 4095 if (value > 4095) value = 4095; this-> value_buffer[pin] = value; - Serial.print("New value of pin "); - Serial.print(pin); - Serial.print(" is "); - Serial.println(value_buffer[pin]*state_buffer[pin]); this->pwm.setPin(pin, state_buffer[pin]*value); + if (change_callback != NULL) { + change_callback(pin, state_buffer[pin], value); + } } + +void DigitalOutputCard::registerChangeCallback(std::function callback) { + this->change_callback = callback; +} + +void DigitalOutputCard::deregisterChangeCallback() { + this->change_callback = NULL; +} + +void DigitalOutputCard::loadPinMap(uint8_t pinMap[16]) { + for(int i = 0; i < 16; i++) { + this->pinMap[i] = pinMap[i]; + this->virtualPinMap[pinMap[i]] = i; + } +} \ No newline at end of file diff --git a/Template Project/lib/ESPMegaPRO/DigitalOutputCard.hpp b/Template Project/lib/ESPMegaPRO/DigitalOutputCard.hpp index e2bac83..41afad8 100644 --- a/Template Project/lib/ESPMegaPRO/DigitalOutputCard.hpp +++ b/Template Project/lib/ESPMegaPRO/DigitalOutputCard.hpp @@ -45,11 +45,27 @@ public: bool getState(uint8_t pin); // Get the pwm value of the specified pin uint16_t getValue(uint8_t pin); + // Register a callback function that will be called when the state of a pin changes + void registerChangeCallback(std::function callback); + // Deregister the callback function + void deregisterChangeCallback(); + // Load a new pin map + void loadPinMap(uint8_t pinMap[16]); // Get type of card uint8_t getType(); private: + // The pwm driver Adafruit_PWMServoDriver pwm; + // The address of the card uint8_t address; + // The state of the card bool state_buffer[16]; + // The pwm value of the card uint16_t value_buffer[16]; + // The callback function + std::function change_callback; + // Physical pin to virtual pin map + uint8_t pinMap[16]; + // Virtual pin to physical pin map + uint8_t virtualPinMap[16]; }; \ No newline at end of file diff --git a/Template Project/lib/ESPMegaPRO/DigitalOutputIoT.cpp b/Template Project/lib/ESPMegaPRO/DigitalOutputIoT.cpp index 213b596..a7065e9 100644 --- a/Template Project/lib/ESPMegaPRO/DigitalOutputIoT.cpp +++ b/Template Project/lib/ESPMegaPRO/DigitalOutputIoT.cpp @@ -27,6 +27,9 @@ bool DigitalOutputIoT::begin(uint8_t card_id, ExpansionCard *card, PubSubClient this->publish_enable_length = strlen(PUBLISH_ENABLE_TOPIC); strcpy(this->state_report_topic, "00/state"); strcpy(this->value_report_topic, "00/value"); + // Register callbacks + auto bindedCallback = std::bind(&DigitalOutputIoT::handleValueChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); + this->card->registerChangeCallback(bindedCallback); return true; } @@ -86,7 +89,6 @@ bool DigitalOutputIoT::processSetStateMessage(char *topic, char *payload, uint8_ Serial.println(state); // Set the state card->setState(pin, state); - publishDigitalOutputState(pin); return true; } return false; @@ -116,7 +118,6 @@ bool DigitalOutputIoT::processSetValueMessage(char *topic, char *payload, uint8_ uint16_t value = atoi(payload); // Set the value card->setValue(pin, value); - publishDigitalOutputValue(pin); return true; } return false; @@ -186,11 +187,11 @@ void DigitalOutputIoT::handleValueChange(uint8_t pin, bool state, uint16_t value } } -void DigitalOutputIoT::registerValueChangeCallback(void (*callback)(uint8_t, bool, uint16_t)) { +void DigitalOutputIoT::registerChangeCallback(std::function callback) { value_change_callback = callback; } -void DigitalOutputIoT::deregisterValueChangeCallback() { +void DigitalOutputIoT::deregisterChangeCallback() { value_change_callback = NULL; } diff --git a/Template Project/lib/ESPMegaPRO/DigitalOutputIoT.hpp b/Template Project/lib/ESPMegaPRO/DigitalOutputIoT.hpp index a166998..55cb959 100644 --- a/Template Project/lib/ESPMegaPRO/DigitalOutputIoT.hpp +++ b/Template Project/lib/ESPMegaPRO/DigitalOutputIoT.hpp @@ -15,8 +15,8 @@ class DigitalOutputIoT : public IoTComponent { void publishDigitalOutputValue(uint8_t pin); void setDigitalOutputsPublishEnabled(bool enabled); void handleValueChange(uint8_t pin, bool state, uint16_t value); - void registerValueChangeCallback(void (*callback)(uint8_t, bool, uint16_t)); - void deregisterValueChangeCallback(); + void registerChangeCallback(std::function callback); + void deregisterChangeCallback(); void publishReport(); void subscribe(); void loop(); @@ -26,7 +26,7 @@ class DigitalOutputIoT : public IoTComponent { bool processSetStateMessage(char *topic, char *payload, uint8_t topic_length); bool processSetValueMessage(char *topic, char *payload, uint8_t topic_length); bool processRequestStateMessage(char *topic, char *payload, uint8_t topic_length); - void (*value_change_callback)(uint8_t, bool, uint16_t); + std::function value_change_callback; DigitalOutputCard *card; char *state_report_topic; char *value_report_topic;