2024-09-20 13:13:42 +03:00
# ifndef ModbusEC_h
# define ModbusEC_h
# define __MODBUSMASTER_DEBUG__ (0)
# define __MODBUSMASTER_DEBUG_PIN_A__ 4
# define __MODBUSMASTER_DEBUG_PIN_B__ 5
# include "Arduino.h"
# include "util/crc16.h"
# include "util/word.h"
/* _____CLASS DEFINITIONS____________________________________________________ */
/**
Arduino class library for communicating with Modbus slaves over
RS232 / 485 ( via RTU protocol ) .
*/
class ModbusMaster
{
public :
ModbusMaster ( ) ;
2025-02-21 17:50:41 +03:00
void begin ( uint8_t , Stream * serial ) ;
2024-09-20 13:13:42 +03:00
void idle ( void ( * ) ( ) ) ;
void preTransmission ( void ( * ) ( ) ) ;
void postTransmission ( void ( * ) ( ) ) ;
static const uint8_t ku8MBIllegalFunction = 0x01 ;
static const uint8_t ku8MBIllegalDataAddress = 0x02 ;
static const uint8_t ku8MBIllegalDataValue = 0x03 ;
static const uint8_t ku8MBSlaveDeviceFailure = 0x04 ;
static const uint8_t ku8MBSuccess = 0x00 ;
static const uint8_t ku8MBInvalidSlaveID = 0xE0 ;
static const uint8_t ku8MBInvalidFunction = 0xE1 ;
static const uint8_t ku8MBResponseTimedOut = 0xE2 ;
static const uint8_t ku8MBInvalidCRC = 0xE3 ;
uint16_t getResponseBuffer ( uint8_t ) ;
void clearResponseBuffer ( ) ;
uint8_t setTransmitBuffer ( uint8_t , uint16_t ) ;
void clearTransmitBuffer ( ) ;
void beginTransmission ( uint16_t ) ;
uint8_t requestFrom ( uint16_t , uint16_t ) ;
void sendBit ( bool ) ;
void send ( uint8_t ) ;
void send ( uint16_t ) ;
void send ( uint32_t ) ;
uint8_t available ( void ) ;
uint16_t receive ( void ) ;
uint8_t readHoldingRegisters ( uint16_t , uint16_t ) ;
uint8_t writeMultipleRegisters ( uint16_t , uint16_t ) ;
uint8_t writeMultipleRegisters ( ) ;
2025-02-24 19:50:42 +03:00
uint8_t writeSingleRegister ( uint16_t , uint16_t ) ;
2024-09-20 13:13:42 +03:00
uint8_t readAddresEctoControl ( ) ;
uint8_t writeAddresEctoControl ( uint8_t ) ;
private :
Stream * _serial ; ///< reference to serial port object
uint8_t _u8MBSlave ; ///< Modbus slave (1..255) initialized in begin()
static const uint8_t ku8MaxBufferSize = 20 ; ///< size of response/transmit buffers
uint16_t _u16ReadAddress ; ///< slave register from which to read
uint16_t _u16ReadQty ; ///< quantity of words to read
uint16_t _u16ResponseBuffer [ ku8MaxBufferSize ] ; ///< buffer to store Modbus slave response; read via GetResponseBuffer()
uint16_t _u16WriteAddress ; ///< slave register to which to write
uint16_t _u16WriteQty ; ///< quantity of words to write
uint16_t _u16TransmitBuffer [ ku8MaxBufferSize ] ; ///< buffer containing data to transmit to Modbus slave; set via SetTransmitBuffer()
uint16_t * txBuffer ; // from Wire.h -- need to clean this up Rx
uint8_t _u8TransmitBufferIndex ;
uint16_t u16TransmitBufferLength ;
uint16_t * rxBuffer ; // from Wire.h -- need to clean this up Rx
uint8_t _u8ResponseBufferIndex ;
uint8_t _u8ResponseBufferLength ;
// Modbus function codes for 16 bit access
static const uint8_t ku8MBReadHoldingRegisters = 0x03 ; ///< Modbus function 0x03 Read Holding Registers
static const uint8_t ku8MBWriteMultipleRegisters = 0x10 ; ///< Modbus function 0x10 Write Multiple Registers
2025-02-24 19:50:42 +03:00
static const uint8_t ku8MBWriteSingleRegister = 0x06 ; ///< Modbus function 0x06 Write Single Register
2024-09-20 13:13:42 +03:00
static const uint8_t ku8MBProgRead46 = 0x46 ; ///< EctoControl function 0x46 Устройство возвращает в ответе свой текущий адрес ADDR
static const uint8_t ku8MBProgWrite47 = 0x47 ; ///< EctoControl function 0x47 высылается ведущим устройством ведомому с указанием сменить свой имеющийся адрес на заданный
// высылается ведущим устройством единственному устройству на шине с неизвестным адресом
// Modbus timeout [milliseconds]
2025-03-10 22:09:42 +03:00
static const uint16_t ku16MBResponseTimeout = 500 ; ///< Modbus timeout [milliseconds]
2024-09-20 13:13:42 +03:00
// master function that conducts Modbus transactions
uint8_t ModbusMasterTransaction ( uint8_t u8MBFunction ) ;
// idle callback function; gets called during idle time between TX and RX
void ( * _idle ) ( ) ;
// preTransmission callback function; gets called before writing a Modbus message
void ( * _preTransmission ) ( ) ;
// postTransmission callback function; gets called after a Modbus message has been sent
void ( * _postTransmission ) ( ) ;
} ;
# endif