diff --git a/documentation/API.md b/documentation/API.md index a69d94b..063f7b1 100644 --- a/documentation/API.md +++ b/documentation/API.md @@ -47,12 +47,12 @@ bool removeIreg(uint16_t offset, uint16_t numregs = 1); ### Modbus RTU Specific API ```c -bool begin(SoftwareSerial* port, int16_t txEnablePin=-1, bool txEnableDirect=true); -bool begin(HardwareSerial* port, int16_t txEnablePin=-1, bool txEnableDirect=true); +bool begin(SoftwareSerial* port, int16_t txEnablePin=-1, ModbusRTUTxEnableMode txEnableMode=TxEnableHigh); +bool begin(HardwareSerial* port, int16_t txEnablePin=-1, ModbusRTUTxEnableMode txEnableMode=TxEnableHigh); bool begin(Stream* port); ``` -Assing Serial port. txEnablePin controls transmit enable for MAX-485. Pass txEnableDirect=false if txEnablePin uses inverse logic. +Assign Serial port. `txEnablePin` controls transmit enable for MAX-485. Use `txEnableMode = TxEnableLow` if `txEnablePin` uses inverse logic (low when transmitting). ```c void setBaudrte(uint32 baud); diff --git a/examples/RTU/README.MD b/examples/RTU/README.MD index 1f4e4b9..884b1f0 100644 --- a/examples/RTU/README.MD +++ b/examples/RTU/README.MD @@ -11,14 +11,14 @@ This example introduces how to use the library for ModbusRTU (typicaly over RS-4 ## Modbus RTU Specific API ```c -bool begin(SoftwareSerial* port, int16_t txEnablePin=-1, bool txEnableDirect=true); -bool begin(HardwareSerial* port, int16_t txEnablePin=-1, bool txEnableDirect=true); +bool begin(SoftwareSerial* port, int16_t txEnablePin=-1, ModbusRTUTxEnableMode txEnableMode=TxEnableHigh); +bool begin(HardwareSerial* port, int16_t txEnablePin=-1, ModbusRTUTxEnableMode txEnableMode=TxEnableHigh); bool begin(Stream* port); ``` - `port` Pointer to Serial port - `txEnablePin` RX/TX control pin. Not assigned (assume auto RX/TX) by default -- `txEnableDirect` Direct (true, default) or inverse (false) RX/TX pin control. +- `txEnablePin` controls transmit enable for MAX-485. Use `txEnableMode = TxEnableLow` if `txEnablePin` uses inverse logic (low when transmitting). Assign Serial port. txEnablePin controls transmit enable for MAX-485. diff --git a/src/ModbusRTU.cpp b/src/ModbusRTU.cpp index a00d609..0f215f6 100644 --- a/src/ModbusRTU.cpp +++ b/src/ModbusRTU.cpp @@ -109,7 +109,7 @@ void ModbusRTUTemplate::setInterFrameTime(uint32_t t_us) { _t = t_us; } -bool ModbusRTUTemplate::begin(Stream* port, int16_t txEnablePin, bool txEnableDirect) { +bool ModbusRTUTemplate::begin(Stream* port, int16_t txEnablePin, ModbusRTUTxEnableMode txEnableMode) { _port = port; _t = 1750UL; #if defined(MODBUSRTU_FLUSH_DELAY) @@ -117,9 +117,9 @@ bool ModbusRTUTemplate::begin(Stream* port, int16_t txEnablePin, bool txEnableDi #endif if (txEnablePin >= 0) { _txEnablePin = txEnablePin; - _direct = txEnableDirect; + _txEnableMode = txEnableMode; pinMode(_txEnablePin, OUTPUT); - digitalWrite(_txEnablePin, _direct?LOW:HIGH); + digitalWrite(_txEnablePin, _txEnableMode == TxEnableHigh ? LOW : HIGH); } return true; } @@ -136,16 +136,16 @@ bool ModbusRTUTemplate::rawSend(uint8_t slaveId, uint8_t* frame, uint8_t len) { #if defined(MODBUSRTU_REDE) if (_txEnablePin >= 0 || _rxPin >= 0) { if (_txEnablePin >= 0) - digitalWrite(_txEnablePin, _direct?HIGH:LOW); + digitalWrite(_txEnablePin, _txEnableMode == TxEnableHigh ? HIGH : LOW); if (_rxPin >= 0) - digitalWrite(_rxPin, _direct?HIGH:LOW); + digitalWrite(_rxPin, _txEnableMode == TxEnableHigh ? HIGH : LOW); #if !defined(ESP32) delayMicroseconds(MODBUSRTU_REDE_SWITCH_US); #endif } #else if (_txEnablePin >= 0) { - digitalWrite(_txEnablePin, _direct?HIGH:LOW); + digitalWrite(_txEnablePin, _txEnableMode == TxEnableHigh ? HIGH : LOW); #if !defined(ESP32) delayMicroseconds(MODBUSRTU_REDE_SWITCH_US); #endif @@ -165,16 +165,16 @@ bool ModbusRTUTemplate::rawSend(uint8_t slaveId, uint8_t* frame, uint8_t len) { delayMicroseconds(_t1 * MODBUSRTU_FLUSH_DELAY); #endif if (_txEnablePin >= 0) - digitalWrite(_txEnablePin, _direct?LOW:HIGH); + digitalWrite(_txEnablePin, _txEnableMode == TxEnableHigh ? LOW : HIGH); if (_rxPin >= 0) - digitalWrite(_rxPin, _direct?LOW:HIGH); + digitalWrite(_rxPin, _txEnableMode == TxEnableHigh ? LOW : HIGH); } #else if (_txEnablePin >= 0) { #if defined(MODBUSRTU_FLUSH_DELAY) delayMicroseconds(_t1 * MODBUSRTU_FLUSH_DELAY); #endif - digitalWrite(_txEnablePin, _direct?LOW:HIGH); + digitalWrite(_txEnablePin, _txEnableMode == TxEnableHigh ? LOW : HIGH); } #endif return true; diff --git a/src/ModbusRTU.h b/src/ModbusRTU.h index ce54348..a358817 100644 --- a/src/ModbusRTU.h +++ b/src/ModbusRTU.h @@ -8,6 +8,21 @@ #pragma once #include "ModbusAPI.h" +/** + * When the TX enable pin is used, specifies the logical level to enable the TX + */ +enum ModbusRTUTxEnableMode { + /** + * The TX enable pin should be high when transmitting + */ + TxEnableHigh, + + /** + * The TX enable pin should be low when transmitting + */ + TxEnableLow +}; + class ModbusRTUTemplate : public Modbus { protected: Stream* _port; @@ -15,7 +30,7 @@ class ModbusRTUTemplate : public Modbus { #if defined(MODBUSRTU_REDE) int16_t _rxPin = -1; #endif - bool _direct = true; // Transmit control logic (true=txEnableDirect, false=inverse) + ModbusRTUTxEnableMode _txEnableMode = TxEnableHigh; // Transmit control logic uint32_t _t; // inter-frame delay in uS #if defined(MODBUSRTU_FLUSH_DELAY) uint32_t _t1; // char send time @@ -46,13 +61,33 @@ class ModbusRTUTemplate : public Modbus { uint32_t calculateMinimumInterFrameTime(uint32_t baud, uint8_t char_bits = 11); void setInterFrameTime(uint32_t t_us); uint32_t charSendTime(uint32_t baud, uint8_t char_bits = 11); + + // Use `ModbusRTUTxEnableMode` overload instead template - bool begin(T* port, int16_t txEnablePin = -1, bool txEnableDirect = true); + [[deprecated]] + bool begin(T* port, int16_t txEnablePin = -1, bool txEnableDirect = true) { + return begin(port, txEnablePin, txEnableDirect ? TxEnableHigh : TxEnableLow); + } + template + bool begin(T* port, int16_t txEnablePin = -1, ModbusRTUTxEnableMode txEnableMode = TxEnableHigh); + #if defined(MODBUSRTU_REDE) + // Use `ModbusRTUTxEnableMode` overload instead template - bool begin(T* port, int16_t txEnablePin, int16_t rxEnablePin, bool txEnableDirect); + [[deprecated]] + bool begin(T* port, int16_t txEnablePin, int16_t rxEnablePin, bool txEnableDirect) { + return begin(port, txEnablePin, rxEnablePin, txEnableDirect ? TxEnableHigh : TxEnableLow); + } + template + bool begin(T* port, int16_t txEnablePin, int16_t rxEnablePin, ModbusRTUTxEnableMode txEnableMode); #endif - bool begin(Stream* port, int16_t txEnablePin = -1, bool txEnableDirect = true); + // Use `ModbusRTUTxEnableMode` overload instead + [[deprecated]] + bool begin(Stream* port, int16_t txEnablePin = -1, bool txEnableDirect = true) { + return begin(port, txEnablePin, txEnableDirect ? TxEnableHigh : TxEnableLow); + } + bool begin(Stream* port, int16_t txEnablePin = -1, ModbusRTUTxEnableMode txEnableMode = TxEnableHigh); + void task(); void client() { isMaster = true; }; inline void master() {client();} @@ -64,7 +99,7 @@ class ModbusRTUTemplate : public Modbus { }; template -bool ModbusRTUTemplate::begin(T* port, int16_t txEnablePin, bool txEnableDirect) { +bool ModbusRTUTemplate::begin(T* port, int16_t txEnablePin, ModbusRTUTxEnableMode txEnableMode) { uint32_t baud = 0; #if defined(ESP32) || defined(ESP8266) // baudRate() only available with ESP32+ESP8266 baud = port->baudRate(); @@ -78,20 +113,20 @@ bool ModbusRTUTemplate::begin(T* port, int16_t txEnablePin, bool txEnableDirect) _port = port; if (txEnablePin >= 0) { _txEnablePin = txEnablePin; - _direct = txEnableDirect; + _txEnableMode = txEnableMode; pinMode(_txEnablePin, OUTPUT); - digitalWrite(_txEnablePin, _direct?LOW:HIGH); + digitalWrite(_txEnablePin, _txEnableMode == TxEnableHigh ? LOW : HIGH); } return true; } #if defined(MODBUSRTU_REDE) template -bool ModbusRTUTemplate::begin(T* port, int16_t txEnablePin, int16_t rxEnablePin, bool txEnableDirect) { - begin(port, txEnablePin, txEnableDirect); +bool ModbusRTUTemplate::begin(T* port, int16_t txEnablePin, int16_t rxEnablePin, ModbusRTUTxEnableMode txEnableMode) { + begin(port, txEnablePin, txEnableMode); if (rxEnablePin > 0) { _rxPin = rxEnablePin; pinMode(_rxPin, OUTPUT); - digitalWrite(_rxPin, _direct?LOW:HIGH); + digitalWrite(_rxPin, _txEnableMode == TxEnableHigh ? LOW : HIGH); } } #endif