Modbus
Page Contents
References
Brief Intro
Big endian, application layer messaging protocol,
Request / reply protocol, services specified by function codes. A working slave must always respond with either an exception or a meaningful result.
Simple PDU (protocol data unit):
- 1-byte function code, followed by data:
{Function Code | Data}
Prodocol Data Unit (PDU) Func Code Data 1 byte n bytes - Built by client, sent to server,
- Max size when taking into account ADU header and footer = 256 bytes - server address (1 byte) - CRC (2bytes) = 253 bytes,
- Function tells server what action to perform,
- Three types:
- MODBUS request -
mb_req_pdu = {function_code, request_data}
, - MODBUS response -
mb_rsp_pdu = {function_code, response_data}
- Normal response echoes function code back, - MODBUS exception response -
mb_excep_rsp_pdu = {exception-function_code, exception-code}
- Exception response echoes function code | 0x80. Exception code is one of:Exception Code Meaning 0x01 Illegal function 0x02 Illegal data address 0x03 Illegal data value 0x04 Slave device failure 0x05 Acknowledge 0x06 Slave device busy 0x07 n/a 0x08 Memory parity error 0x09 n/a 0x0A Gateway path unavailable 0x0B Gateway target failed to respond
- MODBUS request -
- In PDU each data item address from 0 to 65535,
- 1-byte function code, followed by data:
ADU (application data unit):
- Wraps a PDU :
Additional address | PDU | Error check
=Additional address | Function Code | Data | Error check
, - Adds an address prefix and a CRC suffix,
- Lets MODBUS work on specific busses,
- Wraps a PDU :
-
The RTU frame over RS485 looks like this:
Prodocol Data Unit (PDU) Start Slave ID Func Code Data CRC Stop 3.5 bytes 1 byte 1 byte n bytes 2 bytes 3.5 bytes Application Data Unit (ADU) In the same way that the client device echoes back the function code to the master, it also echoes back it's own ID in its response. This is so that the master knows who the response is from [Ref].
Data model based on "tables", which are essentially registers of which there ar 4 types:
- Discrete inputs - RO single bits,
- Coils - RW single bits,
- Input registers - RO 16-bit words,
- Holding registers - RW 16-bit words,
"Tables" can overlay eachother or not,
For each table, protocol allows individual selection of 65,536 data items,
Function codes:
- Public:
- Well defined and guaranteed unique,
- Validated by MODBUS-IDA,
- Conformance test available,
- 1 - 64
Most commonly recognised ones are:
Function Code Register Type 1 Read Coil 2 Read Discrete Input 3 Read Holding Reigsters 4 Read Input Registers 5 Write Single Coil 6 Write Single Holding Register 15 Write Multiple Coils 16 Write Multiple Holding Registers - User definded:
- No guarantee of uniqueness,
- 65 - 72 or 100 to 110
- Reserved
- Public:
Some Public 16-bit Access Tables
A summary of some of the most common 16-bit tables (aka registers):
Register Operation | Code | Packet Description | |||||||||||||||||||||||||||||||||||||||
Read Holding Registers | 0x03 |
|
|||||||||||||||||||||||||||||||||||||||
Read Input Register | 0x04 |
|
|||||||||||||||||||||||||||||||||||||||
Write Single Register | 0x06 |
|
|||||||||||||||||||||||||||||||||||||||
Write Multiple Register | 0x10 |
|
|||||||||||||||||||||||||||||||||||||||
Read/Write Multiple Register | 0x23 | ||||||||||||||||||||||||||||||||||||||||
Mask Write Register | 0x22 | ||||||||||||||||||||||||||||||||||||||||
Read Exception Stats | 0x07 | ||||||||||||||||||||||||||||||||||||||||
Diagnostic | 0x08 | Subcodes 0x00-0x18, 0x20 |
Nice YouTube Tutorial
Command Line Utility - Modpoll
Modpoll is a command line based Modbus master simulator and test utility. It runs on Windows and Linux.
Example usage (note that unless specified modpoll
assumes register addresses start at 0x1):
modpoll [-0] -1 -a 101 -r 1 -c 5 -b 2400 -p none -t 4:hex COM5 [Write values] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ If not present then read else write ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 16-bit holding registers, display as hex ^ ^ ^ ^ Number of registers to read ^ ^ ^ Number of first register read ^ ^ Address of slave device ^ Poll only once then exit First reference is 0 (PDU addressing) instead 1
Complete help listing:
modpoll 3.6 - FieldTalk(tm) Modbus(R) Master Simulator Copyright (c) 2002-2018 proconX Pty Ltd Visit https://www.modbusdriver.com for Modbus libraries and tools. Usage: modpoll [OPTIONS] SERIALPORT|HOST [WRITEVALUES...] Arguments: SERIALPORT Serial port when using Modbus ASCII or Modbus RTU protocol COM1, COM2 ... on Windows /dev/ttyS0, /dev/ttyS1 ... on Linux HOST Host name or dotted IP address when using MDBUS/TCP protocol WRITEVALUES List of values to be written. If none specified (default) modpoll reads data. General options: -m ascii Modbus ASCII protocol -m rtu Modbus RTU protocol (default if SERIALPORT contains \ or COM) -m tcp MODBUS/TCP protocol (default otherwise) -m udp MODBUS UDP -m enc Encapsulated Modbus RTU over TCP -a # Slave address (1-255 for serial, 0-255 for TCP, 1 is default) -r # Start reference (1-65536, 100 is default) -c # Number of values to read (1-125, 1 is default) -t 0 Discrete output (coil) data type -t 1 Discrete input data type -t 3 16-bit input register data type -t 3:hex 16-bit input register data type with hex display -t 3:int 32-bit integer data type in input register table -t 3:mod 32-bit module 10000 data type in input register table -t 3:float 32-bit float data type in input register table -t 4 16-bit output (holding) register data type (default) -t 4:hex 16-bit output (holding) register data type with hex display -t 4:int 32-bit integer data type in output (holding) register table -t 4:mod 32-bit module 10000 type in output (holding) register table -t 4:float 32-bit float data type in output (holding) register table -i Slave operates on big-endian 32-bit integers -f Slave operates on big-endian 32-bit floats -e Use Daniel/Enron single register 32-bit mode (implies -i and -f) -0 First reference is 0 (PDU addressing) instead 1 -1 Poll only once only, otherwise every poll rate interval -l # Poll rate in ms, (1000 is default) -o # Time-out in seconds (0.01 - 10.0, 1.0 s is default) Options for MODBUS/TCP, UDP and RTU over TCP: -p # IP protocol port number (502 is default) Options for Modbus ASCII and Modbus RTU: -b # Baudrate (e.g. 9600, 19200, ...) (19200 is default) -d # Databits (7 or 8 for ASCII protocol, 8 for RTU) -s # Stopbits (1 or 2, 1 is default) -p none No parity -p even Even parity (default) -p odd Odd parity -4 # RS-485 mode, RTS on while transmitting and another # ms after