Skip to content

Commit 278b989

Browse files
committed
support hardware automatic flow control
1 parent 574c3cc commit 278b989

File tree

4 files changed

+26
-21
lines changed

4 files changed

+26
-21
lines changed

README.md

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,20 @@ Screenshots of the web interface:
4141
- queue will accept only one requests to non-responding slaves
4242

4343
## How can I build it myself?
44-
Get the hardware. Cheap clones from China are sufficient:
44+
Get the hardware (cheap clones from China are sufficient) and connect together:
4545

46-
* Arduino Nano, Uno or Mega (and possibly other)
46+
* Arduino Nano, Uno or Mega (and possibly other). On Mega you have to configure Serial in ADVANCED SETTINGS in the sketch.
4747
* W5100, W5200 or W5500 based Ethernet shield (for Nano, I recommend W5500 Ethernet Shield from RobotDyn)
48-
* MAX485 module
49-
50-
Connect the hardware (on Nano and Uno, the sketch uses HW Serial, on Mega you have to configure Serial in ADVANCED SETTINGS in the sketch):
51-
52-
* Arduino <-> MAX485
53-
54-
* Tx1 <-> DI
55-
56-
* Rx0 <-> RO
57-
58-
* Pin 6 <-> DE,RE
48+
* TTL to RS485 module:
49+
- with hardware automatic flow control (recommended)
50+
Arduino <-> Module
51+
Tx1 <-> Tx
52+
Rx0 <-> Rx
53+
- with flow controlled by pin (such as MAX485 module):
54+
Arduino <-> MAX485
55+
Tx1 <-> DI
56+
Rx0 <-> RO
57+
Pin 6 <-> DE,RE
5958

6059
Download this repository (all *.ino files) and open arduino-modbus-rtu-tcp-gateway.ino in Arduino IDE. Download all required libraries (both are available in "library manager"). If you want, you can check the default factory settings (can be later changed via web interface) and advanced settings (can only be changed in sketch). Compile and upload your program to Arduino. Connect your Arduino to ethernet, connect your Modbus RTU slaves to MAX485 module. Use your web browser to access the web interface on default IP http://192.168.1.254 Enjoy :-)
6160

arduino-modbus-rtu-tcp-gateway/01-interfaces.ino

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
1616
maintainDhcp()
1717
- maintain DHCP lease
18-
18+
1919
maintainUptime
2020
- maintains up time in case of millis() overflow
2121
@@ -51,8 +51,10 @@ void startSerial() {
5151
charTimeout = 750;
5252
frameDelay = 1750;
5353
}
54-
pinMode(rs485ControlPin, OUTPUT);
55-
digitalWrite(rs485ControlPin, RS485_RECEIVE); // Init Transceiver
54+
#ifdef RS485_CONTROL_PIN
55+
pinMode(RS485_CONTROL_PIN, OUTPUT);
56+
digitalWrite(RS485_CONTROL_PIN, RS485_RECEIVE); // Init Transceiver
57+
#endif /* RS485_CONTROL_PIN */
5658
}
5759

5860
void startEthernet() {

arduino-modbus-rtu-tcp-gateway/03-modbus-rtu.ino

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@ MicroTimer txDelay;
2727
void sendSerial()
2828
{
2929
if (serialState == SENDING && rxNdx == 0) { // avoid bus collision, only send when we are not receiving data
30-
if (mySerial.availableForWrite() > 0 && txNdx == 0 && digitalRead(rs485ControlPin) == RS485_RECEIVE) {
31-
digitalWrite(rs485ControlPin, RS485_TRANSMIT); // Enable RS485 Transmit
30+
if (mySerial.availableForWrite() > 0 && txNdx == 0) {
31+
#ifdef RS485_CONTROL_PIN
32+
digitalWrite(RS485_CONTROL_PIN, RS485_TRANSMIT); // Enable RS485 Transmit
33+
#endif /* RS485_CONTROL_PIN */
3234
crc = 0xFFFF;
3335
mySerial.write(queueHeaders.first().uid); // send uid (address)
3436
calculateCRC(queueHeaders.first().uid);
3537
}
36-
while (mySerial.availableForWrite() > 0 && txNdx < queueHeaders.first().PDUlen && digitalRead(rs485ControlPin) == RS485_TRANSMIT) {
38+
while (mySerial.availableForWrite() > 0 && txNdx < queueHeaders.first().PDUlen) {
3739
mySerial.write(queuePDUs[txNdx]); // send func and data
3840
calculateCRC(queuePDUs[txNdx]);
3941
txNdx++;
@@ -57,7 +59,9 @@ void sendSerial()
5759
} else if (serialState == DELAY && txDelay.isOver()) {
5860
serialTxCount += queueHeaders.first().PDUlen + 1; // in Modbus RTU over TCP, queuePDUs already contains CRC
5961
if (!localConfig.enableRtuOverTcp) serialTxCount += 2; // in Modbus TCP, add 2 bytes for CRC
60-
digitalWrite(rs485ControlPin, RS485_RECEIVE); // Disable RS485 Transmit
62+
#ifdef RS485_CONTROL_PIN
63+
digitalWrite(RS485_CONTROL_PIN, RS485_RECEIVE); // Disable RS485 Transmit
64+
#endif /* RS485_CONTROL_PIN */
6165
if (queueHeaders.first().uid == 0x00) { // Modbus broadcast - we do not count attempts and delete immediatelly
6266
serialState = IDLE;
6367
deleteRequest();

arduino-modbus-rtu-tcp-gateway/arduino-modbus-rtu-tcp-gateway.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const int reqQueueSize = 256; // total length of TCP or UDP requests stor
4747
const byte maxSlaves = 247; // max number of Modbus slaves (Modbus supports up to 247 slaves, the rest is for reserved addresses)
4848
const int modbusSize = 256; // size of a MODBUS RTU frame (determines size of serialInBuffer and tcpInBuffer)
4949
#define mySerial Serial // define serial port for RS485 interface, for Arduino Mega choose from Serial1, Serial2 or Serial3
50-
const byte rs485ControlPin = 6; // Arduino Pin for RS485 Direction control
50+
#define RS485_CONTROL_PIN 6 // Arduino Pin for RS485 Direction control, disable if you have module with hardware flow control
5151
const byte ethResetPin = 7; // Ethernet shield reset pin (deals with power on reset issue of the ethernet shield)
5252
const byte scanCommand[] = {0x03, 0x00, 0x00, 0x00, 0x01}; // Command sent during Modbus RTU Scan. Slave is detected if any response (even error) is received.
5353

0 commit comments

Comments
 (0)