From 2bef3ce8c059d062e5a7458e99d6d40eaa446408 Mon Sep 17 00:00:00 2001 From: Vasily Davydov Date: Thu, 27 Oct 2022 13:14:37 +0300 Subject: [PATCH] modbus: include timer --- esp-vent-main/inc/Modbus/ModbusMaster.h | 347 +++++++++++++----------- 1 file changed, 182 insertions(+), 165 deletions(-) diff --git a/esp-vent-main/inc/Modbus/ModbusMaster.h b/esp-vent-main/inc/Modbus/ModbusMaster.h index 18e7978..8cf1655 100644 --- a/esp-vent-main/inc/Modbus/ModbusMaster.h +++ b/esp-vent-main/inc/Modbus/ModbusMaster.h @@ -1,6 +1,7 @@ /** @file -Arduino library for communicating with Modbus slaves over RS232/485 (via RTU protocol). +Arduino library for communicating with Modbus slaves over RS232/485 (via RTU +protocol). @defgroup setup ModbusMaster Object Instantiation/Initialization @defgroup buffer ModbusMaster Buffer Management @@ -33,10 +34,10 @@ Arduino library for communicating with Modbus slaves over RS232/485 (via RTU pro */ - #ifndef ModbusMaster_h #define ModbusMaster_h +#include "Timer.h" /** @def __MODBUSMASTER_DEBUG__ (1). @@ -46,24 +47,24 @@ Set to 1 to enable debugging features within class: */ #define __MODBUSMASTER_DEBUG__ (0) - -/* _____STANDARD INCLUDES____________________________________________________ */ +/* _____STANDARD INCLUDES____________________________________________________ + */ // include types & constants of Wiring core API #if defined(ARDUINO) && ARDUINO >= 100 #include "Arduino.h" #else //#include "WProgram.h" -#include #include +#include #endif -uint32_t millis(); #define BYTE 0xA5 -/* _____UTILITY MACROS_______________________________________________________ */ +/* _____UTILITY MACROS_______________________________________________________ + */ - -/* _____PROJECT INCLUDES_____________________________________________________ */ +/* _____PROJECT INCLUDES_____________________________________________________ + */ // functions to calculate Modbus Application Data Unit CRC //#include "util/crc16.h" // moved inlcuding crc16.h to ModbusMaster.cpp @@ -72,207 +73,223 @@ uint32_t millis(); ///#include "util/word.h" #include "word.h" - #include "SerialPort.h" -/* _____CLASS DEFINITIONS____________________________________________________ */ +/* _____CLASS DEFINITIONS____________________________________________________ + */ /** Arduino class library for communicating with Modbus slaves over RS232/485 (via RTU protocol). */ class ModbusMaster { - public: - ModbusMaster(); - ModbusMaster(uint8_t); - ModbusMaster(uint8_t, uint8_t); +public: + ModbusMaster (); + ModbusMaster (uint8_t); + ModbusMaster (uint8_t, uint8_t); - void begin(); - void begin(uint16_t); - void idle(void (*)()); + void begin (); + void begin (uint16_t); + void idle (void (*) ()); - // Modbus exception codes - /** - Modbus protocol illegal function exception. + // Modbus exception codes + /** + Modbus protocol illegal function exception. - The function code received in the query is not an allowable action for - the server (or slave). This may be because the function code is only - applicable to newer devices, and was not implemented in the unit - selected. It could also indicate that the server (or slave) is in the - wrong state to process a request of this type, for example because it is - unconfigured and is being asked to return register values. + The function code received in the query is not an allowable action for + the server (or slave). This may be because the function code is only + applicable to newer devices, and was not implemented in the unit + selected. It could also indicate that the server (or slave) is in the + wrong state to process a request of this type, for example because it is + unconfigured and is being asked to return register values. - @ingroup constant - */ - static const uint8_t ku8MBIllegalFunction = 0x01; + @ingroup constant + */ + static const uint8_t ku8MBIllegalFunction = 0x01; - /** - Modbus protocol illegal data address exception. + /** + Modbus protocol illegal data address exception. - The data address received in the query is not an allowable address for - the server (or slave). More specifically, the combination of reference - number and transfer length is invalid. For a controller with 100 - registers, the ADU addresses the first register as 0, and the last one - as 99. If a request is submitted with a starting register address of 96 - and a quantity of registers of 4, then this request will successfully - operate (address-wise at least) on registers 96, 97, 98, 99. If a - request is submitted with a starting register address of 96 and a - quantity of registers of 5, then this request will fail with Exception - Code 0x02 "Illegal Data Address" since it attempts to operate on - registers 96, 97, 98, 99 and 100, and there is no register with address - 100. + The data address received in the query is not an allowable address for + the server (or slave). More specifically, the combination of reference + number and transfer length is invalid. For a controller with 100 + registers, the ADU addresses the first register as 0, and the last one + as 99. If a request is submitted with a starting register address of 96 + and a quantity of registers of 4, then this request will successfully + operate (address-wise at least) on registers 96, 97, 98, 99. If a + request is submitted with a starting register address of 96 and a + quantity of registers of 5, then this request will fail with Exception + Code 0x02 "Illegal Data Address" since it attempts to operate on + registers 96, 97, 98, 99 and 100, and there is no register with address + 100. - @ingroup constant - */ - static const uint8_t ku8MBIllegalDataAddress = 0x02; + @ingroup constant + */ + static const uint8_t ku8MBIllegalDataAddress = 0x02; - /** - Modbus protocol illegal data value exception. + /** + Modbus protocol illegal data value exception. - A value contained in the query data field is not an allowable value for - server (or slave). This indicates a fault in the structure of the - remainder of a complex request, such as that the implied length is - incorrect. It specifically does NOT mean that a data item submitted for - storage in a register has a value outside the expectation of the - application program, since the MODBUS protocol is unaware of the - significance of any particular value of any particular register. + A value contained in the query data field is not an allowable value for + server (or slave). This indicates a fault in the structure of the + remainder of a complex request, such as that the implied length is + incorrect. It specifically does NOT mean that a data item submitted for + storage in a register has a value outside the expectation of the + application program, since the MODBUS protocol is unaware of the + significance of any particular value of any particular register. - @ingroup constant - */ - static const uint8_t ku8MBIllegalDataValue = 0x03; + @ingroup constant + */ + static const uint8_t ku8MBIllegalDataValue = 0x03; - /** - Modbus protocol slave device failure exception. + /** + Modbus protocol slave device failure exception. - An unrecoverable error occurred while the server (or slave) was - attempting to perform the requested action. + An unrecoverable error occurred while the server (or slave) was + attempting to perform the requested action. - @ingroup constant - */ - static const uint8_t ku8MBSlaveDeviceFailure = 0x04; + @ingroup constant + */ + static const uint8_t ku8MBSlaveDeviceFailure = 0x04; - // Class-defined success/exception codes - /** - ModbusMaster success. + // Class-defined success/exception codes + /** + ModbusMaster success. - Modbus transaction was successful; the following checks were valid: - - slave ID - - function code - - response code - - data - - CRC + Modbus transaction was successful; the following checks were valid: + - slave ID + - function code + - response code + - data + - CRC - @ingroup constant - */ - static const uint8_t ku8MBSuccess = 0x00; + @ingroup constant + */ + static const uint8_t ku8MBSuccess = 0x00; - /** - ModbusMaster invalid response slave ID exception. + /** + ModbusMaster invalid response slave ID exception. - The slave ID in the response does not match that of the request. + The slave ID in the response does not match that of the request. - @ingroup constant - */ - static const uint8_t ku8MBInvalidSlaveID = 0xE0; + @ingroup constant + */ + static const uint8_t ku8MBInvalidSlaveID = 0xE0; - /** - ModbusMaster invalid response function exception. + /** + ModbusMaster invalid response function exception. - The function code in the response does not match that of the request. + The function code in the response does not match that of the request. - @ingroup constant - */ - static const uint8_t ku8MBInvalidFunction = 0xE1; + @ingroup constant + */ + static const uint8_t ku8MBInvalidFunction = 0xE1; - /** - ModbusMaster response timed out exception. + /** + ModbusMaster response timed out exception. - The entire response was not received within the timeout period, - ModbusMaster::ku8MBResponseTimeout. + The entire response was not received within the timeout period, + ModbusMaster::ku8MBResponseTimeout. - @ingroup constant - */ - static const uint8_t ku8MBResponseTimedOut = 0xE2; + @ingroup constant + */ + static const uint8_t ku8MBResponseTimedOut = 0xE2; - /** - ModbusMaster invalid response CRC exception. + /** + ModbusMaster invalid response CRC exception. - The CRC in the response does not match the one calculated. + The CRC in the response does not match the one calculated. - @ingroup constant - */ - static const uint8_t ku8MBInvalidCRC = 0xE3; + @ingroup constant + */ + static const uint8_t ku8MBInvalidCRC = 0xE3; - uint16_t getResponseBuffer(uint8_t); - void clearResponseBuffer(); - uint8_t setTransmitBuffer(uint8_t, uint16_t); - void clearTransmitBuffer(); + 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); + 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 readCoils (uint16_t, uint16_t); + uint8_t readDiscreteInputs (uint16_t, uint16_t); + uint8_t readHoldingRegisters (uint16_t, uint16_t); + uint8_t readInputRegisters (uint16_t, uint8_t); + uint8_t writeSingleCoil (uint16_t, uint8_t); + uint8_t writeSingleRegister (uint16_t, uint16_t); + uint8_t writeMultipleCoils (uint16_t, uint16_t); + uint8_t writeMultipleCoils (); + uint8_t writeMultipleRegisters (uint16_t, uint16_t); + uint8_t writeMultipleRegisters (); + uint8_t maskWriteRegister (uint16_t, uint16_t, uint16_t); + uint8_t readWriteMultipleRegisters (uint16_t, uint16_t, uint16_t, uint16_t); + uint8_t readWriteMultipleRegisters (uint16_t, uint16_t); - uint8_t readCoils(uint16_t, uint16_t); - uint8_t readDiscreteInputs(uint16_t, uint16_t); - uint8_t readHoldingRegisters(uint16_t, uint16_t); - uint8_t readInputRegisters(uint16_t, uint8_t); - uint8_t writeSingleCoil(uint16_t, uint8_t); - uint8_t writeSingleRegister(uint16_t, uint16_t); - uint8_t writeMultipleCoils(uint16_t, uint16_t); - uint8_t writeMultipleCoils(); - uint8_t writeMultipleRegisters(uint16_t, uint16_t); - uint8_t writeMultipleRegisters(); - uint8_t maskWriteRegister(uint16_t, uint16_t, uint16_t); - uint8_t readWriteMultipleRegisters(uint16_t, uint16_t, uint16_t, uint16_t); - uint8_t readWriteMultipleRegisters(uint16_t, uint16_t); +private: + uint8_t _u8SerialPort; ///< serial port (0..3) initialized in constructor + uint8_t _u8MBSlave; ///< Modbus slave (1..255) initialized in constructor + uint16_t _u16BaudRate; ///< baud rate (300..115200) initialized in begin() + static const uint8_t ku8MaxBufferSize + = 64; ///< 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; - private: - uint8_t _u8SerialPort; ///< serial port (0..3) initialized in constructor - uint8_t _u8MBSlave; ///< Modbus slave (1..255) initialized in constructor - uint16_t _u16BaudRate; ///< baud rate (300..115200) initialized in begin() - static const uint8_t ku8MaxBufferSize = 64; ///< 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 bit access + static const uint8_t ku8MBReadCoils + = 0x01; ///< Modbus function 0x01 Read Coils + static const uint8_t ku8MBReadDiscreteInputs + = 0x02; ///< Modbus function 0x02 Read Discrete Inputs + static const uint8_t ku8MBWriteSingleCoil + = 0x05; ///< Modbus function 0x05 Write Single Coil + static const uint8_t ku8MBWriteMultipleCoils + = 0x0F; ///< Modbus function 0x0F Write Multiple Coils - // Modbus function codes for bit access - static const uint8_t ku8MBReadCoils = 0x01; ///< Modbus function 0x01 Read Coils - static const uint8_t ku8MBReadDiscreteInputs = 0x02; ///< Modbus function 0x02 Read Discrete Inputs - static const uint8_t ku8MBWriteSingleCoil = 0x05; ///< Modbus function 0x05 Write Single Coil - static const uint8_t ku8MBWriteMultipleCoils = 0x0F; ///< Modbus function 0x0F Write Multiple Coils + // Modbus function codes for 16 bit access + static const uint8_t ku8MBReadHoldingRegisters + = 0x03; ///< Modbus function 0x03 Read Holding Registers + static const uint8_t ku8MBReadInputRegisters + = 0x04; ///< Modbus function 0x04 Read Input Registers + static const uint8_t ku8MBWriteSingleRegister + = 0x06; ///< Modbus function 0x06 Write Single Register + static const uint8_t ku8MBWriteMultipleRegisters + = 0x10; ///< Modbus function 0x10 Write Multiple Registers + static const uint8_t ku8MBMaskWriteRegister + = 0x16; ///< Modbus function 0x16 Mask Write Register + static const uint8_t ku8MBReadWriteMultipleRegisters + = 0x17; ///< Modbus function 0x17 Read Write Multiple Registers - // Modbus function codes for 16 bit access - static const uint8_t ku8MBReadHoldingRegisters = 0x03; ///< Modbus function 0x03 Read Holding Registers - static const uint8_t ku8MBReadInputRegisters = 0x04; ///< Modbus function 0x04 Read Input Registers - static const uint8_t ku8MBWriteSingleRegister = 0x06; ///< Modbus function 0x06 Write Single Register - static const uint8_t ku8MBWriteMultipleRegisters = 0x10; ///< Modbus function 0x10 Write Multiple Registers - static const uint8_t ku8MBMaskWriteRegister = 0x16; ///< Modbus function 0x16 Mask Write Register - static const uint8_t ku8MBReadWriteMultipleRegisters = 0x17; ///< Modbus function 0x17 Read Write Multiple Registers + // Modbus timeout [milliseconds] + static const uint16_t ku16MBResponseTimeout + = 2000; ///< Modbus timeout [milliseconds] - // Modbus timeout [milliseconds] - static const uint16_t ku16MBResponseTimeout = 2000; ///< Modbus timeout [milliseconds] + // master function that conducts Modbus transactions + uint8_t ModbusMasterTransaction (uint8_t u8MBFunction); - // 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)(); - SerialPort *MBSerial = NULL; // added by KRL + // idle callback function; gets called during idle time between TX and RX + void (*_idle) (); + SerialPort *MBSerial = NULL; // added by KRL }; #endif