Arduino Master & ESP8266 Slave Modbus RTU (TTL)
In many occasions we have communicated our ESP8266 with Arduino via AT commands, but there are certain cases in which it is required to communicate both devices and send and/or receive large numbers of registers, almost in real time, although there are protocols such as I2c, and SPI with Libraries already implemented in arduino, we will use Modbus RTU, par excellence the communication protocol of field for devices of monitoring and control since it is easy its implementation, is safe, fast and approves of errors.
For our test we have an board Arduino MEGA 2560 R3 and Module ESP8266 12E, communicated via modbus RTU connected via direct 3-wire, TTL voltages 0 to 5v.
Arduino Configuration
In this case, it has been configured as a modbus master, using the second serial port (Serial1) of our board, since it has 4 ports available, modifications were made to the master modbus library based on previous tests.
Configuration ESP8266
It has been configured as a slave modbus, in this case the modbus protocol works through an extra serial port generated with the SoftwareSerial library, which allows to create a serial port generated by software with interruptions, it is recommended not to use it at very high speeds in this Case at 9600 bauds, for more information we recommend these previous references.
Tests
The test is simple, we will use 2 registers in this case to verify the reading and writing of both devices since in certain tests they show the devices or just reading or just typing.
Arduino Master & ESP8266 Slave Modbus RTU (TTL 0-5v )
Arduino IDE Code – Arduino
The arduino has a N/A button connected between pin 7 and GND configured as a pullup input, arduino read the status of pin 7 and send the value in the Holding Register [4].
Make a constant reading of the Holding Register [5] and print the value in the Serial terminal.
Note: Download of libraries at the end of the Post.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
/* * Modified by Trialcommand * More Tutorials: * Website http://trialcommand.com * In English: http://en.trialcommand.com */ #include <ModbusMaster232.h> ///#include <SoftwareSerial.h> // Modbus RTU pins D7(13),D8(15) RX,TX // Instantiate ModbusMaster object as slave ID 1 ModbusMaster232 node(1); void setup() { pinMode(7, INPUT_PULLUP); Serial.begin(9600); delay(100); node.begin(9600); // Modbus RTU delay(100); Serial.println("Connected "); Serial.println("Modbus RTU Master Online"); } void loop() { Serial.print("- Arduino Mega 2560 (Master Modbus RTU) -"); node.writeSingleRegister(4,digitalRead(7)); Serial.print("[4] "); Serial.print(digitalRead(7)); delay(20); Serial.print(" "); node.readHoldingRegisters(5, 1); Serial.print("[5] "); Serial.println(node.getResponseBuffer(0)); delay(20); node.clearResponseBuffer(); } |
Arduino IDE Code – ESP8266
The ESP8266 will read the Holding Register [4] and activate the pin 14 (D5) as an output and in turn has a led diode.
Send in the Holding Register [5] an integer with a random value from 1 to 9999.
Note: Note that between the two devices there is a shift of 1 position between the holding registers, this characteristic is common in modbus.
Note: Download of libraries at the end of the Post.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
<span style="color: #553333; font-family: 'Ubuntu Mono', monospace; font-size: 16px; line-height: 25.6px; white-space: pre-wrap;">/* * Trialcommand * More Tutorials: * Website http://trialcommand.com * In English: http://en.trialcommand.com * En Español: http://en.trialcommand.com */ #include <modbus.h> #include <modbusDevice.h> #include <modbusRegBank.h> #include <modbusSlave.h> #include // Modbus RTU pins D7(13),D8(15) RX,TX //SoftwareSerial swSer(13, 15, false, 256); modbusDevice regBank; modbusSlave slave; void setup() { pinMode(14, OUTPUT); //Assign the modbus device ID. regBank.setId(1); // Holding registers regBank.add(40005); regBank.add(40006); slave._device = ®Bank; Serial.begin(9600); delay(100); // Initialize the serial port for coms at 9600 baud slave.setBaud(9600); delay(100); Serial.println("Connected "); Serial.println("Modbus RTU Slave Online"); } void loop() { Serial.print("- ESP8266 12E (Slave Modbus RTU) -"); Serial.print(" [5] "); Serial.print(regBank.get(40005)); int value= regBank.get(40005); digitalWrite(14,value ); delay(20); Serial.print(" "); int value1 = random(1, 9999); Serial.print(" [6] "); Serial.println(value1); regBank.set(40006,value1); delay(20); slave.run(); }</span> |
Connections
Since the communication is TTL (0-5v), the serial1 of arduino mega 2560 pins (Tx1 -18) (Rx1 – 19) is connected to the port of ESP8266 created in softwareserial pins D7 (13), D8 (15) RX , TX, to cross RX -Tx between both, following individual descriptions.
ESP8266 12E NodeMCU
Arduino MEGA 2560 R3
Recommendations
We recommend a speed of 9600 bauds for a good performance, since the serial software library is not Uart own the ESP8266, at high speeds there could be bit errors in the frame, since it works with interruptions.
Modifications have been made to the master and slave libraries for this specific test, the modifications are especially in the assignments and declaration of the serial ports.
Conclusions
- We consider this an excellent solution given that a common and robust industrial protocol is used that would easily apply to communicate with an HMI, PLC, Meter, PAC, SCADA and / or other class of industrial controllers.
- A great benefit is the modbus is the facility of transmitting a large number of registers, it should be noted that it allows for 16-bit integer registers.
References
- ESP8266 two serial ports with SoftwareSerial library
- ESP8266 Slave Modbus RTU (RS232)
- ESP8266 Master Modbus RTU (RS232)
- Arduino Master Modbus RTU (RS232).
- Arduino Master Modbus RTU & PLC Panasonic RS232.