diff --git a/lib/GPIO/BUZZER_Driver.cpp b/lib/GPIO/BUZZER_Driver.cpp index 4cd7642..befb4d8 100644 --- a/lib/GPIO/BUZZER_Driver.cpp +++ b/lib/GPIO/BUZZER_Driver.cpp @@ -10,18 +10,18 @@ namespace drivers Buzzer::Buzzer() { LOG_INFO("Initializing Beeper"); - pinMode(buzzerPin, OUTPUT); - ledcAttach(buzzerPin, 1000, 8); - m_bp.pin = buzzerPin; + pinMode(c_buzzerPin, OUTPUT); + ledcAttach(c_buzzerPin, 1000, 8); + m_bp.pin = c_buzzerPin; m_bp.beeperTask = NULL; - //beep(50, NOTE_G); + beep(50, NOTE_G); } Buzzer::~Buzzer() { beepStop(); - ledcDetach(buzzerPin); - pinMode(buzzerPin, INPUT); + ledcDetach(c_buzzerPin); + pinMode(c_buzzerPin, INPUT); } void Buzzer::beep(const uint16_t tBeep, const note_t note) @@ -57,11 +57,11 @@ namespace drivers while (true) { ledcWriteNote(bPar->pin, bPar->note, OCTAVE); // on with selected note - vTaskDelay(pdMS_TO_TICKS(bPar->tOn)); + delay(bPar->tOn); ledcWriteTone(bPar->pin, 0); // off if (bPar->tOff == 0) break; - vTaskDelay(pdMS_TO_TICKS(bPar->tOff)); + delay(bPar->tOff); } LOG_DEBUG("Beeper Task Ended"); bPar->beeperTask = NULL; diff --git a/lib/GPIO/BUZZER_Driver.h b/lib/GPIO/BUZZER_Driver.h index af6f86d..b0e7d21 100644 --- a/lib/GPIO/BUZZER_Driver.h +++ b/lib/GPIO/BUZZER_Driver.h @@ -10,7 +10,8 @@ namespace drivers class Buzzer { - const uint8_t buzzerPin = 46; // hardware assigned + const uint8_t c_buzzerPin = 46; // hardware assigned + typedef struct { note_t note; diff --git a/lib/GPIO/LED_Driver.cpp b/lib/GPIO/LED_Driver.cpp index 1d4a4bd..cd23eec 100644 --- a/lib/GPIO/LED_Driver.cpp +++ b/lib/GPIO/LED_Driver.cpp @@ -9,21 +9,21 @@ namespace drivers Led::Led() { LOG_INFO("Inizializing RGB Led"); - pinMode(ledPin, OUTPUT); - m_lp.pin = ledPin; + pinMode(c_ledPin, OUTPUT); + m_lp.pin = c_ledPin; m_lp.blinkTask = NULL; } Led::~Led() { setColor({0, 0, 0}); - pinMode(ledPin, INPUT); + pinMode(c_ledPin, INPUT); } void Led::setColor(const color_t color) { blinkStop(); - rgbLedWrite(ledPin, color.r, color.g, color.b); + rgbLedWrite(c_ledPin, color.r, color.g, color.b); } void Led::blinkColor(const uint16_t tOn, const uint16_t tOff, const color_t color) @@ -62,11 +62,11 @@ namespace drivers while (true) { rgbLedWrite(lPar->pin, lPar->color1.g, lPar->color1.r, lPar->color1.b); - vTaskDelay(pdMS_TO_TICKS(lPar->tOn)); + delay(lPar->tOn); rgbLedWrite(lPar->pin, lPar->color2.g, lPar->color2.r, lPar->color2.b); // off if (lPar->tOff == 0) break; - vTaskDelay(pdMS_TO_TICKS(lPar->tOff)); + delay(lPar->tOff); } LOG_DEBUG("Blinker Task Ended"); lPar->blinkTask = NULL; diff --git a/lib/GPIO/LED_Driver.h b/lib/GPIO/LED_Driver.h index ddcf3c9..6a86c26 100644 --- a/lib/GPIO/LED_Driver.h +++ b/lib/GPIO/LED_Driver.h @@ -10,7 +10,7 @@ namespace drivers class Led { - const uint8_t ledPin = 38; + const uint8_t c_ledPin = 38; public: typedef struct diff --git a/lib/RS485/RS485_Driver.cpp b/lib/RS485/RS485_Driver.cpp index 36793c9..9230b46 100644 --- a/lib/RS485/RS485_Driver.cpp +++ b/lib/RS485/RS485_Driver.cpp @@ -65,68 +65,89 @@ namespace drivers readAll(garbage); LOG_INFO("Init MODBUS Master Mode"); m_crc.reset(CRC16_MODBUS_POLYNOME, CRC16_MODBUS_INITIAL, CRC16_MODBUS_XOR_OUT, CRC16_MODBUS_REV_IN, CRC16_MAXIM_REV_OUT); + m_lastAccess = millis(); } + void MODBUS::delayAccess(const uint8_t device) + { + if (device == m_lastDevice) return; + auto now = millis(); + if ((now - m_lastAccess) < c_minDelay) // fixed 10 milliseconds delay between commands + { // minimum m_lastRequest between requests + delay(now - m_lastAccess); + } + m_lastAccess = now; + m_lastDevice = device; + } + // Func 0x01 const bool MODBUS::readCoils(const uint8_t device, const uint16_t reg, const uint16_t num, std::vector &coils) { constexpr uint8_t func = 0x01; + delayAccess(device); LOG_DEBUG("Read coils: dev[", device, "], reg[", reg, "], num[", num, "]"); return readBinary(device, func, reg, num, coils); } - + // Func 0x02 const bool MODBUS::readInputs(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector &inputs) { constexpr uint8_t func = 0x02; + delayAccess(device); LOG_DEBUG("Read multi inputs: dev[", device, "], reg[", reg, "], num[", num, "]"); return readBinary(device, func, reg, num, inputs); } - + // Func 0x03 const bool MODBUS::readHoldingRegisters(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector &values) { constexpr uint8_t func = 0x03; + delayAccess(device); LOG_DEBUG("Read multi holding registers: dev[", device, "], reg[", reg, "], num[", num, "]"); return readInteger(device, func, reg, num, values); } - + // Func 0x04 const bool MODBUS::readInputRegisters(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector &values) { constexpr uint8_t func = 0x04; + delayAccess(device); LOG_DEBUG("Read multi input registers: dev[", device, "], reg[", reg, "], num[", num, "]"); return readInteger(device, func, reg, num, values); } - + // Func 0x05 const bool MODBUS::writeCoil(const uint8_t device, const uint16_t coil, const bool value) { constexpr uint8_t func = 0x05; + delayAccess(device); LOG_DEBUG("Write single coil: dev[", device, "], coil[", coil, "], value[", value ? "true" : "false", "]"); return writeBinary(device, func, coil, {value}); } - + // Func 0x06 const bool MODBUS::writeRegister(const uint8_t device, const uint16_t reg, const uint16_t value) { constexpr uint8_t func = 0x06; + delayAccess(device); LOG_DEBUG("Write single register: dev[", device, "], reg[", reg, "], value[", value, "]"); return writeInteger(device, func, reg, {value}, false); } - + // Func 0x0F const bool MODBUS::writeCoils(const uint8_t device, const uint16_t coils, const std::vector &values) { constexpr uint8_t func = 0x0F; + delayAccess(device); LOG_DEBUG("Write multi coils: dev[", device, "], start[", coils, "], num[", values.size(), "]"); return writeBinary(device, func, coils, values); } - + // Func 0x10 const bool MODBUS::writeRegisters(const uint8_t device, const uint16_t reg, const std::vector &values) { constexpr uint8_t func = 0x10; + delayAccess(device); LOG_DEBUG("Write multi registers: dev[", device, "], start[", reg, "], num[", values.size(), "]"); return writeInteger(device, func, reg, values, true); } @@ -143,7 +164,7 @@ namespace drivers return false; } const uint16_t nRespDataBytes = (uint16_t)ceil(bits / 8.0f); // 1 bit for every coil, if not 8 mutiple padded with zeroes - const uint16_t expectedRespLen = (RESP_HEADER_SIZE + RESP_CRC_SIZE) + nRespDataBytes; // device + function + nbytes + data[] + crc(16b) + const uint16_t expectedRespLen = (c_respHeaderSize + c_respCrcSize) + nRespDataBytes; // device + function + nbytes + data[] + crc(16b) std::vector response; if (!readN(expectedRespLen, response)) { @@ -172,7 +193,7 @@ namespace drivers uint16_t bitNum(0); // get response data bytes excluding header and crc - const std::vector respData(response.begin() + RESP_HEADER_SIZE, response.end() - sizeof(crc_t)); + const std::vector respData(response.begin() + c_respHeaderSize, response.end() - sizeof(crc_t)); for (auto it = respData.begin(); it < respData.end(); it++) { for (uint8_t j(0); j < 8 && bitNum < bits; j++) @@ -193,7 +214,7 @@ namespace drivers return false; } const uint16_t nRespDataBytes = num * sizeof(uint16_t); - const uint16_t expectedRespLen = (RESP_HEADER_SIZE + sizeof(crc_t)) + nRespDataBytes; // device + function + nbytes + data[] + crc(16b) + const uint16_t expectedRespLen = (c_respHeaderSize + sizeof(crc_t)) + nRespDataBytes; // device + function + nbytes + data[] + crc(16b) std::vector response; if (!readN(expectedRespLen, response)) { @@ -220,7 +241,7 @@ namespace drivers out.clear(); out.reserve(nRespDataBytes / sizeof(uint16_t)); // get response data bytes excluding header and crc - const std::vector respData(response.begin() + RESP_HEADER_SIZE, response.end() - RESP_CRC_SIZE); + const std::vector respData(response.begin() + c_respHeaderSize, response.end() - c_respCrcSize); for (auto it = respData.begin(); it < respData.end(); it++) { const uint8_t lo(*it++); diff --git a/lib/RS485/RS485_Driver.h b/lib/RS485/RS485_Driver.h index 4e96fbe..0fee522 100644 --- a/lib/RS485/RS485_Driver.h +++ b/lib/RS485/RS485_Driver.h @@ -13,7 +13,7 @@ namespace drivers { class RS485 { - static const uint8_t PORT = 1; + const uint8_t c_port = 1; public: RS485(const uint32_t baud, const SerialConfig conf); @@ -32,8 +32,9 @@ namespace drivers class MODBUS : private RS485 { - static const uint8_t RESP_HEADER_SIZE = 3; - static const uint8_t RESP_CRC_SIZE = 2; + const uint8_t c_respHeaderSize = 3; + const uint8_t c_respCrcSize = 2; + const uint16_t c_minDelay = 50; typedef struct { @@ -92,6 +93,9 @@ namespace drivers private: CRC16 m_crc; std::mutex m_mutex; + uint8_t m_lastDevice; + uint32_t m_lastAccess; + void delayAccess(const uint8_t device); const std::vector singleRequest(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t data); const std::vector multiRequest(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t qty, const std::vector &data); const bool readBinary(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t bits, std::vector &out); diff --git a/lib/RTC/PCF85063_Driver.h b/lib/RTC/PCF85063_Driver.h index 361f62e..b527da6 100644 --- a/lib/RTC/PCF85063_Driver.h +++ b/lib/RTC/PCF85063_Driver.h @@ -63,38 +63,6 @@ #define RTC_TIMER_FLAG (0x08) -typedef struct -{ - uint16_t year; - uint8_t month; - uint8_t day; - uint8_t dotw; - uint8_t hour; - uint8_t minute; - uint8_t second; -} datetime_t; - -const unsigned char MonthStr[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; -const unsigned char Week[7][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; - -extern datetime_t datetime; -void PCF85063_Init(void); -void PCF85063_Reset(void); -void PCF85063Task(void *parameter); - -void PCF85063_Set_Time(datetime_t time); -void PCF85063_Set_Date(datetime_t date); -void PCF85063_Set_All(datetime_t time); - -void PCF85063_Read_Time(datetime_t *time); - -void PCF85063_Enable_Alarm(void); -uint8_t PCF85063_Get_Alarm_Flag(void); -void PCF85063_Set_Alarm(datetime_t time); -void PCF85063_Read_Alarm(datetime_t *time); - -void datetime_to_str(char *datetime_str, datetime_t time); - namespace drivers { diff --git a/lib/SENECA/S50140_Driver.cpp b/lib/SENECA/S50140_Driver.cpp index 1647748..f29b818 100644 --- a/lib/SENECA/S50140_Driver.cpp +++ b/lib/SENECA/S50140_Driver.cpp @@ -9,7 +9,7 @@ namespace drivers S50140::~S50140() { } - + const S50140::powerinfo_t S50140::getAll() { powerinfo_t info{MAXFLOAT}; @@ -24,54 +24,63 @@ namespace drivers info.whPar = getWhPar(); return info; } - + const float_t S50140::getV() { + auto lock = m_bus.getLock(); return readFloatReg(REG_V); } const float_t S50140::getA() { + auto lock = m_bus.getLock(); return readFloatReg(REG_A); } const float_t S50140::getPact() { + auto lock = m_bus.getLock(); return readFloatReg(REG_Pact); } const float_t S50140::getPapp() { + auto lock = m_bus.getLock(); return readFloatReg(REG_Papp); } const float_t S50140::getPrea() { + auto lock = m_bus.getLock(); return readFloatReg(REG_Prea); } const float_t S50140::getPf() { + auto lock = m_bus.getLock(); return readFloatReg(REG_Pf); } const float_t S50140::getF() { + auto lock = m_bus.getLock(); return readFloatReg(REG_Freq); } const float_t S50140::getWhTot() { + auto lock = m_bus.getLock(); return readFloatReg(REG_WhTot); } const float_t S50140::getWhPar() { + auto lock = m_bus.getLock(); return readFloatReg(REG_WhPart); } - + void S50140::delayRequest() { auto now = millis(); - if ((now - m_lastRequest) < minDelay) + if ((now - m_lastRequest) < c_minDelay) { // minimum m_lastRequest between requests - vTaskDelay(pdMS_TO_TICKS(now - m_lastRequest)); + delay(now - m_lastRequest); } m_lastRequest = now; } - + const uint8_t S50140::getRegset() { std::vector value; @@ -79,7 +88,7 @@ namespace drivers auto lock = m_bus.getLock(); m_bus.readHoldingRegisters(m_address, REG_Regset, 2, value); if (value.empty()) - return UINT8_MAX; + return UINT8_MAX; return value.front() + value.back(); } @@ -101,7 +110,7 @@ namespace drivers constexpr uint16_t resetAll = 0x0A03; constexpr uint16_t stopAll = 0x0A02; constexpr uint16_t startAll = 0x0A01; - while (retries++ < maxRetries) + while (retries++ < c_maxRetries) { bool ok(true); delayRequest(); @@ -126,11 +135,10 @@ namespace drivers uint8_t retries(0); std::vector values; - while (retries++ < maxRetries) + while (retries++ < c_maxRetries) { delayRequest(); - auto lock = m_bus.getLock(); - if (m_bus.readHoldingRegisters(m_address, reg, dataWords, values) && values.size() == dataWords) + if (m_bus.readHoldingRegisters(m_address, reg, c_dataWords, values) && values.size() == c_dataWords) { floatval_t fv; // potrebbe essere il contrario, vedremo fv.words.lo = values[0]; // magari va invertita ancora l'endianness diff --git a/lib/SENECA/S50140_Driver.h b/lib/SENECA/S50140_Driver.h index 810b37e..ec65199 100644 --- a/lib/SENECA/S50140_Driver.h +++ b/lib/SENECA/S50140_Driver.h @@ -11,9 +11,9 @@ namespace drivers class S50140 { private: - const uint8_t maxRetries = 5; - const uint8_t dataWords = 2; - const uint16_t minDelay = 500; + const uint8_t c_maxRetries = 5; + const uint8_t c_dataWords = 2; + const uint16_t c_minDelay = 200; const uint16_t REG_V = 0x100C; const uint16_t REG_A = 0x1016; diff --git a/lib/TEMP/R4DCB08_Driver.cpp b/lib/TEMP/R4DCB08_Driver.cpp index 1dc2b5e..bc3d59d 100644 --- a/lib/TEMP/R4DCB08_Driver.cpp +++ b/lib/TEMP/R4DCB08_Driver.cpp @@ -20,9 +20,9 @@ namespace drivers LOG_ERROR("Invalid Temperature Channel number", ch); return MAXFLOAT; } + auto lock = m_bus.getLock(); while (retries++ < maxRetries) { - auto lock = m_bus.getLock(); if (m_bus.readHoldingRegisters(m_address, REG_TEMP + ch, 1, rawT) && !rawT.empty()) { return rawT.front() / 10.0f; @@ -39,9 +39,9 @@ namespace drivers uint8_t retries(0); std::vector rawT; std::vector out; + auto lock = m_bus.getLock(); while (retries++ < maxRetries) { - auto lock = m_bus.getLock(); if (m_bus.readHoldingRegisters(m_address, REG_TEMP, getNum(), rawT) && !rawT.empty()) { out.reserve(rawT.size()); @@ -65,12 +65,12 @@ namespace drivers uint8_t channel(0); corr.resize(getNum()); // max number of temperature correction values is equal to number of sensors + auto lock = m_bus.getLock(); for (auto v : corr) - { // convert to decimal degreees to register value + { while (retries++ < maxRetries) { - auto lock = m_bus.getLock(); - if (m_bus.writeRegister(m_address, REG_TEMPCORR + channel, v*10)) + if (m_bus.writeRegister(m_address, REG_TEMPCORR + channel, v * 10)) // convert to decimal degreees to register value { channel++; delay(50); @@ -97,7 +97,7 @@ namespace drivers out.reserve(rawV.size()); for (auto v : rawV) { - out.push_back(v/10.0f); + out.push_back(v / 10.0f); } return out; } diff --git a/src/main.cpp b/src/main.cpp index a6edfe3..8ee251c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,10 +1,9 @@ #define DEBUGLOG_DEFAULT_LOG_LEVEL_DEBUG +#include #include #include -#include - #include #include #include @@ -14,8 +13,6 @@ #include #include - -#define DEBUGLOG_DEFAULT_LOG_LEVEL_DEBUG #include #include "utils.h" @@ -34,7 +31,7 @@ void setup() { Serial.begin(9600); LOG_ATTACH_SERIAL(Serial); - conf.init(); // read the configuration from internal flash + conf.init(); // read the configuration from internal flash } void loop() @@ -50,27 +47,26 @@ void loop() auto rtc = drivers::PCF85063(i2c, PCF85063_ADDRESS); auto eth = drivers::Ethernet(conf.m_ethHostname); auto tmp = drivers::R4DCB08(bus, conf.m_modbusTemperatureAddr); - delay(100); - auto io = digitalIO(i2c, bus, {conf.m_modbusRelayAddr}); + // Initialize temperature sensors + sensors = tmp.getNum(); delay(100); auto seneca = drivers::S50140(bus, conf.m_modbusSenecaAddr); auto buzzer = drivers::Buzzer(); auto led = drivers::Led(); - //////////////// DEVICES //////////////// - // Initialize temperature sensors - sensors = tmp.getNum(); + auto io = digitalIO(i2c, bus, {conf.m_modbusRelayAddr}); LOG_INFO("Temperature sensors connected ->", sensors); + //////////////// DEVICES //////////////// //////////////// NETWORK //////////////// auto mqtt = MQTTwrapper(); //////////////// NETWORK //////////////// - std::function mycallback = - [&io](const ArduinoJson::JsonDocument &doc) { - io.digitalIOWrite(0, doc["stat"].as()); - io.digitalIOWrite(15, doc["stat"].as()); - }; - + std::function mycallback = + [&io](const ArduinoJson::JsonDocument &doc) + { + io.digitalIOWrite(0, doc["stat"].as()); + io.digitalIOWrite(15, doc["stat"].as()); + }; //////////////// NETWORK //////////////// /////////////// CALLBACK //////////////// @@ -88,7 +84,7 @@ void loop() { if (eth.getNtpTime(ntpTime) && rtc.setDatetime(drivers::PCF85063::fromEpoch(ntpTime))) { - //buzzer.beep(250, NOTE_F); + // buzzer.beep(250, NOTE_F); led.setColor({255, 255, 0}); const drivers::PCF85063::datetime_t dt(drivers::PCF85063::fromEpoch(ntpTime)); LOG_INFO("NTP Time: ", drivers::PCF85063::datetime2str(dt).c_str()); diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 5fe07cd..45dd28a 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -150,7 +150,7 @@ void MQTTwrapper::clientLoop(void *params) } if (client.state() != MQTT_CONNECTED) { - LOG_ERROR("MQTT disconnect reason ", stateMap.at(client.state())); + LOG_ERROR("MQTT disconnect reason ", stateMap.at(client.state()).c_str()); vTaskDelay(pdMS_TO_TICKS(loopTime * 50)); const bool ok = client.connect(clientName.c_str()); LOG_WARN("MQTT reconnected", ok ? "True" : "False");