Files
ETcontroller_PRO/lib/RS485/RS485_Driver.h
2025-07-25 10:57:17 +02:00

107 lines
3.8 KiB
C++

#pragma once
#define DEBUGLOG_DEFAULT_LOG_LEVEL_INFO
#include <DebugLog.h>
#include <Arduino.h>
#include <HardwareSerial.h> // Reference the ESP32 built-in serial port library
#include <CRC16.h>
#include <memory>
#include <mutex>
namespace drivers
{
class RS485
{
const uint8_t c_port = 1;
public:
RS485(const uint32_t baud, const SerialConfig conf);
RS485(const RS485 &) = delete; // remove copy constructors
RS485 &operator=(const RS485 &) = delete;
const bool write(const std::vector<uint8_t> data);
const bool readAll(std::vector<uint8_t> &data);
const bool readN(const uint16_t nBytes, std::vector<uint8_t> &data);
const bool readUntil(const uint8_t ch, std::vector<uint8_t> &data);
private:
HardwareSerial &m_serial;
};
class MODBUS : private RS485
{
const uint8_t c_respHeaderSize = 3;
const uint8_t c_respCrcSize = 2;
const uint32_t c_minDelay = 250;
typedef struct
{
uint8_t device;
uint8_t func;
uint16_t reg;
uint16_t data;
} req_t;
typedef struct
{
uint8_t device;
uint8_t func;
uint16_t reg;
uint16_t qty;
uint8_t bytes;
} req_multi_t;
typedef req_t resp_t;
typedef uint16_t crc_t;
public:
MODBUS(const uint32_t baud, const SerialConfig conf);
MODBUS(const MODBUS &) = delete; // remove copy constructors
MODBUS &operator=(const MODBUS &) = delete;
// Get transaction lock
std::unique_lock<std::mutex> getLock();
std::mutex &getMutex();
// Func 0x01
const bool readCoils(const uint8_t device, const uint16_t reg, const uint16_t num, std::vector<bool> &coils);
// Func 0x02
const bool readInputs(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector<bool> &inputs);
// Func 0x03
const bool readHoldingRegisters(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector<uint16_t> &values);
// Func 0x04
const bool readInputRegisters(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector<uint16_t> &values);
// Func 0x05
const bool writeCoil(const uint8_t device, const uint16_t coil, const bool value);
// Func 0x06
const bool writeRegister(const uint8_t device, const uint16_t reg, const uint16_t value);
// Func 0x0F
const bool writeCoils(const uint8_t device, const uint16_t coils, const std::vector<bool> &values);
// Func 0x10
const bool writeRegisters(const uint8_t device, const uint16_t reg, const std::vector<uint16_t> &values);
private:
CRC16 m_crc;
std::mutex m_mutex;
uint8_t m_lastDevice;
uint32_t m_lastAccess;
void delayAccess(const uint8_t device);
const std::vector<uint8_t> singleRequest(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t data);
const std::vector<uint8_t> multiRequest(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t qty, const std::vector<uint8_t> &data);
const bool readBinary(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t bits, std::vector<bool> &out);
const bool readInteger(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t num, std::vector<uint16_t> &out);
const bool writeBinary(const uint8_t device, const uint8_t func, const uint16_t reg, const std::vector<bool> &in);
const bool writeInteger(const uint8_t device, const uint8_t func, const uint16_t reg, const std::vector<uint16_t> &in, const bool multi);
const bool verifyCrc(const std::vector<uint8_t> &data);
};
}