Fixed MODBUS and seneca drivers, added partial counter reset

This commit is contained in:
Emanuele Trabattoni
2025-07-13 13:16:24 +02:00
parent d2eba9085e
commit 7e02f3cef2
5 changed files with 96 additions and 60 deletions

View File

@@ -3,7 +3,6 @@
#include <cstring>
#include <endian.h>
//#define DEBUGLOG_DEFAULT_LOG_LEVEL_TRACE
#include "utils.h"
namespace drivers
@@ -18,6 +17,7 @@ namespace drivers
LOG_INFO("Init serial port 1");
// RS485 is hardwired to serial port 1
m_serial.begin(baud, conf, 18, 17);
m_serial.setTimeout(1000);
m_serial.flush();
}
@@ -112,7 +112,7 @@ namespace drivers
{
constexpr uint8_t func = 0x06;
LOG_DEBUG("Write single register: dev[", device, "], reg[", reg, "], value[", value, "]");
return writeInteger(device, func, reg, {value});
return writeInteger(device, func, reg, {value}, false);
}
// Func 0x0F
@@ -128,7 +128,7 @@ namespace drivers
{
constexpr uint8_t func = 0x10;
LOG_DEBUG("Write multi registers: dev[", device, "], start[", reg, "], num[", values.size(), "]");
return writeInteger(device, func, reg, values);
return writeInteger(device, func, reg, values, true);
}
/////////////////////////////////////////////////////////////////
@@ -150,15 +150,15 @@ namespace drivers
LOG_ERROR("Failed receive readBinary response, expected[", expectedRespLen, "], received[", response.size(), "]");
return false;
}
#ifdef DEBUGLOG_DEFAULT_LOG_LEVEL_TRACE
printBytes("readBinary Response", response);
#endif
// element 2 of response has the response data bytes expected
const uint8_t actualRespLen(response.at(2));
if (actualRespLen != nRespDataBytes)
{
LOG_ERROR("Failed receive, data to short: actual[", actualRespLen, "], expected[", nRespDataBytes, "]");
#ifdef DEBUGLOG_DEFAULT_LOG_LEVEL_TRACE
printBytes("readBinary Response", response);
#endif
return false;
}
@@ -198,11 +198,11 @@ namespace drivers
if (!readN(expectedRespLen, response))
{
LOG_ERROR("Failed receive readInteger response, expected[", expectedRespLen, "], received[", response.size(), "]");
#ifdef DEBUGLOG_DEFAULT_LOG_LEVEL_TRACE
printBytes("readInteger Response", response);
#endif
return false;
}
#ifdef DEBUGLOG_DEFAULT_LOG_LEVEL_TRACE
printBytes("readInteger Response", response);
#endif
// element 2 of response has the response data bytes expected
const uint8_t actualRespLen(response.at(2));
@@ -270,11 +270,11 @@ namespace drivers
if (!readN(expectedRespLen, response))
{
LOG_ERROR("Failed receive writeBinary response, expected[", expectedRespLen, "], received[", response.size(), "]");
#ifdef DEBUGLOG_DEFAULT_LOG_LEVEL_TRACE
printBytes("writeBinary Response", response);
#endif
return false;
}
#ifdef DEBUGLOG_DEFAULT_LOG_LEVEL_TRACE
printBytes("writeBinary Response", response);
#endif
// compute crc of current message
if (!verifyCrc(response))
@@ -283,10 +283,10 @@ namespace drivers
return true;
}
const bool MODBUS::writeInteger(const uint8_t device, const uint8_t func, const uint16_t reg, const std::vector<uint16_t> &in)
const bool MODBUS::writeInteger(const uint8_t device, const uint8_t func, const uint16_t reg, const std::vector<uint16_t> &in, const bool multi)
{
const uint16_t num(in.size());
if (num == 1)
if (!multi)
{
if (!write(singleRequest(device, func, reg, in[0])))
{
@@ -298,14 +298,14 @@ namespace drivers
{
// build data vector for request, inverting bytes if necessary
std::vector<uint8_t> requestData;
requestData.resize(in.size() * sizeof(uint16_t));
auto it=requestData.begin();
std::for_each(in.begin(), in.end(), [requestData, &it](auto inV) {
requestData.resize(in.size() * sizeof(uint16_t), 0xff);
auto it = requestData.begin();
for (auto inV : in)
{
const uint16_t beV(htobe16(inV));
*it=highByte(beV);
*(++it)=lowByte(beV);
});
*(it++) = lowByte(beV);
*(it++) = highByte(beV);
}
if (!write(multiRequest(device, func, reg, num, requestData)))
{
LOG_ERROR("Failed send writeMultiInteger command");
@@ -318,11 +318,11 @@ namespace drivers
if (!readN(expectedRespLen, response))
{
LOG_ERROR("Failed receive writeInteger response, expected[", expectedRespLen, "], received[", response.size(), "]");
#ifdef DEBUGLOG_DEFAULT_LOG_LEVEL_TRACE
printBytes("writeInteger Response", response);
#endif
return false;
}
#ifdef DEBUGLOG_DEFAULT_LOG_LEVEL_TRACE
printBytes("writeInteger Response", response);
#endif
// compute crc of current message
if (!verifyCrc(response))
@@ -366,7 +366,7 @@ namespace drivers
header.qty = htobe16(qty);
header.bytes = data.size(); // 8 bit value
//const uint8_t headerBytes(sizeof(req_multi_t)); // sizeof not working because of memory padding
// const uint8_t headerBytes(sizeof(req_multi_t)); // sizeof not working because of memory padding
const uint8_t headerBytes(7);
const uint8_t dataBytes(data.size());
const uint8_t crcBytes(sizeof(crc_t));
@@ -380,7 +380,7 @@ namespace drivers
std::vector<uint8_t> dataOut;
dataOut.resize(headerBytes + dataBytes + crcBytes); // header message + data values + crc code
std::memcpy(dataOut.data(), &header, headerBytes); // copy message
std::memcpy(dataOut.data() + headerBytes, data.data(), dataBytes); // copy data
std::memcpy(dataOut.data() + headerBytes, data.data(), dataBytes); // copy data
std::memcpy(dataOut.data() + headerBytes + dataBytes, &crc, crcBytes); // copy crc
#ifdef DEBUGLOG_DEFAULT_LOG_LEVEL_TRACE