Files
ETcontroller_PRO/lib/TEMP/R4DCB08_Driver.cpp
2025-07-25 10:57:17 +02:00

143 lines
4.3 KiB
C++

#include <R4DCB08_Driver.h>
#include <busdelay.h>
#define BUS_DELAY drivers::BusDelay(m_lastRequest, c_minDelay, "R4DCB08")
namespace drivers
{
R4DCB08::R4DCB08(drivers::MODBUS &bus, const uint8_t address) : m_address(address), m_bus(bus), m_sensors(0)
{
m_sensors = getNum();
m_lastRequest = millis();
}
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;
}
std::lock_guard<std::mutex> lock(m_bus.getMutex());
while (retries++ < c_maxRetries)
{
BUS_DELAY;
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", printHex(m_address).c_str(), "channel", ch);
rawT.clear();
}
return MAXFLOAT;
}
const std::vector<float> R4DCB08::getTempAll()
{
uint8_t retries(0);
std::vector<uint16_t> rawT;
std::vector<float> out;
std::lock_guard<std::mutex> lock(m_bus.getMutex());
while (retries++ < c_maxRetries)
{
BUS_DELAY;
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", printHex(m_address).c_str());
rawT.clear();
}
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
std::lock_guard<std::mutex> lock(m_bus.getMutex());
for (auto v : corr)
{
while (retries++ < c_maxRetries)
{
BUS_DELAY;
if (m_bus.writeRegister(m_address, REG_TEMPCORR + channel, v * 10)) // convert to decimal degreees to register value
{
channel++;
break;
}
LOG_ERROR("Failed to Set Temperature Correction, device", printHex(m_address).c_str());
}
}
}
std::vector<float> R4DCB08::getCorrection()
{
uint8_t retries(0);
std::vector<uint16_t> rawV;
std::vector<float> out;
rawV.reserve(getNum());
std::lock_guard<std::mutex> lock(m_bus.getMutex());
while (retries++ < c_maxRetries)
{
BUS_DELAY;
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", printHex(m_address).c_str());
rawV.clear();
}
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;
std::lock_guard<std::mutex> lock(m_bus.getMutex());
while (retries++ < c_maxRetries)
{
BUS_DELAY;
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", printHex(m_address).c_str());
}
LOG_ERROR("No Temperature Sensors Detected, device", printHex(m_address).c_str());
return 0;
}
}
#undef BUS_DELAY