Modbus通讯协议(二)

您所在的位置:网站首页 modbus模拟器使用 Modbus通讯协议(二)

Modbus通讯协议(二)

#Modbus通讯协议(二)| 来源: 网络整理| 查看: 265

本文介绍通过Java程序向modbus slave模拟器工具读写数据。使用TCP的连接方式,modbus rtu通讯协议。

安装Modbus Slave

安装及使用请看上一篇文章:Modbus通讯协议(一)——测试工具ModbusPoll和ModbusSlave,本篇使用的是Modbus Slave 7.3.1 ,过低版本不支持TCP方式上使用modbus rtu

设置参数并开启连接

点击菜单Setup–>Resd/Write Definition 进行参数设置,Function 选01 在这里插入图片描述 点击菜单Connection–>connect F3进行连接,Connection选Modbus RTU Over TCP/IP 在这里插入图片描述

项目中添加依赖 org.rxtx rxtx 2.1.7

下载一依赖的SDK:net.wimpi.modbus

Java发送和读取工具类

工具类中有不同变量类型的读取和写数据的方法,方法要与modbus slave 寄存器设置的变量类型保持一致

package io.github.talelin.latticy.util; import net.wimpi.modbus.io.ModbusRTUTCPTransaction; import net.wimpi.modbus.msg.*; import net.wimpi.modbus.net.RTUTCPMasterConnection; import net.wimpi.modbus.procimg.InputRegister; import net.wimpi.modbus.util.BitVector; import java.net.InetAddress; public class ModbusRtuUtil { String ip="192.168.1.232"; int port=10000; int slaveID=254; RTUTCPMasterConnection Conn; int ErrorCnt=0; public void Init(String _ip,int _port,int _slaveID) { ip = _ip; port = _port; slaveID = _slaveID; } public boolean BeginConnect() { try { InetAddress addr = InetAddress.getByName(ip); // creat new tcp Conn = new RTUTCPMasterConnection(addr,port); Conn.setTimeout(3000); Conn.connect(); } catch (Exception e) { e.printStackTrace(); } return IsConnect(); } public boolean IsConnect() { if(ErrorCnt>10) { ErrorCnt = 0; if(Conn==null)return false; Conn.close(); Conn = null; } if(Conn==null)return false; return Conn.isConnected(); } public boolean DisConnect() { if(Conn==null)return false; Conn.close(); return IsConnect(); } //read the status of do . the count is the number of do channels public BitVector readDO(int count) { BitVector data = null; try { if(IsConnect()==false) { if(BeginConnect()==false)return data; } if(count==0)return data; //默认第一个继电器的地址0 ReadCoilsRequest req = new ReadCoilsRequest(0, count); req.setUnitID(slaveID); ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn); trans.setRequest(req); trans.execute(); ReadCoilsResponse res = ((ReadCoilsResponse) trans.getResponse()); data = res.getCoils(); ErrorCnt = 0; } catch (Exception e) { e.printStackTrace(); ErrorCnt++; } return data; } //read the coils status? 读取单个继电器状态 public int readSignalDO(int regAddr ) { int data = 0; try { if(IsConnect()==false) { if(BeginConnect()==false)return -1; } ReadCoilsRequest req = new ReadCoilsRequest(regAddr, 1); req.setUnitID(slaveID); ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn); trans.setRequest(req); trans.execute(); ReadCoilsResponse res = ((ReadCoilsResponse) trans.getResponse()); if(res.getCoils().getBit(0)){ data = 1; } ErrorCnt = 0; } catch (Exception e) { e.printStackTrace(); ErrorCnt++; } return data; } /** * 写入数据到真机的DO类型的寄存器上面 * * @param regAddr * @param value */ public void writeSignalDO(int regAddr, int value) { try { if(IsConnect()==false) { if(BeginConnect()==false)return ; } ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn); WriteCoilRequest req = new WriteCoilRequest(regAddr, value==0?false:true); req.setUnitID(slaveID); trans.setRequest(req); trans.execute(); ErrorCnt = 0; } catch (Exception e) { e.printStackTrace(); ErrorCnt++; } } /** * 查询Function 为Input Status的寄存器 * 读取光耦输入状态 * @param count */ public BitVector readDI(int count) { BitVector data = null; try { if(IsConnect()==false) { if(BeginConnect()==false)return data; } if(count==0)return data; // 第一个参数是寄存器的地址,第二个参数是读取多少个 ReadInputDiscretesRequest req = new ReadInputDiscretesRequest(0, count); // 这里设置的Slave Id, 读取的时候这个很重要 req.setUnitID(slaveID); ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn); trans.setRequest(req); // 执行查询 trans.execute(); // 得到结果 ReadInputDiscretesResponse res = (ReadInputDiscretesResponse) trans.getResponse(); data = res.getDiscretes(); ErrorCnt = 0; } catch (Exception e) { e.printStackTrace(); ErrorCnt++; } return data; } public int readSignalDI(int regAddr) { int data = 0; try { if(IsConnect()==false) { if(BeginConnect()==false)return -1; } // 第一个参数是寄存器的地址,第二个参数时读取多少个 ReadInputDiscretesRequest req = new ReadInputDiscretesRequest(regAddr, 1); // 这里设置的Slave Id, 读取的时候这个很重要 req.setUnitID(slaveID); ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn); trans.setRequest(req); // 执行查询 trans.execute(); // 得到结果 ReadInputDiscretesResponse res = (ReadInputDiscretesResponse) trans.getResponse(); if(res.getDiscretes().getBit(0)){ data = 1; } ErrorCnt = 0; } catch (Exception e) { e.printStackTrace(); ErrorCnt++; } return data; } public int[] readAI(int count) { int[] data = null; try { if(IsConnect()==false) { if(BeginConnect()==false)return data; } if(count==0)return data; //这里重点说明下,这个地址和数量一定要对应起来 ReadInputRegistersRequest req = new ReadInputRegistersRequest(0, count); //这个SlaveId一定要正确 req.setUnitID(slaveID); ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn); trans.setRequest(req); trans.execute(); ReadInputRegistersResponse res = (ReadInputRegistersResponse) trans.getResponse(); InputRegister[] rst = res.getRegisters(); if(rst.length!=count)return data; data = new int[count]; for(int i=0;i int data = 0; try { if(IsConnect()==false) { if(BeginConnect()==false)return -1; } //这里重点说明下,这个地址和数量一定要对应起来 ReadInputRegistersRequest req = new ReadInputRegistersRequest(regAddr, 1); //这个SlaveId一定要正确 req.setUnitID(slaveID); ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn); trans.setRequest(req); trans.execute(); ReadInputRegistersResponse res = (ReadInputRegistersResponse) trans.getResponse(); data = res.getRegisterValue(0); ErrorCnt = 0; } catch (Exception e) { e.printStackTrace(); ErrorCnt++; } return data; } public int readRegister(int regAddr) { int data = 0; try { if(IsConnect()==false) { if(BeginConnect()==false)return -1; } ReadMultipleRegistersRequest req = new ReadMultipleRegistersRequest(regAddr, 1); req.setUnitID(slaveID); ModbusRTUTCPTransaction trans = new ModbusRTUTCPTransaction(Conn); trans.setRequest(req); trans.execute(); ReadMultipleRegistersResponse res = (ReadMultipleRegistersResponse) trans.getResponse(); data = res.getRegisterValue(0); ErrorCnt = 0; } catch (Exception e) { e.printStackTrace(); ErrorCnt++; } return data; } } 测试 package io.github.talelin.latticy; import io.github.talelin.latticy.util.ModbusRtuUtil; import net.wimpi.modbus.util.BitVector; import org.junit.Test; public class ModbusTest { @Test public void handleDevice() throws Exception{ ModbusRtuUtil rtuUtil = new ModbusRtuUtil(); int MaxDONum = 4;//继电器数量 int MaxDINum = 4;//光耦输入数量 int MaxAINum = 4;//模拟量输入通道数量 //初始化设备 rtuUtil.Init("127.0.0.1", 502, 1); //ip,端口,slaveID 此处参数要与Modbus Slave中设置的一致 rtuUtil.BeginConnect(); System.out.println("写入数据到真机的DO类型的寄存器上面"); rtuUtil.writeSignalDO(0, 1);//Modbus Slave中Function Code选01 //读取DO 继电器 BitVector DOVal= rtuUtil.readDO(MaxDONum); //Modbus Slave中Function Code选01 // //读取DI // BitVector DIVal= rtuUtil.readDI(MaxDINum);//Modbus Slave中Function Code选02 // //读取AI // int[] AIVal =null; // if(MaxAINum>0) AIVal= rtuUtil.readAI(MaxAINum);//Modbus Slave中Function Code选04 if(MaxDONum>0)PrintfDODIVal("DO Status:",DOVal,MaxDONum); // if(MaxDINum>0) PrintfDODIVal("DI Status:",DIVal,MaxDINum); // if(MaxAINum>0)PrintfAIVal("AI Status:",AIVal); // Thread.sleep(1000); //equip.DisConnect(); } public static void PrintfDODIVal(String prev,BitVector val,int size) { System.out.println(prev); if(val==null)return; for(int i=0;i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3