#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) { auto lock = m_bus.getLock(); 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) { auto lock = m_bus.getLock(); 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) { auto lock = m_bus.getLock(); 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) { auto lock = m_bus.getLock(); 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) { auto lock = m_bus.getLock(); 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; } }