Added Temperature board driver

This commit is contained in:
Emanuele Trabattoni
2025-07-12 16:11:05 +02:00
parent e4d28b55cb
commit 1ad98799b4
3 changed files with 204 additions and 11 deletions

133
lib/TEMP/R4DCB08_Driver.cpp Normal file
View File

@@ -0,0 +1,133 @@
#include <R4DCB08_Driver.h>
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<uint16_t> 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<float> R4DCB08::getTempAll()
{
uint8_t retries(0);
std::vector<uint16_t> rawT;
std::vector<float> 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<float> 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<float> R4DCB08::getCorrection()
{
uint8_t retries(0);
std::vector<uint16_t> rawV;
std::vector<float> 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<uint16_t> 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;
}
}

47
lib/TEMP/R4DCB08_Driver.h Normal file
View File

@@ -0,0 +1,47 @@
#pragma once
#include <DebugLog.h>
#include <RS485_Driver.h>
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<float> getTempAll();
void setCorrection(std::vector<float> corr);
std::vector<float> getCorrection();
const uint8_t getNum();
private:
const uint8_t m_address;
uint8_t m_sensors;
MODBUS &m_bus;
};
}

View File

@@ -6,6 +6,7 @@
#include <PubSubClient.h>
#include <PCF85063_Driver.h>
#include <R4DCB08_Driver.h>
#include <ETH_Driver.h>
#include <digitalIO.h>
@@ -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([&eth](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<uint16_t> results;
std::vector<bool> 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);
}