第一次搭建项目很多不熟悉各种不知道,在此记录不熟悉的modbus部分以供参考,至于JAVA部分就不详谈了,毕竟以后还是要进一步学习的,现在这些幼稚的记录了以后反而尴尬
modbus主机从机都可以发起连接的,这次项目我们是用主机主动连接从机的方式(从机连接主机的童鞋需要在主机端创建一个Listener监听来自从机的请求,用ModbusTCPListener),项目比较繁杂我单独把modbus部分的主机端代码拎出来了,这里用到了jamodbus.jar,UnityRegister.java是一个大神写的不过不知道具体是谁写的但是依然很感谢他,既然有包包,问题就在于如何调用,没有教程和文档只得自己去看源码,modbusutil虽然我只写了一点点代码,但是我这个水平真心累,给不是专门做这些的童鞋一个模版,少走一些弯路,至少主机主动连接从机的代码可以直接拿过去当工具包用了
package Modbus;
import net.wimpi.modbus.ModbusException;
import net.wimpi.modbus.io.ModbusTCPTransaction;
import net.wimpi.modbus.msg.*;
import net.wimpi.modbus.net.TCPMasterConnection;
import net.wimpi.modbus.util.BitVector;
import java.net.InetAddress;
/**
* Created by wxy on 2016/9/27.
*/
public class ModbusUtil {
public static TCPMasterConnection connectClient(String ip, int port) {
try {
InetAddress addr = InetAddress.getByName(ip);
TCPMasterConnection con = new TCPMasterConnection(addr);
con.setPort(port);
con.connect();
return con;
} catch (Exception e) {
System.out.print("connectClient");
return null;
}
}
public static void disconnectClient(TCPMasterConnection con){
con.close();
}
public static int[] readHoldingRegister(int slaveId, int address, int count, TCPMasterConnection con){
try {
int[] data = new int[count];
ReadMultipleRegistersRequest req = new ReadMultipleRegistersRequest(address, count);
req.setUnitID(slaveId);
ModbusTCPTransaction trans = new ModbusTCPTransaction(con);
trans.setRequest(req);
trans.execute();
ReadMultipleRegistersResponse res = (ReadMultipleRegistersResponse) trans.getResponse();
for(int i = 0; i < count; i++){
data[i] = res.getRegisterValue(i);
}
return data;
} catch (ModbusException e) {
return null;
}
}
public static boolean readCoil(int slaveId, int address, int count, TCPMasterConnection con){
try {
boolean coil = false;
ReadCoilsRequest req = new ReadCoilsRequest(address, count);
req.setUnitID(slaveId);
ModbusTCPTransaction trans = new ModbusTCPTransaction(con);
trans.setRequest(req);
trans.execute();
ReadCoilsResponse res = (ReadCoilsResponse) trans.getResponse();
for(int i = 0 ; i < count ; i ++) {
coil = res.getCoilStatus(i);
}
return coil;
} catch (ModbusException e) {
return true;
}
}
public static void writeHoldingRegister(int slaveId, int address, int value, TCPMasterConnection con){
try {
ModbusTCPTransaction trans = new ModbusTCPTransaction(con);
UnityRegister register = new UnityRegister(value);
WriteSingleRegisterRequest req = new WriteSingleRegisterRequest(address, register);
/*WriteSingleRegisterResponse response = new WriteSingleRegisterResponse();*/
req.setUnitID(slaveId);
trans.setRequest(req);
System.out.println("ModbusSlave: FC" + req.getFunctionCode() + " ref=" + req.getReference() + " value=" + register.getValue());
/*System.out.println();*/
trans.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void writeCoil(int slaveId, int address, boolean value, TCPMasterConnection con){
try {
ModbusTCPTransaction trans = new ModbusTCPTransaction(con);
WriteCoilRequest req = new WriteCoilRequest(address,value);
/*WriteSingleRegisterResponse response = new WriteSingleRegisterResponse();*/
req.setUnitID(slaveId);
trans.setRequest(req);
System.out.println("ModbusSlave: value=" + value);
/*System.out.println();*/
trans.execute();
} catch (ModbusException e) {
e.printStackTrace();
}
}
}
函数名字取得都很简单,分别是连接,断开连接,读写保持寄存器,读写线圈,参数也是一眼看出来,就不说了
直接调用函数就可以读写寄存器了,是不是很简单
这里可以用Modbus Slave这个软件测试
先设置slave,这里function代表寄存器种类,可以看modbus协议。设置一下ID和address即可
点击连接设置一下协议和端口,我这边用的TCP/IP
随便写个函数测试一下好不好用吧