2023-12-31 18:38:25 +00:00
|
|
|
/**
|
|
|
|
* @file AnalogIoT.cpp
|
|
|
|
* @brief Implementation of the AnalogIoT class.
|
|
|
|
*
|
|
|
|
* This file contains the implementation of the AnalogIoT class, which provides functionality for handling analog input and output operations in an IoT system.
|
|
|
|
* The class allows for setting the state and value of digital-to-analog converters (DACs), as well as reading the value of analog-to-digital converters (ADCs).
|
|
|
|
* It also supports publishing the state and value of DACs and ADCs over MQTT.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
#include <AnalogIoT.hpp>
|
|
|
|
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Default constructor for the AnalogIoT class.
|
|
|
|
*
|
|
|
|
* This constructor initializes the AnalogIoT object and sets up the ADC conversion callbacks.
|
|
|
|
*/
|
2023-12-30 11:27:39 +00:00
|
|
|
AnalogIoT::AnalogIoT() : adc_conversion_callbacks() {
|
2023-12-28 17:39:11 +00:00
|
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
|
|
adc_publish_enabled[i] = false;
|
|
|
|
adc_conversion_interval[i] = 1000;
|
|
|
|
}
|
2023-12-31 06:29:11 +00:00
|
|
|
this->adc_conversion_callback_index = 0;
|
2023-12-28 17:39:11 +00:00
|
|
|
}
|
|
|
|
|
2023-12-31 18:38:25 +00:00
|
|
|
/**
|
|
|
|
* @brief Default destructor for the AnalogIoT class.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
AnalogIoT::~AnalogIoT() {
|
2023-12-31 18:38:25 +00:00
|
|
|
this->adc_conversion_callbacks.clear();
|
2023-12-28 17:39:11 +00:00
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Initializes the AnalogIoT object.
|
|
|
|
* @param card_id The ID of the card.
|
|
|
|
* @param card A pointer to the card object.
|
|
|
|
* @param mqtt A pointer to the MQTT client object.
|
|
|
|
* @param base_topic The base MQTT topic.
|
|
|
|
* @return True if the initialization was successful, false otherwise.
|
|
|
|
* @note This function can be called from the main program but it is recommended to use ESPMegaIoT to initialize the IoT Components.
|
|
|
|
* This function initializes the AnalogIoT object and registers the callbacks for handling DAC changes.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
bool AnalogIoT::begin(uint8_t card_id, ExpansionCard *card, PubSubClient *mqtt, char *base_topic) {
|
|
|
|
this->mqtt = mqtt;
|
|
|
|
this->base_topic = base_topic;
|
|
|
|
this->card = (AnalogCard*)card;
|
|
|
|
this-> card_id = card_id;
|
|
|
|
this->dac_set_state_length = strlen(DAC_SET_STATE_TOPIC);
|
|
|
|
this->dac_set_value_length = strlen(DAC_SET_VALUE_TOPIC);
|
|
|
|
this->dac_state_length = strlen(DAC_STATE_TOPIC);
|
|
|
|
this->dac_value_length = strlen(DAC_VALUE_TOPIC);
|
|
|
|
this->request_state_length = strlen(REQUEST_STATE_TOPIC);
|
|
|
|
this->dac_publish_enable_length = strlen(DAC_PUBLISH_ENABLE_TOPIC);
|
|
|
|
// Register callbacks
|
|
|
|
auto bindedCallback = std::bind(&AnalogIoT::handleDACChange, this, std::placeholders::_1, std::placeholders::_2);
|
|
|
|
this->card->registerDACChangeCallback(bindedCallback);
|
|
|
|
return true;
|
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Publishes the state of all DACs.
|
|
|
|
* @note This function is called when a request state message is received.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
void AnalogIoT::handleMqttMessage(char *topic, char *payload){
|
|
|
|
uint8_t topic_length = strlen(topic);
|
|
|
|
if(this-> processDACSetStateMessage(topic, payload, topic_length)) return;
|
|
|
|
if(this-> processDACSetValueMessage(topic, payload, topic_length)) return;
|
|
|
|
if(this-> processRequestStateMessage(topic, payload, topic_length)) return;
|
|
|
|
if(this-> processADCSetConversionIntervalMessage(topic, payload, topic_length)) return;
|
|
|
|
if(this-> processADCSetConversionEnabledMessage(topic, payload, topic_length)) return;
|
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Publishes the state of all DACs.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
void AnalogIoT::publishADCs() {
|
|
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
|
|
this->publishADC(i);
|
|
|
|
}
|
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Publishes the state of a DAC.
|
|
|
|
* @param pin The pin of the DAC.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
void AnalogIoT::publishADC(uint8_t pin) {
|
|
|
|
if (this->adc_publish_enabled[pin]) {
|
|
|
|
uint16_t value = this->card->analogRead(pin);
|
|
|
|
char *topic = new char[15];
|
|
|
|
sprintf(topic, "adc/%02d/value", pin);
|
|
|
|
char *payload = new char[10];
|
|
|
|
sprintf(payload, "%d", value);
|
|
|
|
this->publishRelative(topic, payload);
|
|
|
|
delete[] topic;
|
|
|
|
delete[] payload;
|
2023-12-29 17:49:09 +00:00
|
|
|
// Call all callbacks
|
2023-12-31 06:29:11 +00:00
|
|
|
for (auto& callback : this->adc_conversion_callbacks) {
|
|
|
|
callback.second(pin, value);
|
2023-12-29 17:49:09 +00:00
|
|
|
}
|
2023-12-28 17:39:11 +00:00
|
|
|
}
|
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Sets the interval at which the state of all DACs is published.
|
|
|
|
* @param interval The interval in milliseconds.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
void AnalogIoT::setADCsPublishInterval(uint32_t interval) {
|
|
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
|
|
adc_conversion_interval[i] = interval;
|
|
|
|
}
|
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Sets whether the state of all DACs is published.
|
|
|
|
* @param enabled True if the state of all DACs should be published, false otherwise.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
void AnalogIoT::setADCsPublishEnabled(bool enabled) {
|
|
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
|
|
adc_publish_enabled[i] = enabled;
|
|
|
|
}
|
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Registers a callback for handling ADC conversions.
|
|
|
|
* @param callback The callback function.
|
|
|
|
* @return The handler of the callback.
|
|
|
|
*/
|
2023-12-31 06:32:38 +00:00
|
|
|
uint8_t AnalogIoT::registerADCConversionCallback(std::function<void(uint8_t, uint16_t)> callback) {
|
|
|
|
this->adc_conversion_callbacks[this->adc_conversion_callback_index] = callback;
|
|
|
|
return this->adc_conversion_callback_index++;
|
2023-12-31 06:29:11 +00:00
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Unregisters a callback for handling ADC conversions.
|
|
|
|
* @param handler The handler of the callback.
|
|
|
|
*/
|
2023-12-31 06:41:48 +00:00
|
|
|
void AnalogIoT::unregisterADCConversionCallback(uint8_t handler) {
|
2023-12-31 06:29:11 +00:00
|
|
|
this->adc_conversion_callbacks.erase(handler);
|
2023-12-28 17:39:11 +00:00
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Sets the interval at which the value of an ADC channel is read.
|
|
|
|
* @param pin The pin of the ADC channel.
|
|
|
|
* @param interval The interval in milliseconds.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
void AnalogIoT::setADCConversionInterval(uint8_t pin, uint16_t interval) {
|
|
|
|
adc_conversion_interval[pin] = interval;
|
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Enables or disables the periodic reading of the value of an ADC channel.
|
|
|
|
* @param pin The pin of the ADC channel.
|
|
|
|
* @param enabled True if the value of the ADC channel should be read, false otherwise.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
void AnalogIoT::setADCConversionEnabled(uint8_t pin, bool enabled) {
|
|
|
|
adc_publish_enabled[pin] = enabled;
|
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Processes a message received on the MQTT topic for setting the state of a DAC.
|
|
|
|
* @param topic The topic of the message.
|
|
|
|
* @param payload The payload of the message.
|
|
|
|
* @param topic_length The length of the topic.
|
|
|
|
* @note This function is not meant to be called from user code.
|
|
|
|
* @return True if the message was processed, false otherwise.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
bool AnalogIoT::processADCSetConversionIntervalMessage(char *topic, char *payload, uint8_t topic_length) {
|
2023-12-28 17:48:43 +00:00
|
|
|
// TODO: Process payload matching the criteria
|
|
|
|
// Topic: adc/<%02d>/set/conversion_interval
|
|
|
|
// The first 4 characters are "adc/"
|
|
|
|
// The length of the topic must be 30 characters
|
|
|
|
// The last 24 characters must be "/set/conversion_interval"
|
|
|
|
// After all these conditions are met, the topic is valid
|
|
|
|
// Extract the pin number from the topic
|
|
|
|
if (topic_length != 30) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (strncmp(topic, "adc/", 4)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (strncmp(topic + 26, "/set/conversion_interval", 24)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
uint8_t pin = (topic[4] - '0') * 10 + (topic[5] - '0');
|
|
|
|
// Extract the payload
|
|
|
|
uint16_t interval = atoi(payload);
|
|
|
|
// Set the interval
|
|
|
|
this->setADCConversionInterval(pin, interval);
|
|
|
|
return true;
|
2023-12-28 17:39:11 +00:00
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Processes a message received on the MQTT topic for setting the value of a DAC.
|
|
|
|
* @param topic The topic of the message.
|
|
|
|
* @param payload The payload of the message.
|
|
|
|
* @param topic_length The length of the topic.
|
|
|
|
* @note This function is not meant to be called from user code.
|
|
|
|
* @return True if the message was processed, false otherwise.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
bool AnalogIoT::processADCSetConversionEnabledMessage(char *topic, char *payload, uint8_t topic_length) {
|
2023-12-28 17:48:43 +00:00
|
|
|
// Topic: adc/<%02d>/set/conversion_enabled
|
|
|
|
// The first 4 characters are "adc/"
|
|
|
|
// The length of the topic must be 29 characters
|
|
|
|
// The last 23 characters must be ""/set/conversion_enabled
|
|
|
|
// After all these conditions are met, the topic is valid
|
|
|
|
// Extract the pin number from the topic
|
|
|
|
if (topic_length != 29) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (strncmp(topic, "adc/", 4)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (strncmp(topic + 25, "/set/conversion_enabled", 23)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
uint8_t pin = (topic[4] - '0') * 10 + (topic[5] - '0');
|
|
|
|
// Extract the payload
|
|
|
|
bool enabled = atoi(payload);
|
|
|
|
// Set conversion enabled
|
|
|
|
this->setADCConversionEnabled(pin, enabled);
|
|
|
|
return true;
|
2023-12-28 17:39:11 +00:00
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Processes a message received on the MQTT topic for setting the state of a DAC.
|
|
|
|
* @param topic The topic of the message.
|
|
|
|
* @param payload The payload of the message.
|
|
|
|
* @param topic_length The length of the topic.
|
|
|
|
* @note This function is not meant to be called from user code.
|
|
|
|
* @return True if the message was processed, false otherwise.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
bool AnalogIoT::processDACSetStateMessage(char *topic, char *payload, uint8_t topic_length) {
|
2023-12-28 17:48:43 +00:00
|
|
|
// Topic: dac/<%02d>/set/state
|
|
|
|
// The first 4 characters are "dac/"
|
|
|
|
// The length of the topic must be 16 characters
|
|
|
|
// The last 10 characters must be "/set/state"
|
|
|
|
// After all these conditions are met, the topic is valid
|
|
|
|
// Extract the pin number from the topic
|
|
|
|
if (topic_length != 16) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (strncmp(topic, "dac/", 4)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (strncmp(topic + 12, "/set/state", 10)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
uint8_t pin = (topic[4] - '0') * 10 + (topic[5] - '0');
|
|
|
|
// Extract the payload
|
|
|
|
bool state = atoi(payload);
|
|
|
|
// Set the state
|
|
|
|
this->card->setDACState(pin, state);
|
|
|
|
return true;
|
2023-12-28 17:39:11 +00:00
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Processes a message received on the MQTT topic for setting the value of a DAC.
|
|
|
|
* @param topic The topic of the message.
|
|
|
|
* @param payload The payload of the message.
|
|
|
|
* @param topic_length The length of the topic.
|
|
|
|
* @note This function is not meant to be called from user code.
|
|
|
|
* @return True if the message was processed, false otherwise.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
bool AnalogIoT::processDACSetValueMessage(char *topic, char *payload, uint8_t topic_length) {
|
2023-12-28 17:48:43 +00:00
|
|
|
// Topic: dac/<%02d>/set/value
|
|
|
|
// The first 4 characters are "dac/"
|
|
|
|
// The length of the topic must be 16 characters
|
|
|
|
// The last 10 characters must be "/set/value"
|
|
|
|
// After all these conditions are met, the topic is valid
|
|
|
|
// Extract the pin number from the topic
|
|
|
|
if (topic_length != 16) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (strncmp(topic, "dac/", 4)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (strncmp(topic + 12, "/set/value", 10)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
uint8_t pin = (topic[4] - '0') * 10 + (topic[5] - '0');
|
|
|
|
// Extract the payload
|
|
|
|
uint16_t value = atoi(payload);
|
|
|
|
// Set the value
|
|
|
|
this->card->setDACValue(pin, value);
|
|
|
|
return true;
|
2023-12-28 17:39:11 +00:00
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Processes a message received on the MQTT topic for requesting the state of all DACs.
|
|
|
|
* @param topic The topic of the message.
|
|
|
|
* @param payload The payload of the message.
|
|
|
|
* @param topic_length The length of the topic.
|
|
|
|
* @note This function is not meant to be called from user code.
|
|
|
|
* @return True if the message was processed, false otherwise.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
bool AnalogIoT::processRequestStateMessage(char *topic, char *payload, uint8_t topic_length) {
|
2023-12-28 17:48:43 +00:00
|
|
|
// Topic: requeststate
|
|
|
|
// The length of the topic must be 12 characters
|
|
|
|
// After all these conditions are met, the topic is valid
|
|
|
|
if (topic_length != 12) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (strncmp(topic, REQUEST_STATE_TOPIC, 12)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// Publish the state of all DACs
|
|
|
|
this->publishDACs();
|
|
|
|
// Publish the state of all ADCs
|
|
|
|
this->publishADCs();
|
|
|
|
return false;
|
2023-12-28 17:39:11 +00:00
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Subscribes to all MQTT topics used by the AnalogIoT object.
|
|
|
|
* @note This function is called when the MQTT client connects.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
void AnalogIoT::subscribe() {
|
|
|
|
// There are 4 DACs and 8 ADCs
|
|
|
|
// DACs: dac/<%02d>/set/state, dac/<%02d>/set/value, dac/publish_enable
|
|
|
|
// ADCs: adc/<%02d>/set/conversion_interval, adc/<%02d>/set/conversion_enabled
|
|
|
|
|
|
|
|
// Subscribe to all set state topics
|
|
|
|
char topic[20];
|
|
|
|
for (uint8_t i = 0; i < 4; i++) {
|
|
|
|
sprintf(topic, "dac/%02d/set/state", i);
|
|
|
|
this->subscribeRelative(topic);
|
|
|
|
}
|
|
|
|
// Subscribe to all set value topics
|
|
|
|
for (uint8_t i = 0; i < 4; i++) {
|
|
|
|
sprintf(topic, "dac/%02d/set/value", i);
|
|
|
|
this->subscribeRelative(topic);
|
|
|
|
}
|
|
|
|
// Subscribe to all set conversion interval topics
|
|
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
|
|
sprintf(topic, "adc/%02d/set/conversion_interval", i);
|
|
|
|
this->subscribeRelative(topic);
|
|
|
|
}
|
|
|
|
// Subscribe to all set conversion enabled topics
|
|
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
|
|
sprintf(topic, "adc/%02d/set/conversion_enabled", i);
|
|
|
|
this->subscribeRelative(topic);
|
|
|
|
}
|
|
|
|
// Subscribe to publish enable topic
|
|
|
|
this->subscribeRelative("dac/publish_enable");
|
|
|
|
}
|
|
|
|
void AnalogIoT::loop() {
|
|
|
|
// Iterate over all ADCs and publish if enabled and interval has passed
|
|
|
|
uint32_t now = millis();
|
|
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
|
|
if (this->adc_publish_enabled[i] && now - this->last_adc_publish > this->adc_conversion_interval[i]) {
|
|
|
|
this->publishADC(i);
|
|
|
|
this->last_adc_publish = now;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Publishes the state of all DACs.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
void AnalogIoT::publishReport() {
|
|
|
|
publishADCs();
|
|
|
|
publishDACs();
|
|
|
|
}
|
|
|
|
|
2023-12-31 18:38:25 +00:00
|
|
|
/**
|
|
|
|
* @brief Gets the type of the card.
|
|
|
|
* @return The type of the card.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
uint8_t AnalogIoT::getType() {
|
|
|
|
return CARD_TYPE_ANALOG;
|
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Publishes the state of all DACs.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
void AnalogIoT::publishDACs() {
|
|
|
|
for (uint8_t i = 0; i < 4; i++) {
|
|
|
|
this->publishDAC(i);
|
|
|
|
}
|
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Publishes the state of a DAC.
|
|
|
|
* @param pin The pin of the DAC.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
void AnalogIoT::publishDAC(uint8_t pin) {
|
|
|
|
this->publishDACState(pin);
|
|
|
|
this->publishDACValue(pin);
|
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Publishes the state of a DAC.
|
|
|
|
* @param pin The pin of the DAC.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
void AnalogIoT::publishDACState(uint8_t pin) {
|
|
|
|
char *topic = new char[15];
|
|
|
|
sprintf(topic, "dac/%02d/state", pin);
|
|
|
|
char *payload = new char[2];
|
|
|
|
sprintf(payload, "%d", this->card->getDACState(pin));
|
|
|
|
this->publishRelative(topic, payload);
|
|
|
|
delete[] topic;
|
|
|
|
delete[] payload;
|
|
|
|
}
|
2023-12-31 18:38:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Publishes the value of a DAC.
|
|
|
|
* @param pin The pin of the DAC.
|
|
|
|
*/
|
2023-12-28 17:39:11 +00:00
|
|
|
void AnalogIoT::publishDACValue(uint8_t pin) {
|
|
|
|
char *topic = new char[15];
|
|
|
|
sprintf(topic, "dac/%02d/value", pin);
|
|
|
|
char *payload = new char[5];
|
|
|
|
sprintf(payload, "%d", this->card->getDACValue(pin));
|
|
|
|
this->publishRelative(topic, payload);
|
|
|
|
delete[] topic;
|
|
|
|
delete[] payload;
|
|
|
|
}
|
2023-12-30 07:42:52 +00:00
|
|
|
|
2023-12-31 18:38:25 +00:00
|
|
|
/**
|
|
|
|
* @brief Publishes the state of a DAC.
|
|
|
|
* @param pin The pin of the DAC.
|
|
|
|
*/
|
2023-12-30 07:42:52 +00:00
|
|
|
void AnalogIoT::handleDACChange(uint8_t pin, uint16_t value) {
|
|
|
|
this->publishDAC(pin);
|
|
|
|
}
|