#pragma once #include #include #include // Reference the ESP32 built-in serial port library #include #include #define Extension_CH1 1 // Expansion Channel 1 #define Extension_CH2 2 // Expansion Channel 2 #define Extension_CH3 3 // Expansion Channel 3 #define Extension_CH4 4 // Expansion Channel 4 #define Extension_CH5 5 // Expansion Channel 5 #define Extension_CH6 6 // Expansion Channel 6 #define Extension_CH7 7 // Expansion Channel 7 #define Extension_CH8 8 // Expansion Channel 8 #define Extension_ALL_ON 9 // Expansion ALL ON #define Extension_ALL_OFF 10 // Expansion ALL OFF namespace drivers { class RS485 { static const uint8_t PORT = 1; public: RS485(const uint32_t baud, const SerialConfig conf); 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 : public 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); // 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; 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 uint16_t bits, const std::vector &in); const bool writeInteger(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t num, const std::vector &in); const bool verifyCrc(const std::vector &data); }; }