之前一直在說關於數據庫方面的問題,還沒有結束。
但是因為公司最近一直在弄關於硬件對接方面的問題,所以穿插一項,說一說如何通過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如何對接硬件設備。