From 1ad98799b413d06cf9f2efe222025daa6d1ff3ee Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Sat, 12 Jul 2025 16:11:05 +0200 Subject: [PATCH] Added Temperature board driver --- lib/TEMP/R4DCB08_Driver.cpp | 133 ++++++++++++++++++++++++++++++++++++ lib/TEMP/R4DCB08_Driver.h | 47 +++++++++++++ src/main.cpp | 35 +++++++--- 3 files changed, 204 insertions(+), 11 deletions(-) create mode 100644 lib/TEMP/R4DCB08_Driver.cpp create mode 100644 lib/TEMP/R4DCB08_Driver.h diff --git a/lib/TEMP/R4DCB08_Driver.cpp b/lib/TEMP/R4DCB08_Driver.cpp new file mode 100644 index 0000000..92d2ea0 --- /dev/null +++ b/lib/TEMP/R4DCB08_Driver.cpp @@ -0,0 +1,133 @@ +#include + +namespace drivers +{ + R4DCB08::R4DCB08(drivers::MODBUS &bus, const uint8_t address) : m_address(address), m_bus(bus), m_sensors(0) + { + m_sensors = getNum(); + } + + R4DCB08::~R4DCB08() + { + } + + const float R4DCB08::getTemp(const uint8_t ch) + { + uint8_t retries(0); + std::vector rawT; + if (ch < 0 || ch > getNum()) + { + LOG_ERROR("Invalid Temperature Channel number", ch); + return MAXFLOAT; + } + while (retries++ < maxRetries) + { + if (m_bus.readHoldingRegisters(m_address, REG_TEMP + ch, 1, rawT) && !rawT.empty()) + { + return rawT.front() / 10.0f; + } + LOG_ERROR("Failed to Read Temperature, device", m_address, "channel", ch); + rawT.clear(); + delay(50); + } + return MAXFLOAT; + } + + const std::vector R4DCB08::getTempAll() + { + uint8_t retries(0); + std::vector rawT; + std::vector out; + while (retries++ < maxRetries) + { + if (m_bus.readHoldingRegisters(m_address, REG_TEMP, getNum(), rawT) && !rawT.empty()) + { + out.reserve(rawT.size()); + for (auto v : rawT) + { + out.push_back(v / 10.0f); + } + return out; + } + LOG_ERROR("Failed to Read All Temperature, device", m_address); + rawT.clear(); + delay(50); + } + out.clear(); + return out; + } + + void R4DCB08::setCorrection(std::vector corr) + { + uint8_t retries(0); + uint8_t channel(0); + corr.resize(getNum()); // max number of temperature correction values is equal to number of sensors + + for (auto v : corr) + { // convert to decimal degreees to register value + while (retries++ < maxRetries) + { + if (m_bus.writeRegister(m_address, REG_TEMPCORR + channel, v*10)) + { + channel++; + delay(50); + break; + } + LOG_ERROR("Failed to Set Temperature Correction, device", m_address); + delay(50); + } + } + } + + std::vector R4DCB08::getCorrection() + { + uint8_t retries(0); + std::vector rawV; + std::vector out; + rawV.reserve(getNum()); + + while (retries++ < maxRetries) + { + if (m_bus.readHoldingRegisters(m_address, REG_TEMPCORR, getNum(), rawV)) + { + out.reserve(rawV.size()); + for (auto v : rawV) + { + out.push_back(v/10.0f); + } + return out; + } + LOG_ERROR("Failed to Get Temperature Correction, device", m_address); + rawV.clear(); + delay(50); + } + out.clear(); + return out; + } + + const uint8_t R4DCB08::getNum() + { + if (m_sensors) + return m_sensors; + uint8_t retries(0); + uint8_t sensors(0); + std::vector rawT; + while (retries++ < maxRetries) + { + if (m_bus.readHoldingRegisters(m_address, REG_TEMP, T_MAX, rawT)) + { + for (auto v : rawT) + { + if (v <= INT16_MAX) + sensors++; // 32768 is returned if sensor is disconnected + } + m_sensors = sensors; + return m_sensors; + } + LOG_ERROR("Failed to Get Sensor Number, device", m_address); + delay(50); + } + LOG_ERROR("No Temperature Sensors Detected, device", m_address); + return 0; + } +} diff --git a/lib/TEMP/R4DCB08_Driver.h b/lib/TEMP/R4DCB08_Driver.h new file mode 100644 index 0000000..36a0cf4 --- /dev/null +++ b/lib/TEMP/R4DCB08_Driver.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include + +namespace drivers +{ + + class R4DCB08 + { + + public: + enum tempCh + { + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T_MAX + }; + + const uint8_t maxRetries = 5; + const uint16_t REG_TEMP = 0x0000; + const uint16_t REG_TEMPCORR = 0x0008; + + public: + R4DCB08(drivers::MODBUS &bus, const uint8_t address); + ~R4DCB08(); + + const float getTemp(const uint8_t ch); + const std::vector getTempAll(); + + void setCorrection(std::vector corr); + std::vector getCorrection(); + + const uint8_t getNum(); + + private: + const uint8_t m_address; + uint8_t m_sensors; + MODBUS &m_bus; + }; +} diff --git a/src/main.cpp b/src/main.cpp index 0b175e0..5580e5a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -43,6 +44,7 @@ void loop() const uint8_t baseRegister(0x00); uint16_t k(0); uint8_t ethRetries(0); + uint8_t sensors(0); //////////////// DEVICES //////////////// // Declared here to keep devices local to the main loop otherwise the kernel crashes // @@ -50,7 +52,10 @@ void loop() auto bus = drivers::MODBUS(9600, SERIAL_8N1); auto rtc = drivers::PCF85063(i2c, PCF85063_ADDRESS); auto eth = drivers::Ethernet("waveshare-test"); + auto tmp = drivers::R4DCB08(bus, tempBoardAddr); + delay(100); auto io = digitalIO(i2c, bus, {relayBoardAddr}); + delay(100); Network.onEvent([ð](arduino_event_id_t event, arduino_event_info_t info) { eth.onEvent(event, info); }); @@ -61,6 +66,10 @@ void loop() delay(1000); } + // Initialize temperature sensors + sensors = tmp.getNum(); + LOG_INFO("Temperature sensors connected ->", sensors); + // Get RTC time at startup time_t ntpTime; drivers::PCF85063::datetime_t dt; @@ -82,22 +91,22 @@ void loop() while (true) { LOG_INFO("[", k++, "] Loop"); - std::vector results; - std::vector values; - + eth.getNtpTime(ntpTime); dt = drivers::PCF85063::fromEpoch(ntpTime); - LOG_INFO("Netwrok Datetime", rtc.datetime2str(dt).c_str()); + LOG_INFO("Network Datetime", rtc.datetime2str(dt).c_str()); LOG_INFO("Current Datetime", rtc.getTimeStr().c_str()); mqtt.publish("test/esp32-out", ("[" + std::to_string(k) + "] -> " + rtc.getTimeStr()).c_str()); - if (bus.readHoldingRegisters(tempBoardAddr, baseRegister, 1, results)) - { - for (auto i(0); i < results.size(); i++) - { - LOG_INFO("[", i, "]Temperature: ", results.at(i) / 10.0f); - } - results.clear(); + uint8_t i(0); + delay(10); + for (auto v: tmp.getTempAll()) { + LOG_INFO("Temperature channel", i++, "->", v); + } + i=0; + delay(10); + for (auto v : tmp.getCorrection()){ + LOG_INFO("Temperature correction channel", i++, "tc", v); } for (auto j(0); j < io.getOutNum(); j++) @@ -107,6 +116,10 @@ void loop() delay(500); } + //for (auto j(0); j < io.getOutNum(); j++) + //{ + // io.digitalIOWrite(j, false); + //} delay(5000); }