Introduction to the protocol
Modbus protocol, first of all, from the literal understanding it includes Mod and Bus two parts, first of all, it is a bus, that is, bus protocol, bus means that there are hosts, there are slaves, these devices on the same bus.
Modbus supports a single master, multiple slaves, and up to 247 slave devices. About Mod, because this protocol was first used in PLC controllers, to be precise, PLC controllers from Modicon, which is where the Modbus name comes from. Later Modicon was acquired by Schneider Electric, the Modbus protocol was widely used in industrial controllers, HMIs and sensors, and was gradually accepted by other manufacturers, becoming the industry standard for communication protocols in the industrial field, and is now a commonly used method of connection between industrial electronic devices.
-
Each device (PLC, HMI, control panel, driver, motion control, input/output device) can use the Modbus protocol to initiate remote operation.
-
Mutual communication is possible on Modbus based on serial links and Ethernet TCP/IP networks.
-
Some gateways allow communication between several buses or networks using the Modbus protocol.
Glossary of terms
HDLC Advanced Data Link Control
HMI Human Machine Interface
IETF Internet Engineering Task Force
I/O Input/Output Devices
IP Internet protocol
MAC Medium Access Control
MB Modbus protocol
MBAP Modbus Protocol
with respect tocomputer bussupplementary note
Bus (Bus) is the public communication trunk between the various functional components of the computer to transmit information, it is composed of wires transmission harness, according to the type of information transmitted by the computer, the computer bus can be divided intodata bus (computer)、address bus (computing)cap (a poem)control bus, which are used to transmit data, data addresses and control signals, respectively.Bus is an internal structure, it is the cpu, memory, input and output devices to transfer information common channel, the host of the various components connected through the bus, external devices through the corresponding interface circuit and then connected to the bus, thus forming a computer hardware system. In a computer system, theCommon pathway for transferring information between componentsCalled a bus, a microcomputer is structured as a bus to connect various functional components.
The main reason why Modbus is widely used
- Standard and open, users can use the Modbus protocol free of charge and with confidence, without paying license fees or infringing intellectual property rights
- Modbus can support a variety of electrical interfaces, such as RS-232, RS-485, etc. It can also be transmitted over a variety of media, such as twisted pair, fiber optic, and wireless.
- The Modbus frame format is simple, compact and easy to understand. It is easy for users to use and simple for vendors to develop.
protocol version
Modbus protocol is currently defined based on serial () and Ethernet data transfer protocols, respectively, which serial (RS232, RS485, RS422, fiber optic, wireless, etc.) data transfer protocols are divided into Modbus RTU and Modbus ASCII serial link protocols, Ethernet data transfer protocols a Modbus TCP/IP protocol.
Of these, Modbus RTU is a compact, binary representation of data, and Modbus ASCII is a human-readable, verbose representation.
operating mode
The Modbus protocol uses Master/Slave communication. In TCP/IP transmission mode, the Master node is also called a client and the Slave node is also called a server. All host nodes connected to the bus have and only one Master node, the rest are Slave nodes.Optional addresses are 1~247, the address of each Slave node must be unique)。
Master-slave communication is request/answer based, and each time it communicates, the master node sends a request first (using broadcast mode, unicast mode), and the slave node responds to the command and answers as required, or reports an exception. When the master node does not send a request, the slave node will not send data by itself, and the slave nodes cannot communicate with each other (that is, the slave nodes cannot send requests to each other).
Regardless of whether the master node sends a broadcast or unicast command, practically all slave nodes will receive the command in its entirety. However, when a unicast command is sent, only the slave nodes with the same address as specified in the command will execute and respond to the command, and the other slave nodes will ignore the received command, whereas for a broadcast request, all the devices receiving the command will execute the command, but will not respond to the command to the master.
half-duplex communication
Modbus cannot communicate synchronously because of the request/response mechanism (synchronous communication requires both the sender and the receiver to send and receive data at the same tempo), and only one frame of data is transmitted on the bus at a time, which is a half-duplex communication.
Modbus does not support busy mechanism processing, for example, the host sends commands to the slave, if the slave is dealing with other tasks, then the slave will not be able to respond to the host, so you need to determine whether it is received properly by software.
Modbus message frame
The Modbus protocol defines a simple protocol data unit (PDU -> function code + data part) independent of the underlying communication layer. On a specific bus or network
The MODBUS protocol mapping enables the introduction of additional fields on the application data unit (ADU -> address field + function code + data + glitch).
Universal Data Frame
address field | function code | digital | error check digit |
---|---|---|---|
1 byte | 1 byte | N bytes | CRC: 16 bytes LRC: 1 byte |
Note: Each division field is represented in hexadecimal
-
address field
Slave device address, usually 1-247 is a valid address and 0 is a broadcast address (for receiving broadcast data from the host).Each slave must be uniquely addressed on the bus, and only slaves that match the address code sent by the host can respond with return data。
The master node selects the slave device that needs to communicate by placing the address of the slave node to be contacted into the address field of the message. When a slave node sends a response message, it needs to put its own address into the address field of the response so that the master node knows which device made the response.
-
function code
Indicates the type of data requested by the master node.
When the master node sends a message to the slave device, the function code will tell the slave device what actions it needs to perform. For example, go read the switch state of an input, read the data contents of a set of registers, etc.
-
digital
embodyregister addresscap (a poem)register dataet al. (and other authors)
-
error checking
The result of redundancy checking of data, CRC, LRC
Where the client sends a request to the server when the transaction processing is normal, fills the function code code designator in the function code, stating the action that the server needs to perform, and fills the data code area with specific requirements, such as the address and number of registers to read, and when the communication is normal, the server fills the function code area of the returned communication frame with an opcode, which is = the function code, and fills the data area of the communication frame with the returned sampling data .
When a transaction processing exception occurs, the server populates the function code of the returned communication frame with an error code that = function code + 0x80, i.e., the highest position of the function code, 1, indicates that an error occurred. The error code is also populated in the data segment that follows to indicate the specifics of the error in this communication.
Modbus ASCII Message Frames
Start Bit (😃 + ADU + End Character)
starting position | address field | function code | digital | LRC | closing character |
---|---|---|---|---|---|
: | 1 byte | 1 byte | N bytes | 1 byte | 2 characters |
Description: The message starts with:
Colon character (ASCII hexadecimal representation)3A
) begins with a carriage return line feed (CR LF
, ASCII hexadecimal representation0D
,0A
) End.
A typical ASCII message frame looks like this
starting position | address field | function code | digital | LRC | closing character |
---|---|---|---|---|---|
: | 2 characters | 2 characters | 0 to 2x252 characters | 2 characters | 2 characters |
Modbus RTU Message Frames
address field | function code | digital | CRC Low Byte | CRC high byte |
---|---|---|---|---|
1 byte | 1 byte | 0 to 252 bytes | 1 byte | 1 byte |
Explanation: In RTU communication mode, the byte data it sends is the original byte data, and there is no need to convert it again after the receiver receives it.
Attention:
- RTU mode, data frames must be separated from each other by at least 3.5 characters of time, and messages are differentiated by time intervals as follows:
- In RTU mode, the entire frame must be sent in a continuous stream of characters. If the idle interval between two characters is greater than 1.5 characters, the frame is considered incomplete and should be discarded by the receiving node.
-
character time
The so-called character time refers to the time it takes to transmit an ASCII character. An ASCII character contains 1 byte (8 bits), so transmitting a character takes the time of transmitting 8 data bits (so the character transmission time here refers to the time consumed in transmitting 1 byte of data).However, in reality, it takes more than 8 bits of time to transmit 1 byte of data, because in addition to the inherent 1 byte of data, there are also some auxiliary bits that need to be transmitted. For example, sending 1 byte requires a fixed start bit of 1 bit, 8 bits of data, 1 bit of parity (optional), 1 bit of stop bit, of which 8 bits of data are the real valid data, so there is the following formula to calculate the character time.
Character time = 1s / baud rate × total number of byte bits of the character.
For example: Fixed start bit 1 bit, data bit 8 bits, odd/even parity bit 1 bit, stop bit 1 bit, baud rate is 9600 bps, calculate the transmission time of a single character as:
character time = 1000 ms / 9600 × ( 1 + 8 + 1 + 1 ) = 1.145833 ms
Modbus TCP/IP Message Frames
MBAP message header + PDU (here the PDU is derived from the data link layer PDU)
Transaction meta-identifier | protocol identifier | lengths | unit identifier | function code | digital |
---|---|---|---|---|---|
2 bytes | 2 bytes | 2 bytes | 1 byte | 1 byte | N bytes |
The MBAP message header includes the following fields:
-
Transaction meta-identifier
Modbus request/response transaction identification, can be understood as the serial number of the message, generally after each communication should be added 1 to distinguish between different communication data messages.
-
protocol identifier
00
00
Indicates Modbus protocol Client startup -
lengths
Indicates the length of the data to follow, including the unit identifier and data field
-
unit identifier
The identifier of a remote slave node connected on a serial link or other bus, understood as the slave address
data encoding
MODBUS uses aBig-Endian
(Low address bit holds the highest valid byte) Indicates the address and data items. This means that when transmitting multiple bytes, the highest valid bit is sent first.
Example:
Register Size Value
16 0x1234 First byte sent is 0x12, then 0x34
Reference reading:Difference between Big Endian and Little Endiand
data model
In order to abstract the data accessible in the PLC, the Modbus protocol defines the concept of a data model, which defines four types of accessible data:
typology | adults and children | access authority | Element address prefix encoding | Element address range (0~65535) | Element address range (1~9999) |
---|---|---|---|---|---|
Output Coils (Coils) | 1 Bit | readable and writable | 0 | 000000~065535 | 00000~09999 |
Discrete Input | 1 Bit | read-only (computing) | 1 | 100000~165535 | 10000~19999 |
Input Registers | 16 Bit | read-only (computing) | 3 | 300000~365535 | 30000~39999 |
Holding Registers | 16 Bit | readable and writable | 4 | 400000~465535 | 40000~49999 |
In fact all of the above data types belong to the terminology used in Programmable Logic Controllers (PLCs) and can be simply understood as containers used to store data; coils are usually used to indicate switching states (e.g., on or off of a relay), while registers are usually used to store linear or non-linear numerical data.
Each data type in the data model allows a maximum of 65536 elements, with the address numbering of the elements starting at 0, hence the range of addresses: 0-65535.
It should be noted that 65536 is the maximum element range allowed by the Modbus protocol, and in practice, such a large storage area is generally not needed, so PLC manufacturers generally use an address range of 10000 or less.
Element address prefix encoding was introduced to simplify the correspondence between the data model and the device storage area.
Reference Links:/jf_52001760/article/details/130192127
A data model is an abstraction that must be mapped to real physical storage areas in order to be accessed in actual use.
The Modbus protocol allows devices to map each of the four data types to different storage blocks, each block is independent of the other, and different values can be read using different function codes, as shown in the following figure
Devices with multiple independent blocks
Equipment with only 1 block
function code
The function codes as a whole can be divided into three categories:
- public function code (computing)
- User-defined function codes ([65, 72], [100, 110])
- Reserved function codes
Common Function Codes
function code | name (of a thing) | Type of operation | Functional Description | |
---|---|---|---|---|
01 | Read coil status | bit operation | Read Bit (Read N bits) Read Slave Coil Registers | |
02 | Read Input Discrete | bit operation | Read Bit (Read N bits) Read Discrete Input Registers | |
03 | Read Holding Register | byte operation | Reads integer, character, status word, floating-point (reads N words) Reads holding registers | |
04 | Read Input Register | byte operation | Reads integer, status word, floating point (reads N words) Reads input registers | |
05 | Write Single Coil | bit operation | Write Bit (Write 1 bit) Write Coil Registers | |
06 | Write Single Holding Register | byte operation | Write integer, character, status word, floating-point (write a word) Write the holding registers, the | |
0F | Write multiple coils | bit operation | Write bits (write N bits) force the on/off of a sequence of consecutive logic coils. | |
10 | Write Multiple Holding Registers | bit operation | Write plastic, character, status, and floating-point (write N words) to load a specific binary value into a string of consecutive holding registers. |
Example of a request and answer message
Modbus RTU communication
Example 1: Write a single register. Write 1 data to 01 address device 0x0105 holding register: 0x0190
Host sends: 01 06 01 05 01 90 99 CB
Slave reply: 01 06 01 05 01 90 99 CB
Description: 01 indicates the slave address, 06 function code indicates writing a single holding register, 01 05 indicates the register address, 01 90 indicates the value written to the register, and 99 CB is the CRC checksum value.
It can be seen that when 1 register data is written, the data frame responded by the slave and the data frame sent by the master complete the same.
Attachment: CRC (Cyclic Redundancy Check) online calculation address:http:///
CRC-16 code implementation
# -*- coding:utf-8 -*-
'''The process of generating a CRC is as follows.
1. Load a 16-bit register into hexadecimal FFFF, which is called the CRC register.
2. The first 8-bit byte of the telegram is isochronized with the low byte of the above CRC register, and the result is placed in the CRC register.
3. Shift the CRC register 1 bit to the right (towards LSB (Least Significant Bit)) and zero the MSB (Most Significant Bit). The LSB is extracted and detected.
4. If LSB is 0, repeat step 3 (another shift).
If LSB is 1: Isolate polynomial value 0xA001 to CRC register (corresponding to 16-bit binary: 1010 0000 0000 0001).
5. Repeat steps 3 and 4 until 8 shifts are completed. When this is done, the complete operation of the 8-bit byte will be completed. 6.
6. Repeat steps 2 through 5 for the next byte in the message, and continue until all messages have been processed.
7. The final contents of the CRC register is the CRC value. 8.
8. When placing the CRC value in the message, the CRC high and low bytes need to be exchanged.
'''
def hex_char_to_int(hex_char).
'''
:param hex_char: hexadecimal representation of the character.
:return: bytes
'''
return "0123456789ABCDEF".find(hex_char)
def hex_string_to_bytes(hex_string).
'''
Convert a hexadecimal string to a byte array.
:param hex_string: hexadecimal representation of the string
:return: array of bytes
'''
hex_string = hex_string.strip()
hex_string_len = len(hex_string)
if not hex_string_len.
hex_string_len = len(hex_string)
byte_array = [] # store the final result
hex_string = hex_string.upper()
for i in range(int(hex_string_len/2)):: hex_char_to_int(hex_string[2*i])
high_digit = hex_char_to_int(hex_string[2*i]) # Get the upper 4 bits of the decimal representation.
low_digit = hex_char_to_int(hex_string[2*i+1]) # Get the low 4-bit decimal representation.
# high_digit shift left by 4 bits to form the high 4 bits of the byte
byte_array.append(high_digit << 4 | low_digit) # Get the byte through the different-or operation
if hex_string_len % 2 == 1: # Handle the last 1 character if it is not divisible
byte_array.append(0x00 | hex_char_to_int(hex_string[hex_string_len-1]))
return byte_array
def bytes_to_hex_string(byte_list).
'''
Bytes to hexadecimal string
:param byte_list: array of bytes
:return: The uppercase hex string representation of the byte array.
'''
hex_string = ""
for i in range(len(byte_list)):: [2:] Delete '0x'.
# [2:] Remove '0x'.
# zfill(2) 1 byte needs 2 hexadecimal characters to represent it, padded with zeros if not enough
hex_string += hex(byte_list[i] & 0xFF)[2:].zfill(2)
return hex_string.upper()
def calculate_crc(data).
reg_crc = 0xFFFF
for byte in data.
reg_crc ^= byte
for _ in range(8).
if reg_crc & 0x0001: # Here you can determine if the least significant bit is 0 by doing the sum operation, which is equivalent to step 3
reg_crc = (reg_crc >> 1) ^ 0xA001
else: reg_crc >> 1) ^ 0xA001
reg_crc >>= 1
return reg_crc.to_bytes(2, 'big') # return 2 bytes of data representing an integer in big endian mode
# Test
string_data = '01 06 01 05 01 90'
string_data = string_data.replace(' ', '')
byte_list = bytes(string_data, encoding='utf-8') # Note that you can't use code: implementation here, it's wrong and you won't get the right result
byte_list = hex_string_to_bytes(string_data)
crc_value = calculate_crc(byte_list)
print(crc_value, bytes_to_hex_string(crc_value)) # Output: b'\xcb\x99' CB99
final_crc = ''
for byte in crc_value.
final_crc = str(hex(byte)).lstrip('0x') + ' ' + final_crc
print(final_crc.upper()) # Output: 99 CB
Example 2: Write multiple registers. Write 3 registers data to 01 address device 0x0105, 0x0106, 0x0107 address holding registers: 0x1102, 0x0304, 0x0566
Master sends: 01 10 01 05 00 03 06 11 02 03 04 05 66 4A 12
Slave reply: 01 10 01 05 00 03 91 F5
Description: 01 Slave address, 10 Function code means write multiple holding registers, 01 05 means start address, 00 03 means write 3 registers, 06 means the amount of data is 6 bytes, 11 02/03 04/05 66 means the value of writing 3 registers respectively, 4A 12 means CRC checksum value.
Example 3: Read a single register. Read 01 address device 0x0105 hold register data.
Host sends: 01 03 01 05 00 01 95 F7
Slave reply: 01 03 02 56 78 87 C6
Description:
03 means read multiple registers, 0105 means start address, 00 01 means read 1 register
02 indicates 2 bytes and 56 78 indicates the data in the register.
Example 4: Read multiple registers. Read 01 address device 0x0105, 0x0106, 0x0107 address holding registers, a total of 3 registers data.
Host sends: 01 03 01 05 00 03 14 36
Slave reply: 01 03 06 11 22 33 44 55 66 2A 18
Description:
03 means read multiple registers, 01 05 means start address, 00 03 means read 3 registers
06 indicates 6 bytes and 11 22 33 44 55 66 indicates the data in the register.
Modbus ASCII
Example: To address 0x0405 of the slave device at address 0x01, write the value 0x1234 in the following message:
Host sends request: :01 06 04 05 12 34 AA <CR><LF>.
Description: 01 indicates the device address, 06 indicates writing a single holding register. 04 05 indicates the register address, 12 34 indicates the data, and AA indicates the LRC checksum value. The actual data to be checksummed does not contain the start character (:) and the end character (<CR><LF>
)。
P.S. Address for online calculation of LRC checksums (longitudinal redundancy checksums):http:///
LRC code implementation
string = '01 06 04 05 12 34'
total = 0
for item in (' '):
total += int(item, 16)
result = total % 256
hex_lrc_vale = hex(256 - result)
error code
Common error codes are shown in the table below.
exception code | name (of a thing) | descriptive |
---|---|---|
01 (01H) | illicit function | The function code received in the request is not an authorized operation of the slave device. The slave device may be in an error state and unable to process a particular request. |
02 (02H) | illicit data address (computing) | The data address received by the slave device is not an authorized address of the slave device. |
03 (03H) | illegal data value | The specified data is out of range or not allowed. |
04 (04H) | Slave equipment failure | The slave device failed to perform a requested operation because of an unfixable error |
05 (05H) | recognize | Acknowledgement The slave device has accepted the request and is processing it, but it takes a long time to perform these operations. Return this response to prevent a timeout error from occurring in the client (or master), and the client (or host) can continue to send polling program completion messages to confirm the completion of processing. |
06 (06H) | Slave equipment busy | The slave device is busy processing another command. The master device must send the request after the slave device is idle |
07 (07H) | negative confirmation | Slave device cannot execute the request sent by the master device |
08 (08H) | Storing parity errors | The slave device detected a parity error from the memory while trying to read the extended memory |
10 (0AH) | Unavailable gateway paths | Used in conjunction with a gateway to indicate that the gateway is unable to assign an internal communications path to the input port value output port for processing requests. Usually means that the gateway is misconfigured or overloaded |
11 (0BH) | Gateway target device response failure | Used with a gateway to indicate that no response is being received from the target device, usually meaning that the device is not in the network |