Freud's Blog

Stay hungry, stay foolish. 少年辛苦终身事,莫向光阴惰寸功。

Modbus-(五)-0x01 Read coils(读取线圈)

Posted on By Freud Kang

模拟器Server设置

Connection -> Connect

connect-setup

Setup -> Slave Definition

setup-definition

双击00000列第一行

setup-value

模拟器Client设置

Connection -> Connection Setup

connection-setup

Setup -> Read/Write Definition

read-write-definition

代码实现

Test0X01.java

package com.freud;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

/**
 * 
 * @author Freud Kang
 *
 */
public class Test0X01 {

	public static void main(String[] args) throws Exception {

		Socket socket = null;

		OutputStream os = null;
		InputStream is = null;

		try {
			socket = new Socket("localhost", 502);
			os = socket.getOutputStream();
			is = socket.getInputStream();
			byte[] request = new byte[] { 0X00, 0X01, 0X00, 0X00, 0X00, 0X06, 0X01, 0X01, 0X00,
					0X00, 0X00, 0X08 };
			System.out.println("Request : " + bytes2HexString(request));
			os.write(request);
			Thread.sleep(100);
			byte[] buffer = new byte[is.available()];
			is.read(buffer);
			String result = bytes2HexString(buffer);
			System.out.println("response : " + result);
		} finally {
			if (is != null) {
				is.close();
			}
			if (os != null) {
				os.flush();
				os.close();
			}
			if (socket != null) {
				socket.close();
			}
		}
	}

	public static String bytes2HexString(byte[] src) {
		StringBuilder stringBuilder = new StringBuilder();
		if (src == null || src.length <= 0) {
			return null;
		}
		for (int i = 0; i < src.length; i++) {
			int v = src[i] & 0xFF;
			String hv = Integer.toHexString(v).toUpperCase();
			if (hv.length() < 2) {
				stringBuilder.append(0);
			}
			stringBuilder.append(hv);
		}
		return stringBuilder.toString();
	}
}

/**
 * Request  : 000100000006010100000008 
 * response : 000100000003018101
 */

Request解析

0X00, 0X01, 0X00, 0X00, 0X00, 0X06, 0X01, 0X01, 0X00, 0X00, 0X00, 0X0A解析为16进制为000100000006010100000008

传输标志(2) 协议标志(2) 长度(2) 单元标志(1) 功能码(1) 起始地址(2) 线圈数(2)
0001 0000 0006 01 01 0000 0008

Response解析

返回字节数组解析为16进制为00010000000401010101

传输标志(2) 协议标志(2) 长度(2) 单元标志(1) 功能码(1) 数组个数(1) 线圈状态(1)
0001 0000 0004 01 01 01 01

其中数组个数01代表长度表示其后有1个字节。线圈状态01解析为2进制为00000001,分别代表线圈的对应状态

8 7 6 5 4 3 2 1
0 0 0 0 0 0 0 1

官方文档

Request

Request

Response

Response

*N = Quantity of Outputs / 8, if the remainder is different of 0 N = N+1

Error

Error

Example

Example

State Diagram

State Diagram



参考资料

Modbus官方文档:《Modbus_Application_Protocol_V1_1b3》

Modbus RTU和ASCII 协议解析 : http://www.modbustools.com/modbus.html