Protocol: Modbus
Getting Started
This page is the reference section for the Modbus Protocol in SHIP.
If you’re just getting started, you may want to start with App Note AN0500 – Using Modbus in SHIP: A Step-by-Step Tutorial.
What is Modbus?
Modbus is a very simple master/slave communications protocol operated traditionally over point-to-point RS232 or multi-drop RS485 networks.
It is designed to be operated in half-duplex mode, with one device, and one device only, designated the master that is responsible for polling and directing all the slaves. Slaves cannot spontaneously initiate data messages: they must be polled by the master. Similarly, slaves cannot talk peer-to-peer to another slave. The master must poll one slave, gather data, and re-send it to another.
Every slave on a given network must have a unique identification number (slave ID). Slaves may respond to more than one slave ID (acting as multiple slaves in one physical device), but no slave IDs can overlap. Slaves can be simple devices, like sensors or actuators, often with a tiny DIP switch to manually select from a range of slave IDs. More sophisticated slaves can implement front-panel selectable slave IDs.
The master has no id (although in some networks 0 is reserved for the master). This is because the slaves do not need to address the master explicitly, they always just respond to requests from the master.
Protocol Modes
Modbus is a very simple set of packet protocol. When the packet is decoded, regardless of the protocol transmission “mode”, it contains exactly the same message contents. Software decoders can be written with various decoder/encoder front ends for the different transmission modes and the rest of the software can be unified.
When Modbus is transmitted over RS232, RS422, and RS485 type serial networks, there are two standard transmission modes: ASCII or RTU (binary). The serial network must be designated ASCII or RTU. You cannot mix modes on the same network. There is no negotiation process and auto-baud capabilities do not exist. The type must be set by the network/system designer once and all devices on the network must be manually set to the correct speed.
When Modbus is transmitted over TCP/IP, the Modbus TCP mode is used.
For more information on the protocol, see the list of modbus references.
ASCII
MODBUS_SLAVE_ASCII is a human-readable ASCII transmission format and is easy to debug on a sniffer terminal device (a device that only listens but does not drive the RS232 or RS485 cable) since a terminal program would display the packets. It is very easy to parse in software, with unique start (‘:’) and end-packet characters (CR-LF), but because every byte is sent as a hex-ascii value (for example, an ‘a’ is sent as two bytes ‘2’ and ‘1’, representing hex 0x21 which is an ‘a’), it is half the speed of a binary transmission protocol.
Every master-initiated packet looks like this:
Modbus ASCII Packet Format (Master Packet) | ||
---|---|---|
Name | Bytes | Description |
Start | 1 | ":" (ASCII 0x3A) start-of-packet character |
Slave ID | 2 | ASCII of slave id (for example, slave id 0x2F is sent as two characters "2" and "F") |
Function Code | 2 | ASCII of command (called a "function code", or "FCxx" where xx is the code) |
Data | varies | Command specific data as a sequence of ASCII characters (2 per byte), in MSB format |
Checksum | 2 | Simple 8-bit checksum |
End | 2 | CR-LF sequence terminating packet |
Every slave responds with a modified version of the packet:
Modbus ASCII Packet Format (Slave Response) | ||
---|---|---|
Name | Bytes | Description |
Start | 1 | ":" (ASCII 0x3A) start-of-packet character |
Slave ID | 2 | ASCII of slave id |
Function Code | 3 | ASCII of command with high bit set if error |
Data | varies | Command specific response data |
Checksum | 2 | Simple 8-bit checksum |
End | 2 | CR-LF sequence terminating packet |
Modbus ASCII mode has several advantages:
- easy to debug on a sniffer terminal device (a device that only listens but does not drive the RS232 or RS485 cable) since a terminal program can display the packets in a human readable format, 1 packet per line
- easy to parse and stay synchronized in software, with a unique start character (‘:’) and end sequence (CR-LF)
- smaller/simpler software for the 8-bit checksum calculation than the 16-bit CRC used in RTU mode
and a few disadvantages:
- half the speed of RTU: every byte is sent as a hex-ASCII value , it is half the speed of a binary transmission protocol.
- less robust than RTU: an 8-bit checksum is far more susceptible to missing errors than the RTU’s 16-bit CRC
RTU
Modbus RTU is a binary transmission format. Every master-initiated packet looks like this:
Modbus RTU Packet Format (Master Packet) | ||
---|---|---|
Name | Bytes | Description |
Slave ID | 1 | The byte ID of the slave to target |
Function Code | 1 | The command (called a "function code", or "FCxx" where xx is the code) |
Data | varies | Command specific data as a sequence of bytes, in MSB format where appropriate |
CRC | 2 | 16-bit CRC |
Every slave responds with a modified version of the packet:
Modbus ASCII Packet Format (Slave Response) | ||
---|---|---|
Name | Bytes | Description |
Slave ID | 1 | The byte ID of the slave to target |
Function Code | 1 | Same FC as master requested; high bit is set if error |
Data | varies | Command specific response data as a sequence of bytes, in MSB format where appropriate |
CRC | 2 | 16-bit CRC |
Modbus RTU mode has advantages:
- faster than Modbus ASCII: one byte per character rather than two
- more robust to noise than ASCII: the 16-bit CRC is better at detecting bit errors than the ASCII 8-bit checksum
and a few disadvantages:
- trickier to write software to stay synchronized in a noisy environment: no start/end sequences
- CRC requires more software on the slave to generate/test
- harder to to debug on a sniffer terminal device: typically needs a packet decoder program
TCP
Although not currently natively supported in SHIP, Modbus packets can also be sent over TCP/IP connections to enable server and cloud connectivity. Often the SIM will be set up as a Modbus master controlling a slave (such as a motor, pump, or PLC). With the addition of a very simple UART to WiFi bridge and a server-based Modbus slave implementation, the SIM can now be “cloud connected” and send and receive information from a server. In this mode, for example, the SIM can supply a cloud-based application with motor or equipment status and both the GUI on the SIM and the cloud application can control the equipment.
Modbus TCP Packet Format (Master Packet) | ||
---|---|---|
Name | Bytes | Description |
Sequence # | 2 | Since TCP/IP can deliver out-of-order, this enables in-order handling by master and slave. |
Protocol ID | 2 | 0x0000 means Modbus/TCP |
Length | 2 | Number of bytes after this point in the packet |
Slave ID | 1 | Slave Address 0x01..0xFE (0xFF if not used) |
Function Code | 1 | Standard Modbus Function Code |
Data | (varies) | FCxx specific command or response data |
Modbus TCP Packet Format (Slave Response) | ||
---|---|---|
Name | Bytes | Description |
Sequence # | 2 | Same sequence number from master packet. |
Protocol ID | 2 | 0x0000 means Modbus/TCP |
Length | 2 | Number of bytes after this point in the packet |
Slave ID | 1 | Slave Address 0x01..0xFE (0xFF if not used) |
Function Code | 1 | Modbus Function Code (high bit set if error) |
Data | (varies) | FCxx specific command or response data |
Function Codes
Wikipedia has a complete list of common Modbus Function Codes. However the basic codes are:
Modbus Basic Function Codes | |||
---|---|---|---|
FC | Name | Description | SHIPEngine Support |
0x01 | Read Coil | Get the state of one Boolean output | v4.0.180+ |
0x02 | Read Input | Get the state of one Boolean input | v4.0.180+ |
0x03 | Read Holding Registers | Get the values of a sequence of 16-bit outputs | v4.0.180+ (single mode) |
0x04 | Read Input Registers | Get the values of a sequence of 16-bit inputs | v4.0.180+ (single mode) |
0x05 | Force Single Coil | Set the state of one Boolean output | v4.0.180+ |
0x06 | Preset Single Register | Set the values of one 16-bit output | v4.0.180+ |
0x0F | Force Multiple Coil | Set the state of a sequence of Boolean outputs | - |
0x10 | Preset Multiple Registers | Set the values of a sequence of 16-bit outputs | - |
Function codes are often represented as “FCxx”, for example FC01. Note that when represented in this fashion, the code is always represented in decimal (base 10). So FC16, for instance, is function code 16 decimal or 0x10 hex: the Preset Multiple Registers command.
Slave Variables
Each slave has a (typically fixed) set of boolean and/or 16-bit inputs and outputs that it uses. The documentation for the slave will publish a table of these “variables” and permitted FCs.
For example a simple modbus-enabled temperature sensor might have a very simple published interface:
Example Temperature Sensor Modbus Interface | |||||
---|---|---|---|---|---|
Variable | Address | Type | Direction | FCs Permitted | Description |
Temperature | 0x2000 | 16-bit | input | FC02 | Current temperature in degrees C (signed 16-bit value) |
Calibrate | 0x4000 | Boolean | output | FC05 | When sent as true, will force a calibration cycle in the sensor |
The direction is the Modbus direction with respect to the master, so an “input” is an input to the master and an “output” is an output to a slave from the master.
This is a very simple command-set to implement in the sensor. The addresses could even be ignored, since there is only one 16-bit input and one Boolean output — any FC02 could fetch the temperature and any FC05 could force the recalibration.
Programmable Logic Controllers (PLCs), such as the inexpensive Automation Direct Click Series publish a complete list of all addresses, data types, and function codes permitted to access the PLC.
Polling
Modbus is a single-master/multiple-slave protocol. While the actual physical transmission mechanism (e.g. RS232, Ethernet, WiFi, RS485) may be half or full duplex, the protocol is a command-response protocol.
The master initiates a request by sending a command packet to a slave. The targeted slave then replies with a response packet. There is a 1:1 relationship between master and slave packets (unless an error occurs).
Within each packet (master request or slave response), when used over a serial channel, the packet is not interactive. There is no concept of byte-by-byte ACK/NAK type traffic. The whole request is pushed in one direction in one burst and the whole reply is pushed back in one burst.
In the Modbus TCP protocol, since TCP/IP can get packets mixed up and out of sequence depending on network latency, there is an extra sequence number in each packet. Each end is responsible for (optionally) handling packets out of order.
The master is therefore responsible for polling all its slaves, and within each slave all the variables it needs to know. There is no way for a slave to send an alarm or value proactively — it must be polled by the master at a frequency acceptable to the event. If a slave has an input Boolean indicating, for example, it is overheating, then the master must poll the slave (and specifically, get this Boolean value) at a sufficient rate such that the latency of display/response is acceptable for the system.
Such algorithms in the master can get fairly sophisticated. For example, the master can have a “slow poll” mechanism where every slave and every input/output value is polled over some period of time. When an output needs to be changed, the master can interleave a set request to the target slave in between the slow poll cycle requests. A simpler master might poll all connected slaves and only once per polling cycle allow a “set” to be sent out to a slave. There are many variations possible, including fast polling of a specific slave combined with slow polling of other slaves. Or, for example, a specific variable at a slave (like the overheat example above) might be polled at one frequency while the rest of the slaves/variables are polled at another.
For this reason, master-side software implementations may be larger and more complicated than slave-side software implementations. SHIPEngine supports both master and slave modes, including support for poll timing at any level and even simultaneous master and slave support over separate communications channels.
References
More Information
- Simply Modbus is an excellent learning reference
- Wikipedia has a fairly good overview of Modbus
- Modbus.org if you want to be overwhelmed
Debugging Tools
- Simply Modbus has inexpensive PC-Based software for simulating a master/slave
- FrontLine Test Equipment has a PC-USB sniffer device (with software) for RS232 and 485 cables (this is what we use at Serious)
- Modpoll Modbus® Polling Tool is a free command line based Modbus master simulator and test utility
- Modbus Poll master simulator is a Modbus master simulator with a excellent user interface. Support RTU and ASCII modes.
Embedded Software
- Serious SHIPWare No-cost C source code on Micrium, FreeRTOS, and Segger for Serious Integrated Modules (SIM owners only, registration necessary)
- Protocessor Free source for Microchip PIC18 MCUs (registration necessary)
- Micrum µC/Modbus Commercial, robust, and fully supported; many MCU ports