You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
External libraries have been replaced to improve compatibility. Sketch is now compatible with Arduino Nano, Uno and Mega. Ethernet chips W5100, W5200 and W5500.
Copy file name to clipboardExpand all lines: README.md
+25-8Lines changed: 25 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -43,11 +43,11 @@ Screenshots of the web interface:
43
43
## How can I build it myself?
44
44
Get the hardware. Cheap clones from China are sufficient:
45
45
46
-
* Arduino (Nano, Uno, possibly other)
47
-
* W5500-based Ethernet shield (for Nano, I recommend W5500 Ethernet Shield from RobotDyn)
46
+
* Arduino Nano, Uno or Mega (and possibly other)
47
+
*W5100, W5200 or W5500based Ethernet shield (for Nano, I recommend W5500 Ethernet Shield from RobotDyn)
48
48
* MAX485 module
49
49
50
-
Connect the hardware:
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
51
52
52
* Arduino <-> MAX485
53
53
@@ -57,7 +57,7 @@ Connect the hardware:
57
57
58
58
* Pin 6 <-> DE,RE
59
59
60
-
Download this repository (all *.ino files) and open arduino-modbus-rtu-tcp-gateway.ino in Arduino IDE. Download all required libraries (some of them are available in "library manager", other have to be manually downloaded from github). 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 :-)
60
+
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 :-)
61
61
62
62
## Where can I learn more about Modbus protocols?
63
63
@@ -74,15 +74,32 @@ The key to success is:
74
74
75
75
* use StreamLib https://github.com/jandrassy/StreamLib
76
76
* use F macros for your HTML code
77
-
* for W5500 ethernet modules, use Ethernet3 https://github.com/sstaub/Ethernet3
77
+
*use for() loop for repetitive code
78
78
* use POST method (rather than GET) for your webforms, see this tutorial https://werner.rothschopf.net/202003_arduino_webserver_post_en.htm
79
79
80
80
Big thanks to the authors of these libraries and tutorials!
81
81
82
-
## Background
82
+
## Limitations
83
83
84
-
This project started as a simple "playground" where I learned things. However, it evolved into more serious project: Modbus gateway in full compliance with Modbus standards. Later on, web interface was added as a demonstration of what a simple Arduino Nano is capable of.
84
+
#### Portability
85
85
86
-
Not everything could fit into the limited flash memory of Arduino Nano / Uno. The DHCP client within a ethernet library consumes too much memory. The code for automatic IP address is in the sketch but disabled by default. If you want to use auto IP functionality, you have to use something bigger (such as Arduino Mega) and uncomment #define ENABLE_DHCP. After that, new "Auto IP" setting will appear in the IP settings web interface.
86
+
The code was tested on Arduino Nano, Uno and Mega, ethernet chips W5100 and W5500. It may work on other platforms, but:
87
+
88
+
* The pseudorandom generator (for random MAC) is seeded through watch dog timer interrupt - this will work only on Arduino (credits to https://sites.google.com/site/astudyofentropy/project-definition/timer-jitter-entropy-sources/entropy-library/arduino-random-seed)
89
+
* The restart function will also work only on Arduino.
90
+
91
+
#### Ethernet socket
92
+
93
+
The default Ethernet.h library determines MAX_SOCK_NUM by microcontroller RAM (not by Ethernet chip type). So if you use W5500 (which has 8 sockets available) on Arduino Nano, only 4 sockets will be used. If you want to force the library to use 8 sockets, edit https://github.com/arduino-libraries/Ethernet/blob/master/src/Ethernet.h#L36
94
+
95
+
#### Memory
96
+
97
+
Not everything could fit into the limited flash memory of Arduino Nano / Uno. If you have a microcontroller with more memory (such as Mega), you can enable extra features in the main sketch by uncommenting:
98
+
99
+
* #define ENABLE_DHCP will allow you to set "Auto IP" via DHCP in the IP settings web interface. Leased IP is automatically renewed.
byte pduStart; // first byte of Protocol Data Unit (i.e. Function code)
58
62
if (localConfig.enableRtuOverTcp) pduStart = 1; // In Modbus RTU, Function code is second byte (after address)
59
63
else pduStart = 7; // In Modbus TCP/UDP, Function code is 8th byte (after address)
60
64
if (errorCode == 0) {
61
65
// Store in request queue: 2 bytes MBAP Transaction ID (ignored in Modbus RTU over TCP); MBAP Unit ID (address); PDUlen (func + data);remote IP; remote port; TCP client Number (socket) - 0xFF for UDP
byte pduStart; // first byte of Protocol Data Unit (i.e. Function code)
106
110
if (localConfig.enableRtuOverTcp) pduStart = 1; // In Modbus RTU, Function code is second byte (after address)
107
111
else pduStart = 7; // In Modbus TCP/UDP, Function code is 8th byte (after address)
108
112
if (errorCode == 0) {
109
113
// Store in request queue: 2 bytes MBAP Transaction ID (ignored in Modbus RTU over TCP); MBAP Unit ID (address); PDUlen (func + data);remote IP; remote port; TCP client Number (socket) - 0xFF for UDP
return0xFF; // reject: do nothing and return no error code
190
194
}
191
195
}
192
-
193
-
if (queueHeaders.isEmpty() == false && slavesResponding[address] == false) { // allow only one request to non responding slaves
196
+
if (queueHeaders.isEmpty() == false && getSlaveResponding(address) == false) { // allow only one request to non responding slaves
194
197
for (byte j = queueHeaders.size(); j > 0 ; j--) { // start searching from tail because requests to non-responsive slaves are usually towards the tail of the queue
195
198
if (queueHeaders[j - 1].uid == address) {
196
199
return0x0B; // return modbus error 11 (Gateway Target Device Failed to Respond) - usually means that target device (address) is not present
0 commit comments