通过Modbus RS485向智能电表发送指令无响应问题求助
问题排查:RS485转USB连接智能电表无响应
我尝试通过USB<->RS485转换器,使用jSerialComm库向智能电表发送指令获取total_deliver(kwh)数据。试过两种方式生成指令字节数组(str.getBytes()和二进制直接初始化),但都没收到电表响应,求帮忙排查。
主函数代码
public static void main(String[] args) throws UnsupportedEncodingException { SerialPort[] Device_ports = SerialPort.getCommPorts(); for (int i = 0; i < Device_ports.length; i++) { System.out.println("["+i+"]"+Device_ports[i].getSystemPortName()+":"+Device_ports[i].getDescriptivePortName()+"-"+Device_ports[i].getPortDescription()); } SerialPort mySerialPort = Device_ports[1]; String cmd = "0F04049E0002103B"; byte[] arr = {(byte) 00001111, 00000100, 00000100, (byte) 10011110, 00000000, 00000010, (byte) 00010000, (byte) 00111011}; byte[] byte_arr = cmd.getBytes(); for (int i = 0; i < 3; i++ ) { //Send(OpenPort(mySerialPort), arr); Send(OpenPort(mySerialPort), byte_arr); Recv(mySerialPort); } mySerialPort.closePort(); }
Send方法代码
public static void Send(SerialPort mySerialPort, byte[] arr) { if (mySerialPort.isOpen()) { System.out.println("Send "); for (int i = 0; i < arr.length; i++) { System.out.print(arr[i]+ " "); } mySerialPort.writeBytes(arr, arr.length); } else { System.out.println("Send fail"); } }
Recv方法代码
public static byte[] Recv(SerialPort mySerialPort) { byte[] readbuffer = new byte[25]; int counter = 0; try { while (counter <= 5) { while (mySerialPort.bytesAvailable() == 0 && counter <= 5) { Thread.sleep(20000); System.out.println("Receive: none"); counter++; } mySerialPort.readBytes(readbuffer, readbuffer.length); System.out.println("Receive: "); for (int i = 0; i < readbuffer.length; i++) { System.out.print(readbuffer[i]+" "); } } } catch (Exception e) { e.printStackTrace(); } return readbuffer; }
核心排查方向
指令字节数组生成错误
cmd.getBytes()是错误的转换方式:十六进制字符串"0F"会被转成ASCII字节0x30和0x46,而非电表需要的0x0F,必须手动将十六进制字符串转成对应字节。- 二进制初始化的
arr存在语法问题:Java中数字开头为0表示八进制,00001111实际是八进制数,转byte会溢出,正确写法应为(byte)0b00001111。
串口参数不匹配
- 智能电表通常要求固定的波特率、数据位、停止位和奇偶校验(如9600 8N1),代码未配置这些参数,jSerialComm默认参数可能与电表不符,需在打开串口前设置:
mySerialPort.setBaudRate(9600); mySerialPort.setNumDataBits(8); mySerialPort.setNumStopBits(1); mySerialPort.setParity(SerialPort.NO_PARITY);
- 智能电表通常要求固定的波特率、数据位、停止位和奇偶校验(如9600 8N1),代码未配置这些参数,jSerialComm默认参数可能与电表不符,需在打开串口前设置:
硬件与接线问题
- 确认USB-RS485转换器的A、B线与电表RS485接口对应正确,不可接反;部分转换器需外接电源或配置收发控制引脚。
接收逻辑问题
Thread.sleep(20000)等待时间过长,电表响应通常在几秒内,过长等待可能错过响应;readBytes一次性读取25字节,但电表响应长度更短,需处理实际读取的字节数;循环中重复调用OpenPort可能导致串口异常,应仅打开一次串口。
内容的提问来源于stack exchange,提问作者Aenbiarshy
相关产品推荐
相关产品推荐

