通過Java使用ModBus協議控制硬件


之前一直在說關於數據庫方面的問題,還沒有結束。

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM