#include #include #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 rawT; if (ch < 0 || ch > getNum()) { LOG_ERROR("Invalid Temperature Channel number", ch); return MAXFLOAT; } std::lock_guard 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 R4DCB08::getTempAll() { uint8_t retries(0); std::vector rawT; std::vector out; std::lock_guard 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 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 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 R4DCB08::getCorrection() { uint8_t retries(0); std::vector rawV; std::vector out; rawV.reserve(getNum()); std::lock_guard 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 rawT; std::lock_guard 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