Modbus协议比较简单,如果熟悉i/o操作的能很快上手。 基本点:
字节、字、位基本单位换算大端小端差异异步事件模型直接上代码:
```java package com.bool.test; import com.serotonin.modbus4j.BatchRead; import com.serotonin.modbus4j.BatchResults; import com.serotonin.modbus4j.ModbusFactory; import com.serotonin.modbus4j.ModbusMaster; import com.serotonin.modbus4j.code.DataType; import com.serotonin.modbus4j.exception.ErrorResponseException; import com.serotonin.modbus4j.exception.ModbusInitException; import com.serotonin.modbus4j.exception.ModbusTransportException; import com.serotonin.modbus4j.ip.IpParameters; import com.serotonin.modbus4j.locator.BaseLocator; public class ModbusTest { static ModbusFactory modbusFactory; static { if(modbusFactory == null) { modbusFactory = new ModbusFactory(); } } /** * 获取master * @return * @throws ModbusInitException */ public static ModbusMaster getMaster() throws ModbusInitException { IpParameters parameters = new IpParameters(); parameters.setHost("127.0.0.1"); parameters.setPort(502); ModbusMaster master = modbusFactory.createTcpMaster(parameters,false); master.init(); return master; } /** * 01 读取线圈状态 0x * @param slaveId * @param offset * @return * @throws ModbusInitException * @throws ErrorResponseException * @throws ModbusTransportException */ public static Boolean readCoilStatus(int slaveId,int offset) throws ModbusInitException, ErrorResponseException, ModbusTransportException { BaseLocator<Boolean> loc = BaseLocator.coilStatus(slaveId,offset); return getMaster().getValue(loc); } /** * 02 读离散输入状态 1x * @param slaveId * @param offset * @return * @throws ModbusInitException * @throws ErrorResponseException * @throws ModbusTransportException */ public static Boolean readInputStatus(int slaveId,int offset) throws ModbusInitException, ErrorResponseException, ModbusTransportException { BaseLocator<Boolean> loc = BaseLocator.inputStatus(slaveId,offset); return getMaster().getValue(loc); } /** * 03 读保持寄存器 4x * @param slaveId * @param offset * @param dataType * @return * @throws ModbusInitException * @throws ErrorResponseException * @throws ModbusTransportException */ public static Number readHoldingRegister(int slaveId,int offset,int dataType) throws ModbusInitException, ErrorResponseException, ModbusTransportException { BaseLocator<Number> loc = BaseLocator.holdingRegister(slaveId,offset,dataType); return getMaster().getValue(loc); } /** * 04 读输入寄存器 * @param slaveId * @param offset * @param dataType * @return * @throws ModbusInitException * @throws ErrorResponseException * @throws ModbusTransportException */ public static Number readInputRegister(int slaveId,int offset,int dataType) throws ModbusInitException, ErrorResponseException, ModbusTransportException { BaseLocator<Number> loc = BaseLocator.inputRegister(slaveId,offset,dataType); return getMaster().getValue(loc); } /** * 批量读取数据的方法 * @throws ModbusInitException * @throws ErrorResponseException * @throws ModbusTransportException */ public static void batchRead() throws ModbusInitException, ErrorResponseException, ModbusTransportException { BatchRead<Integer> batchRead = new BatchRead<Integer>(); batchRead.addLocator(0,BaseLocator.holdingRegister(1,1, DataType.FOUR_BYTE_FLOAT)); batchRead.addLocator(1,BaseLocator.inputStatus(1,0)); ModbusMaster master = getMaster(); batchRead.setContiguousRequests(false); BatchResults<Integer> results = master.send(batchRead); System.out.println(results.getValue(0)); System.out.println(results.getValue(1)); } public static void main(String[] args){ try{ // Boolean v011 = readCoilStatus(1,0); // Boolean v012 = readCoilStatus(1,1); // Boolean v013 = readCoilStatus(1,6); // System.out.println(v011); // System.out.println(v012); // System.out.println(v013); Number number = readHoldingRegister(1, 0, DataType.FOUR_BYTE_FLOAT); System.out.println(number); }catch (Exception e){ e.printStackTrace(); } } }常见的四个功能码: 0x01:读线圈 0x02:读离散量输入 0x03:读保持寄存器 0x04:读输入寄存器
在编写过程中可以用Modbus Slave来模拟服务器,Modbus poll模拟设备。