#pragma once #define DEBUGLOG_DEFAULT_LOG_LEVEL_INFO #include #include #include // Reference the ESP32 built-in serial port library #include #include #include namespace drivers { class RS485 { static const uint8_t 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 data); const bool readAll(std::vector &data); const bool readN(const uint16_t nBytes, std::vector &data); const bool readUntil(const uint8_t ch, std::vector &data); private: HardwareSerial &m_serial; }; class MODBUS : private RS485 { static const uint8_t RESP_HEADER_SIZE = 3; static const uint8_t RESP_CRC_SIZE = 2; 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; // Func 0x01 const bool readCoils(const uint8_t device, const uint16_t reg, const uint16_t num, std::vector &coils); // Func 0x02 const bool readInputs(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector &inputs); // Func 0x03 const bool readHoldingRegisters(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector &values); // Func 0x04 const bool readInputRegisters(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector &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 &values); // Func 0x10 const bool writeRegisters(const uint8_t device, const uint16_t reg, const std::vector &values); private: CRC16 m_crc; std::mutex m_mutex; const std::vector singleRequest(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t data); const std::vector multiRequest(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t qty, const std::vector &data); const bool readBinary(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t bits, std::vector &out); const bool readInteger(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t num, std::vector &out); const bool writeBinary(const uint8_t device, const uint8_t func, const uint16_t reg, const std::vector &in); const bool writeInteger(const uint8_t device, const uint8_t func, const uint16_t reg, const std::vector &in, const bool multi); const bool verifyCrc(const std::vector &data); }; }