initial analog card OOP draft
This commit is contained in:
parent
75aa6f490b
commit
ec7b7f2510
|
@ -10,6 +10,47 @@ AnalogCard::AnalogCard() : dac0(DAC0_ADDRESS),
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnalogCard::dacWrite(uint8_t pin, uint16_t value)
|
void AnalogCard::dacWrite(uint8_t pin, uint16_t value)
|
||||||
|
{
|
||||||
|
this->setDACState(pin, value > 0);
|
||||||
|
this->setDACValue(pin, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalogCard::setDACState(uint8_t pin, bool state)
|
||||||
|
{
|
||||||
|
this->dac_state[pin] = state;
|
||||||
|
this->sendDataToDAC(pin, this->dac_value[pin]*state);
|
||||||
|
if (this->dac_change_callback != NULL)
|
||||||
|
{
|
||||||
|
this->dac_change_callback(pin, state, this->dac_value[pin]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalogCard::setDACValue(uint8_t pin, uint16_t value)
|
||||||
|
{
|
||||||
|
this->dac_value[pin] = value;
|
||||||
|
this->sendDataToDAC(pin, value*this->dac_state[pin]);
|
||||||
|
if (this->dac_change_callback != NULL)
|
||||||
|
{
|
||||||
|
this->dac_change_callback(pin, this->dac_state[pin], value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t AnalogCard::getDACValue(uint8_t pin)
|
||||||
|
{
|
||||||
|
return this->dac_value[pin];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AnalogCard::getDACState(uint8_t pin)
|
||||||
|
{
|
||||||
|
return this->dac_state[pin];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t AnalogCard::getDACValue(uint8_t pin)
|
||||||
|
{
|
||||||
|
return this->dac_value[pin];
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalogCard::sendDataToDAC(uint8_t pin, uint16_t value)
|
||||||
{
|
{
|
||||||
switch (pin)
|
switch (pin)
|
||||||
{
|
{
|
||||||
|
@ -85,4 +126,14 @@ void AnalogCard::loop()
|
||||||
uint8_t AnalogCard::getType()
|
uint8_t AnalogCard::getType()
|
||||||
{
|
{
|
||||||
return CARD_TYPE_ANALOG;
|
return CARD_TYPE_ANALOG;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalogCard::registerDACChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback)
|
||||||
|
{
|
||||||
|
this->dac_change_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalogCard::deregisterDACChangeCallback()
|
||||||
|
{
|
||||||
|
this->dac_change_callback = NULL;
|
||||||
}
|
}
|
|
@ -16,11 +16,21 @@ class AnalogCard : public ExpansionCard {
|
||||||
public:
|
public:
|
||||||
AnalogCard();
|
AnalogCard();
|
||||||
void dacWrite(uint8_t pin, uint16_t value);
|
void dacWrite(uint8_t pin, uint16_t value);
|
||||||
|
void sendDataToDAC(uint8_t pin, uint16_t value);
|
||||||
uint16_t analogRead(uint8_t pin);
|
uint16_t analogRead(uint8_t pin);
|
||||||
bool begin();
|
bool begin();
|
||||||
void loop();
|
void loop();
|
||||||
|
bool getDACState(uint8_t pin);
|
||||||
|
uint16_t getDACValue(uint8_t pin);
|
||||||
|
void setDACState(uint8_t pin, bool state);
|
||||||
|
void setDACValue(uint8_t pin, uint16_t value);
|
||||||
|
void registerDACChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback);
|
||||||
|
void deregisterDACChangeCallback();
|
||||||
uint8_t getType();
|
uint8_t getType();
|
||||||
private:
|
private:
|
||||||
|
std::function<void(uint8_t, bool, uint16_t)> dac_change_callback;
|
||||||
|
bool dac_state[4];
|
||||||
|
uint16_t dac_value[4];
|
||||||
MCP4725 dac0;
|
MCP4725 dac0;
|
||||||
MCP4725 dac1;
|
MCP4725 dac1;
|
||||||
MCP4725 dac2;
|
MCP4725 dac2;
|
||||||
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
#include <AnalogIoT.hpp>
|
||||||
|
|
||||||
|
AnalogIoT::AnalogIoT() {
|
||||||
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
|
adc_publish_enabled[i] = false;
|
||||||
|
adc_conversion_interval[i] = 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AnalogIoT::~AnalogIoT() {
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
void AnalogIoT::publishADCs() {
|
||||||
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
|
this->publishADC(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void AnalogIoT::setADCsPublishInterval(uint32_t interval) {
|
||||||
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
|
adc_conversion_interval[i] = interval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void AnalogIoT::setADCsPublishEnabled(bool enabled) {
|
||||||
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
|
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) {
|
||||||
|
adc_conversion_callback = callback;
|
||||||
|
}
|
||||||
|
void AnalogIoT::deregisterADCConversionCallback() {
|
||||||
|
adc_conversion_callback = NULL;
|
||||||
|
}
|
||||||
|
void AnalogIoT::setADCConversionInterval(uint8_t pin, uint16_t interval) {
|
||||||
|
adc_conversion_interval[pin] = interval;
|
||||||
|
}
|
||||||
|
void AnalogIoT::setADCConversionEnabled(uint8_t pin, bool enabled) {
|
||||||
|
adc_publish_enabled[pin] = enabled;
|
||||||
|
}
|
||||||
|
bool AnalogIoT::processADCSetConversionIntervalMessage(char *topic, char *payload, uint8_t topic_length) {
|
||||||
|
// TODO: publish all DACs and ADCs
|
||||||
|
}
|
||||||
|
bool AnalogIoT::processADCSetConversionEnabledMessage(char *topic, char *payload, uint8_t topic_length) {
|
||||||
|
// TODO: publish all DACs and ADCs
|
||||||
|
}
|
||||||
|
bool AnalogIoT::processDACSetStateMessage(char *topic, char *payload, uint8_t topic_length) {
|
||||||
|
// TODO: publish all DACs and ADCs
|
||||||
|
}
|
||||||
|
bool AnalogIoT::processDACSetValueMessage(char *topic, char *payload, uint8_t topic_length) {
|
||||||
|
// TODO: publish all DACs and ADCs
|
||||||
|
}
|
||||||
|
bool AnalogIoT::processRequestStateMessage(char *topic, char *payload, uint8_t topic_length) {
|
||||||
|
// TODO: publish all DACs and ADCs
|
||||||
|
}
|
||||||
|
void AnalogIoT::publishReport() {
|
||||||
|
// TODO: publish all DACs and ADCs
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void AnalogIoT::publishReport() {
|
||||||
|
publishADCs();
|
||||||
|
publishDACs();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t AnalogIoT::getType() {
|
||||||
|
return CARD_TYPE_ANALOG;
|
||||||
|
}
|
||||||
|
void AnalogIoT::publishDACs() {
|
||||||
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
|
this->publishDAC(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void AnalogIoT::publishDAC(uint8_t pin) {
|
||||||
|
this->publishDACState(pin);
|
||||||
|
this->publishDACValue(pin);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
|
@ -1,23 +1,58 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <IoTComponent.hpp>
|
#include <IoTComponent.hpp>
|
||||||
#include <AnalogCard.hpp>
|
#include <AnalogCard.hpp>
|
||||||
|
|
||||||
|
#define DAC_SET_STATE_TOPIC "/set/state"
|
||||||
|
#define DAC_SET_VALUE_TOPIC "/set/value"
|
||||||
|
#define DAC_STATE_TOPIC "/dac/00/state"
|
||||||
|
#define DAC_VALUE_TOPIC "/dac/00/value"
|
||||||
|
#define DAC_PUBLISH_ENABLE_TOPIC "/publish_enable"
|
||||||
|
#define REQUEST_STATE_TOPIC "requeststate"
|
||||||
|
|
||||||
class AnalogIoT : public IoTComponent {
|
class AnalogIoT : public IoTComponent {
|
||||||
public:
|
public:
|
||||||
AnalogIoT();
|
AnalogIoT();
|
||||||
~AnalogIoT();
|
~AnalogIoT();
|
||||||
bool begin(uint8_t card_id, AnalogCard *card, PubSubClient *mqtt, char *base_topic);
|
bool begin(uint8_t card_id, ExpansionCard *card, PubSubClient *mqtt, char *base_topic);
|
||||||
void handleMqttMessage(char *topic, char *payload);
|
void handleMqttMessage(char *topic, char *payload);
|
||||||
|
void handleDACChange(uint8_t pin, uint16_t value);
|
||||||
void publishADCs();
|
void publishADCs();
|
||||||
|
void publishADC(uint8_t pin);
|
||||||
|
void publishDACs();
|
||||||
|
void publishDAC(uint8_t pin);
|
||||||
|
void publishDACState(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 deregisterADCConversionCallback();
|
||||||
|
void setADCConversionInterval(uint8_t pin, uint16_t interval);
|
||||||
|
void setADCConversionEnabled(uint8_t pin, bool enabled);
|
||||||
|
bool processADCSetConversionIntervalMessage(char *topic, char *payload, uint8_t topic_length);
|
||||||
|
bool processADCSetConversionEnabledMessage(char *topic, char *payload, uint8_t topic_length);
|
||||||
|
bool processDACSetStateMessage(char *topic, char *payload, uint8_t topic_length);
|
||||||
|
bool processDACSetValueMessage(char *topic, char *payload, uint8_t topic_length);
|
||||||
|
bool processRequestStateMessage(char *topic, char *payload, uint8_t topic_length);
|
||||||
|
void publishReport();
|
||||||
|
void subscribe();
|
||||||
|
void loop();
|
||||||
void publishReport();
|
void publishReport();
|
||||||
void subscribe();
|
void subscribe();
|
||||||
uint8_t getType();
|
uint8_t getType();
|
||||||
private:
|
private:
|
||||||
char *adc_topic;
|
uint8_t dac_set_state_length;
|
||||||
char *dac_topic;
|
uint8_t dac_set_value_length;
|
||||||
uint32_t adc_publish_interval = 1000;
|
uint8_t dac_state_length;
|
||||||
|
uint8_t dac_value_length;
|
||||||
|
uint8_t request_state_length;
|
||||||
|
uint8_t dac_publish_enable_length;
|
||||||
uint32_t last_adc_publish = 0;
|
uint32_t last_adc_publish = 0;
|
||||||
bool adc_publish_enabled = false;
|
|
||||||
AnalogCard *card;
|
AnalogCard *card;
|
||||||
|
bool adc_publish_enabled[8];
|
||||||
|
uint16_t adc_conversion_interval[8];
|
||||||
|
uint32_t last_adc_conversion[8];
|
||||||
|
std::function<void(uint8_t, uint16_t)> dac_change_callback;
|
||||||
|
std::function<void(uint8_t, uint16_t)> adc_conversion_callback;
|
||||||
};
|
};
|
|
@ -15,7 +15,6 @@ bool DigitalOutputIoT::begin(uint8_t card_id, ExpansionCard *card, PubSubClient
|
||||||
this->mqtt = mqtt;
|
this->mqtt = mqtt;
|
||||||
this->base_topic = base_topic;
|
this->base_topic = base_topic;
|
||||||
this->card = (DigitalOutputCard *) card;
|
this->card = (DigitalOutputCard *) card;
|
||||||
if(!card->begin()) return false;
|
|
||||||
this-> card_id = card_id;
|
this-> card_id = card_id;
|
||||||
this->set_state_length = strlen(SET_STATE_TOPIC);
|
this->set_state_length = strlen(SET_STATE_TOPIC);
|
||||||
this->set_value_length = strlen(SET_VALUE_TOPIC);
|
this->set_value_length = strlen(SET_VALUE_TOPIC);
|
||||||
|
|
Loading…
Reference in New Issue