核心依赖: modbus4j-3.0.4-SNAPSHOT.jar
1.获取tcp slave
-
//springboot项目实现CommandLineRunner类和@Component注解,程序启动时就加载tcp slave
-
@Component
-
public class Slave implements CommandLineRunner {
-
@Override
-
public void run(String... args) throws Exception {
-
createSalve();
-
}
-
private void createSalve() {
-
//创建modbus工厂
-
ModbusFactory modbusFactory = new ModbusFactory();
-
//创建TCP服务端
-
final ModbusSlaveSet salve = modbusFactory.createTcpSlave(true);
-
//向过程影像区添加数据
-
salve.addProcessImage(Register.getModscanProcessImage(1));
-
//获取寄存器
-
salve.getProcessImage(1);
-
try {
-
salve.start();
-
} catch (ModbusInitException e) {
-
e.printStackTrace();
-
}
-
}
-
}
2.创建线圈和寄存器
-
public class Register {
-
static BasicProcessImage getModscanProcessImage(int slaveId) {
-
BasicProcessImage processImage = new BasicProcessImage(slaveId);
-
processImage.setInvalidAddressValue(Short.MIN_VALUE);
-
//创建可读写开关量
-
processImage.setCoil(0, true);
-
processImage.setCoil(1, false);
-
processImage.setCoil(2, true);
-
processImage.setCoil(3, false);
-
processImage.setCoil(4, true);
-
processImage.setCoil(5, false);
-
processImage.setCoil(6, true);
-
processImage.setCoil(7, true);
-
processImage.setCoil(8, true);
-
processImage.setCoil(9, true);
-
//创建只读开关量
-
processImage.setInput(0, false);
-
processImage.setInput(1, false);
-
processImage.setInput(2, true);
-
processImage.setInput(3, false);
-
processImage.setInput(4, true);
-
processImage.setInput(5, true);
-
processImage.setInput(6, true);
-
processImage.setInput(7, false);
-
processImage.setInput(8, true);
-
processImage.setInput(9, true);
-
//创建 保持寄存器
-
processImage.setHoldingRegister(0, (short) 1);
-
processImage.setHoldingRegister(1, (short) 10);
-
processImage.setHoldingRegister(2, (short) 100);
-
processImage.setHoldingRegister(3, (short) 1000);
-
processImage.setHoldingRegister(4, (short) 10000);
-
processImage.setHoldingRegister(5, (short) 10000);
-
processImage.setHoldingRegister(6, (short) 10000);
-
processImage.setHoldingRegister(7, (short) 10000);
-
processImage.setHoldingRegister(8, (short) 10000);
-
processImage.setHoldingRegister(9, (short) 10000);
-
//创建 只读寄存器
-
processImage.setInputRegister(0, (short) 10000);
-
processImage.setInputRegister(1, (short) 1000);
-
processImage.setInputRegister(2, (short) 100);
-
processImage.setInputRegister(3, (short) 10);
-
processImage.setInputRegister(4, (short) 1);
-
processImage.setInputRegister(5, (short) 1);
-
processImage.setInputRegister(6, (short) 1);
-
processImage.setInputRegister(7, (short) 1);
-
processImage.setInputRegister(8, (short) 1);
-
processImage.setInputRegister(9, (short) 1);
-
processImage.addListener(new BasicProcessImageListener());
-
return processImage;
-
}
-
}
3.监听线圈和寄存器
-
public class BasicProcessImageListener implements ProcessImageListener {
-
@Override
-
public void coilWrite(int offset, boolean oldValue, boolean newValue) {
-
System.out.println("Coil at " + offset + " was set from " + oldValue + " to " + newValue);
-
}
-
@Override
-
public void holdingRegisterWrite(int offset, short oldValue, short newValue) {
-
System.out.println("HoldRrgister at " + offset + " was set from " + oldValue + " to " + newValue);
-
}
-
}
1.获取tcp master
-
public class TcpMaster {
-
private static ModbusFactory modbusFactory;
-
static {
-
if (modbusFactory == null) {
-
modbusFactory = new ModbusFactory();
-
}
-
}
-
/**
-
* 获取master
-
*
-
* @return master
-
*/
-
public static ModbusMaster getMaster() {
-
IpParameters params = new IpParameters();
-
params.setHost("localhost");
-
params.setPort(502);
-
params.setEncapsulated(true);
-
ModbusMaster master = modbusFactory.createTcpMaster(params, false);// TCP 协议
-
try {
-
//设置超时时间
-
master.setTimeout(1000);
-
//设置重连次数
-
master.setRetries(3);
-
//初始化
-
master.init();
-
} catch (ModbusInitException e) {
-
e.printStackTrace();
-
}
-
return master;
-
}
-
}
2.读取线圈和寄存器中的数据
-
@Component
-
public class Modbus4jReadUtils {
-
//获取master
-
private static ModbusMaster master = TcpMaster.getMaster();
-
/**
-
* 读(线圈)开关量数据
-
*
-
* @param slaveId slaveId
-
* @param offset 位置
-
* @return 读取值
-
*/
-
public boolean[] readCoilStatus(int slaveId, int offset, int numberOfBits)
-
throws ModbusTransportException, ErrorResponseException, ModbusInitException {
-
ReadCoilsRequest request = new ReadCoilsRequest(slaveId, offset, numberOfBits);
-
ReadCoilsResponse response = (ReadCoilsResponse) master.send(request);
-
boolean[] booleans = response.getBooleanData();
-
return valueRegroup(numberOfBits, booleans);
-
}
-
/**
-
* 开关数据 读取外围设备输入的开关量
-
*/
-
public boolean[] readInputStatus(int slaveId, int offset, int numberOfBits)
-
throws ModbusTransportException, ErrorResponseException, ModbusInitException {
-
ReadDiscreteInputsRequest request = new ReadDiscreteInputsRequest(slaveId, offset, numberOfBits);
-
ReadDiscreteInputsResponse response = (ReadDiscreteInputsResponse) master.send(request);
-
boolean[] booleans = response.getBooleanData();
-
return valueRegroup(numberOfBits, booleans);
-
}
-
/**
-
* 读取保持寄存器数据
-
*
-
* @param slaveId slave Id
-
* @param offset 位置
-
*/
-
public short[] readHoldingRegister(int slaveId, int offset, int numberOfBits)
-
throws ModbusTransportException, ErrorResponseException, ModbusInitException {
-
ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, offset, numberOfBits);
-
ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) master.send(request);
-
return response.getShortData();
-
}
-
/**
-
* 读取外围设备输入的数据
-
*
-
* @param slaveId slaveId
-
* @param offset 位置
-
*/
-
public short[] readInputRegisters(int slaveId, int offset, int numberOfBits)
-
throws ModbusTransportException, ErrorResponseException, ModbusInitException {
-
ReadInputRegistersRequest request = new ReadInputRegistersRequest(slaveId, offset, numberOfBits);
-
ReadInputRegistersResponse response = (ReadInputRegistersResponse) master.send(request);
-
return response.getShortData();
-
}
-
/**
-
* 批量读取 可以批量读取不同寄存器中数据
-
*/
-
public void batchRead() throws ModbusTransportException, ErrorResponseException, ModbusInitException {
-
BatchRead<Integer> batch = new BatchRead<Integer>();
-
batch.addLocator(0, BaseLocator.holdingRegister(1, 1, DataType.TWO_BYTE_INT_SIGNED));
-
batch.addLocator(1, BaseLocator.inputStatus(1, 0));
-
batch.setContiguousRequests(true);
-
BatchResults<Integer> results = master.send(batch);
-
System.out.println("batchRead:" + results.getValue(0));
-
System.out.println("batchRead:" + results.getValue(1));
-
}
-
private boolean[] valueRegroup(int numberOfBits, boolean[] values) {
-
boolean[] bs = new boolean[numberOfBits];
-
int temp = 1;
-
for (boolean b : values) {
-
bs[temp - 1] = b;
-
temp++;
-
if (temp > numberOfBits)
-
break;
-
}
-
return bs;
-
}
-
}
3.向线圈和寄存器中写数据
-
@Component
-
public class Modbus4jWriteUtils {
-
// 获取Master
-
private static ModbusMaster tcpMaster = TcpMaster.getMaster();
-
/**
-
* 写单个(线圈)开关量数据
-
*
-
* @param slaveId slave的ID
-
* @param writeOffset 位置
-
* @param writeValue 值
-
* @return 是否写入成功
-
*/
-
public boolean writeCoil(int slaveId, int writeOffset, boolean writeValue)
-
throws ModbusTransportException, ModbusInitException {
-
// 创建请求
-
WriteCoilRequest request = new WriteCoilRequest(slaveId, writeOffset, writeValue);
-
// 发送请求并获取响应对象
-
WriteCoilResponse response = (WriteCoilResponse) tcpMaster.send(request);
-
return !response.isException();
-
}
-
/**
-
* 写多个开关量数据(线圈)
-
*
-
* @param slaveId slaveId
-
* @param startOffset 开始位置
-
* @param bdata 写入的数据
-
* @return 是否写入成功
-
*/
-
public boolean writeCoils(int slaveId, int startOffset, boolean[] bdata)
-
throws ModbusTransportException, ModbusInitException {
-
// 创建请求
-
WriteCoilsRequest request = new WriteCoilsRequest(slaveId, startOffset, bdata);
-
// 发送请求并获取响应对象
-
WriteCoilsResponse response = (WriteCoilsResponse) tcpMaster.send(request);
-
return !response.isException();
-
}
-
/***
-
* 保持寄存器写单个
-
*
-
* @param slaveId slaveId
-
* @param writeOffset 开始位置
-
* @param writeValue 写入的数据
-
*/
-
public boolean writeRegister(int slaveId, int writeOffset, short writeValue)
-
throws ModbusTransportException, ModbusInitException {
-
// 创建请求对象
-
WriteRegisterRequest request = new WriteRegisterRequest(slaveId, writeOffset, writeValue);
-
// 发送请求并获取响应对象
-
WriteRegisterResponse response = (WriteRegisterResponse) tcpMaster.send(request);
-
return !response.isException();
-
}
-
/**
-
* 保持寄存器写入多个模拟量数据
-
*
-
* @param slaveId modbus的slaveID
-
* @param startOffset 起始位置偏移量值
-
* @param sdata 写入的数据
-
* @return 返回是否写入成功
-
*/
-
public boolean writeRegisters(int slaveId, int startOffset, short[] sdata)
-
throws ModbusTransportException, ModbusInitException {
-
// 创建请求对象
-
WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, sdata);
-
// 发送请求并获取响应对象
-
WriteRegistersResponse response = (WriteRegistersResponse) tcpMaster.send(request);
-
return !response.isException();
-
}
-
/**
-
* 根据类型写数据(如:写入Float类型的模拟量、Double类型模拟量、整数类型Short、Integer、Long)
-
*
-
* @param value 写入值
-
* @param dataType com.serotonin.modbus4j.code.DataType
-
*/
-
public void writeHoldingRegister(int slaveId, int offset, Number value, int dataType)
-
throws ModbusTransportException, ErrorResponseException, ModbusInitException {
-
// 类型
-
BaseLocator<Number> locator = BaseLocator.holdingRegister(slaveId, offset, dataType);
-
tcpMaster.setValue(locator, value);
-
}
-
}