模拟器Server设置
Connection -> Connect
Setup -> Slave Definition
Display -> Signed
代码实现
Test0X17.java
package com.freud;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
*
* @author Freud Kang
*
*/
public class Test0X17 {
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();
String request = "00010000000F0117000000020002000204001E0028";
System.out.println("Request : " + request);
os.write(hexStrToBytes(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 byte[] hexStrToBytes(String hexStr) {
if (hexStr.length() % 2 != 0) {
throw new IllegalArgumentException("十六进制的字符串长度必须是2的倍数!");
}
byte[] ret = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length(); i = i + 2) {
ret[i / 2] = (byte) Integer.parseInt(hexStr.substring(i, i + 2), 16);
}
return ret;
}
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 : 00010000000F0117000000020002000204001E0028
* response : 000100000007011704000A0014
*/
Request解析
发送字节数组解析为16进制为00010000000F0117000000020002000204001E0028
传输标志(2) | 协议标志(2) | 长度(2) | 单元标志(1) | 功能码(1) | 读开始地址(2) | 读寄存器个数(2) | 写开始地址(2) | 写寄存器个数(2) | 写字节个数(1) | 写寄存器值(4) |
0001 | 0000 | 000F | 01 | 17 | 0000 | 0002 | 0002 | 0002 | 04 | 00 1E 00 28 |
其中写寄存器值001E0028
转换为十进制为30 40
Response解析
返回字节数组解析为16进制为000100000007011704000A0014
传输标志(2) | 协议标志(2) | 长度(2) | 单元标志(1) | 功能码(1) | 字节个数(1) | 读取寄存器值(4) |
0001 | 0000 | 0007 | 01 | 17 | 04 | 00 0A 00 14 |
其中读取寄存器值000A0014
转换为十进制为10 20
模拟器Server控制前
模拟器Server控制结果
官方文档
Request
*N = Quantity to Write
Response
*N’ = Quantity to Read
Error
Example
State Diagram
参考资料
Modbus官方文档:《Modbus_Application_Protocol_V1_1b3》
Modbus RTU和ASCII 协议解析 : http://www.modbustools.com/modbus.html