Browse our Blog. You will find multiple applications, solutions, code examples. Navigate using the tag cloud or search using specific criteris
How to use Modbus TCP Slave library with a PLC controller Arduino
To be able to follow easily the explanation of our Modbus TCP libraries for industrial PLC Arduino, first of all it would be interesting to have a look at the Modbus RTU post to understand better the characteristics and configurations of this type of communication on industrial Arduino devices.
On this blog we will introduce you to our libraries to be able to implement the Modbus TCP/IP Slave mode when working with programmable logic controllers. Basically it works in the same way as the Modbus RTU with some exceptions.
TCP - Transmission Control Protocol.
IP - Internet Protocol.
This is a Modbus variant used for communications over TCP/IP networks on industrial controllers for Arduino automation, connecting over port 502. It does not require a checksum calculation, as lower layers already provide checksum protection.
Modbus TCP encapsulates Modbus RTU request and response data packets in a TCP packet transmitted over standard Ethernet networks. The unit number is still included and its interpretation varies by application - the unit or slave address is not the primary means of addressing in TCP. The most important address here is the IP address. As we said before the standard port for Modbus TCP is 502, but port number can often be reassigned if you wish.
The checksum field normally found at the end of an RTU packet is omitted from the TCP packet. Checksum and error handling are handled by Ethernet in the case of Modbus TCP.
The TCP version of Modbus follows the OSI Network Reference Model. Modbus TCP defines the presentation and application layers in the OSI model. This type of transmission makes the definition of master and slave less obvious because Ethernet allows peer to peer communication. The meaning of client and server are better known entities in Ethernet based networking. In this context, the slave becomes the server and the master becomes the client. There can be more than one client obtaining data from server. In another words we can say that this means there can be multiple masters as well as multiple slaves. Instead of defining master and slave on a physical device by device basis, the designer will have to create logical associations between master and slave to define the roles.
Modbus TCP Slave with Arduino IDE
The Modbus TCP Slave module implements the Modbus TCP Slave funcionality.
#include <ModbusTCPSlave.h> ModbusTCPSlave slave;
The default TCP port is the 502 but you can change it with:
// Set the TCP listening port to 510 instead of 502 ModbusTCPSlave slave(510);
To map the coils, discrete inputs, holding registers and input registers addresses with the desired variables values, the module uses four variables arrays:
bool coils[NUM_COILS]; bool discreteInputs[NUM_DISCRETE_INPUTS]; uint16_t holdingRegistesr[NUM_HOLDING_REGISTERS]; uint16_t inputRegisters[NUM_INPUT_REGISTERS];
The lengths of these arrays depend on the application and the registers usages. Obviously, the names of the arrays also depend on your preferences.
To associate the registers arrays with the library, it is possible to use there functions in the
slave.setCoils(coils, NUM_COILS); slave.setDiscreteInputs(discreteInputs, NUM_DISCRETE_INPUTS); slave.setHoldingRegisters(holdingRegisters, NUM_HOLDING_REGISTERS); slave.setInputRegisters(inputRegisters, NUM_INPUT_REGISTERS);
It is not required to have all kind of registers mapping to work, only the ones used by the application.
To start Modbus TCP server, call the
begin function after the registers mapping. It is also possible to call the
begin function before the registers mapping. Remember to begin the Ethernet before the Modbus TCP Slave object in the
// Init the Ethernet Ethernet.begin(mac, ip); // Init the ModbusTCPSlave object slave.begin();
At this time the Modbus TCP server is running and the only important thing to do is to update the Modbus TCP Slave object often in the lllll function, and treat the registers mapping values too update variables, inputs and outputs.
// Update discrete inputs and input registers values discreteInputs = digitalRead(I0_7); inputRegisters = analogRead(I0_0); // ... // Update the ModbusTCPSlave object slave.update(); // Update coils and holding registers digitalWrite(Q0_0, coils); // ...