
Modbus
Modbus是个独立的协议栈,不是建立在TCP/IP协议族上的。
基本概念H1
Modbus是通过主从关系实现的请求-响应协议。在主从关系中,通信总是成对发生(一个设备必须发起请求,然后等待响应),并且发起请求的设备(主设备)负责发起每次交互。通常,主设备是人机界面(HMI)或者监控和数据采集(SCADA)系统,而从设备是传感器、可编程逻辑控制器(PLC)或可编程自动化控制器(PAC)。这些请求和响应的内容以及发送这些消息的网络层由协议的不同层来定义。
协议层H2
在最初的做法中,Modbus是建立在串行端口之上的单一协议,因此它不能被分成多个层。随着时间的推移,该协议引入了不同的应用数据单元,来更改串行通信所用的数据包格式,或允许使用TCP/IP和用户数据报协议(UDP)网络。这样便实现了核心协议和网络层的分离,前者用于定义协议数据单元(PDU),后者用于定义应用数据单元(ADU)。
Modbus协议有下面的具体实现
- Modbus RTU 使用串口协议,采用二进制编码
- Modbus ASCII 使用串口协议,使用ASCII字符集编码
- Modbus TCP 使用TCP协议作为网络层
- Modbus UDP 使用UDP协议作为网络层
连接方式H2
Modbus协议的连接方式是有点特殊的,对于不通的网络层实现,连接方式也不太一样
- For Modbus Serial, up to 247 slave devices can be connected on a single serial network. It is important to that each slave device have a unique Unit ID.
- For Modbus Ethernet, a Modbus Master I/O Server can only connect to a single slave device. to communicate with multiple Modbus Ethernet slave devices, you must define a separate Master I/O Server for each device.
数据模型H2
Modbus的数据模型定义了4个存储区,每个存储区包含65536个数据项,但是不同的数据区数据项的长度是不一样的
| Primary tables | Object type | Type of | Comments |
|---|---|---|---|
| Discretes Input | Single bit | Read-Only | This type of data can be provided by an I/O system. |
| Coils | Single bit | Read-Write | This type of data can be alterable by an application program. |
| Input Registers | 16-bit word | Read-Only | This type of data can be provided by an I/O system |
| Holding Registers | 16-bit word | Read-Write | This type of data can be alterable by an application program. |
每个数据区的数据如何定义,Modbus协议是没有规定的,依赖于的应用程序本身。
数据项的地址范围是0-65535,但是存址是使用数据项的编号的,范围是1-65536。
协议数据单元H2
mb_req_pdu = {function_code, request_data},其中
- function_code = [1 byte] MODBUS function code
- request_data = [n bytes] This field is function code dependent and usually contains information such as variable references, variable counts, data offsets, sub-function codes etc.
mb_rsp_pdu = {function_code, response_data},其中
- function_code = [1 byte] MODBUS function code
- response_data = [n bytes] This field is function code dependent and usually contains information such as variable references, variable counts, data offsets, sub-function codes, etc.
Function Code描述H1
Request中的Quantity是指寄存器的数量,Coils、Input寄存器的数据类型为1个字节;Holder寄存器的数据列行为2个字节。
01 (0x01) Read CoilsH2

02 (0x02) Read Discrete InputsH2

03 (0x03) Read Holding RegistersH2


6.4 04 (0x04) Read Input RegistersH2

测试工具H1
- Modbus Slave Modbus主机仿真器,用于测试和调试Modbus从设备。该软件支持Modbus的RTU、ASCII、TCP/IP。用来帮助开发人员测试Modbus从设备,或者其它Modbus协议的测试和仿真。
- Modbus Poll Modbus从设备仿真器,可以仿真32个从设备/地址域。每个接口都提供了对EXCEL报表的OLE自动化支持。主要用来模拟Modbus从站设备,接收主站的命令包,回送数据包。帮助Modbus通讯设备开发人员进行Modbus通讯协议的模拟和测试,用于模拟、测试、调试Modbus通讯设备。
- Virtual Serial Port Driver 虚拟串口工具,不需要串口接线,提供虚拟的串口,适合学习和调试使用。
开发H1
Modbus4JH2
tsx
public static void main(String[] args) throws Exception {String commPortId = "COM1";int baudRate = 9600;int flowControlIn = 0;int flowControlOut = 0;int dataBits = 8;int stopBits = 2;int parity = 0;TestSerialPortWrapper wrapper = new TestSerialPortWrapper(commPortId, baudRate, flowControlIn, flowControlOut, dataBits, stopBits, parity);IpParameters ipParameters = new IpParameters();ipParameters.setHost("localhost");ModbusFactory modbusFactory = new ModbusFactory();ModbusMaster master = modbusFactory.createTcpMaster(ipParameters, false);try {master.init();int slaveId = 241;readCoilTest(master, slaveId, 98, 200);}}public static void readCoilTest(ModbusMaster master, int slaveId, int start, int len) {try {ReadCoilsRequest request = new ReadCoilsRequest(slaveId, start, len);ReadCoilsResponse response = (ReadCoilsResponse) master.send(request);if (response.isException())System.out.println("Exception response: message=" + response.getExceptionMessage());elseSystem.out.println(Arrays.toString(response.getBooleanData()));}catch (ModbusTransportException e) {e.printStackTrace();}}
参考H1
https://modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf
