之前一直在说关于数据库方面的问题,还没有结束。
但是因为公司最近一直在弄关于硬件对接方面的问题,所以穿插一项,说一说如何通过ModBus协议控制硬件设备。
首先,说一下需要的包
以下包和java包同级:
1、modbus4J.jar
2、rxtx-2.2pre2-bins.zip
3、RXTXcomm.jar
4、seroUtils.jar
以下包和src同级:
1、rxtxParallel.dll
2、rxtxSerial.dll
然后上代码:
public class Box {
//MODBUS的设备地址。 默认为254, 但由于次代码不支持254的地址,所以需要修改设备的地址为1.
private final static int SLAVE_ADDRESS=1;
//默认波特率为9600
private final static int BAUD_RATE = 9600;
public static void main(String[] args) throws ModbusInitException, InterruptedException{
SerialParameters serialParameters = new SerialParameters();
//设定MODBUS通讯的串行口
serialParameters.setCommPortId("COM4");
//设定成无奇偶校验
serialParameters.setParity(0);
//设定成数据位是8位
serialParameters.setDataBits(8);
//设定为1个停止位
serialParameters.setStopBits(1);
serialParameters.setPortOwnerName("Numb nuts");
//串行口上的波特率
serialParameters.setBaudRate(BAUD_RATE);
ModbusFactory modbusFactory = new ModbusFactory();
ModbusMaster master = modbusFactory.createRtuMaster(serialParameters);
try {
master.init();
//
readDiscreteInputTest(master,SLAVE_ADDRESS,0,8);//读取设备的光耦状态 8为光耦的数量,根据实际设备通道来写
readInputRegistersTest(master,SLAVE_ADDRESS,0,8);//读取设备的模拟量状态 8为模拟量的数量,根据实际设备通道来写
writeRegistersTest(master,SLAVE_ADDRESS, 0, new short[]{1,2,3,4,5,6, 7, 8, 9} );//写保持寄存器内容 不需要可以屏蔽
readHoldingRegistersTest(master,SLAVE_ADDRESS,0,2);//读取保持寄存器内容 不需要可以屏蔽
writeCoilTest(master,SLAVE_ADDRESS,0,true);//控制继电器输出 第1通道打开
Thread.sleep(1000);
writeCoilTest(master,SLAVE_ADDRESS,0,false);//控制继电器输出 第1通道关闭
Thread.sleep(1000);
writeCoilTest(master,SLAVE_ADDRESS,1,true);//控制继电器输出 第2通道打开
Thread.sleep(1000);
writeCoilTest(master,SLAVE_ADDRESS,1,false);//控制单个继电器输出 第2通道关闭
Thread.sleep(1000);
writeCoilsTest(master,SLAVE_ADDRESS,1,new boolean[]{false,true,false,true});//控制继电器输出 不能超过设备通道数量
Thread.sleep(1000);
writeCoilsTest(master,SLAVE_ADDRESS,1,new boolean[]{true,false,true,false});//控制继电器输出 不能超过设备通道数量
}
finally {
master.destroy();
}
}
/**
* 读光耦输入信号
* @param master 主站
* @param slaveId 从站地址
* @param start 起始地址的偏移量
* @param len 待读寄存器的个数
*/
private static void readDiscreteInputTest(ModbusMaster master, int slaveId, int start, int len) {
try {
ReadDiscreteInputsRequest request = new ReadDiscreteInputsRequest(slaveId, start, len);
ReadDiscreteInputsResponse response = (ReadDiscreteInputsResponse) master.send(request);
System.out.println("读光耦输入信号");
if (response.isException())
System.out.println("Exception response: message=" + response.getExceptionMessage());
else
System.out.println(Arrays.toString(response.getBooleanData()));
}
catch (ModbusTransportException e) {
e.printStackTrace();
}
}
/**
* 读输入寄存器上的内容
* @param master 主站
* @param slaveId 从站地址
* @param start 起始地址的偏移量
* @param len 待读寄存器的个数
*/
private static void readInputRegistersTest(ModbusMaster master, int slaveId, int start, int len) {
try {
ReadInputRegistersRequest request = new ReadInputRegistersRequest(slaveId, start, len);
ReadInputRegistersResponse response = (ReadInputRegistersResponse) master.send(request);
System.out.println("读输入寄存器上的内容");
if (response.isException())
System.out.println("Exception response: message=" + response.getExceptionMessage());
else
System.out.println(Arrays.toString(response.getShortData()));
}
catch (ModbusTransportException e) {
e.printStackTrace();
}
}
/**
* 读保持寄存器上的内容
* @param master 主站
* @param slaveId 从站地址
* @param start 起始地址的偏移量
* @param len 待读寄存器的个数
*/
private static void readHoldingRegistersTest(ModbusMaster master, int slaveId, int start, int len) {
try {
ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, start, len);
ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) master.send(request);
System.out.println("读保持寄存器上的内容");
if (response.isException())
System.out.println("Exception response: message=" + response.getExceptionMessage());
else
System.out.println(Arrays.toString(response.getShortData()));
}
catch (ModbusTransportException e) {
e.printStackTrace();
}
}
/**
* 批量写数据到保持寄存器
* @param master 主站
* @param slaveId 从站地址
* @param start 起始地址的偏移量
* @param values 待写数据
*/
public static void writeRegistersTest(ModbusMaster master, int slaveId, int start, short[] values) {
try {
WriteRegistersRequest request = new WriteRegistersRequest(slaveId, start, values);
WriteRegistersResponse response = (WriteRegistersResponse) master.send(request);
System.out.println("批量写数据到保持寄存器");
if (response.isException())
System.out.println("Exception response: message=" + response.getExceptionMessage());
else
System.out.println("Success");
}
catch (ModbusTransportException e) {
e.printStackTrace();
}
}
/**
* 控制单个继电器输出
* @param master 主站
* @param slaveId 从站地址
* @param start 起始地址的偏移量
* @param val 待写数据
*/
public static void writeCoilTest(ModbusMaster master, int slaveId, int start, boolean val) {
try {
WriteCoilRequest request = new WriteCoilRequest(slaveId, start, val);
WriteCoilResponse response = (WriteCoilResponse) master.send(request);
System.out.println("控制单个继电器输出");
if (response.isException())
System.out.println("Exception response: message=" + response.getExceptionMessage());
else
System.out.println("Success");
}
catch (ModbusTransportException e) {
e.printStackTrace();
}
}
/**
* 控制多个继电器输出
* @param master 主站
* @param slaveId 从站地址
* @param start 起始地址的偏移量
* @param values 待写数据
*/
public static void writeCoilsTest(ModbusMaster master, int slaveId, int start, boolean[] values) {
try {
WriteCoilsRequest request = new WriteCoilsRequest(slaveId, start, values);
WriteCoilsResponse response = (WriteCoilsResponse) master.send(request);
System.out.println("控制多个继电器输出");
if (response.isException())
System.out.println("Exception response: message=" + response.getExceptionMessage());
else
System.out.println("Success");
}
catch (ModbusTransportException e) {
e.printStackTrace();
}
}
}
如果是使用Maven,那么pom中增加如下代码
<dependency>
<groupId>com.example</groupId>
<artifactId>example</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/lib/seroUtils.jar</systemPath>
</dependency>
<dependency>
<groupId>com.example2</groupId>
<artifactId>example2</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/lib/modbus4J.jar</systemPath>
</dependency>
<dependency>
<groupId>com.example3</groupId>
<artifactId>example3</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/lib/RXTXcomm.jar</systemPath>
</dependency>
注意点:
serialParameters.setCommPortId("COM4");
这段代码中的COM4需要注意,需要和”我的电脑“--”属性“--”设备管理器“--”端口“中的参数一致。
以上代码,是对接某个品牌的继电器的代码,通过这次的对接,更加深刻了Java如何对接硬件设备。