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模拟设备。