java對(duì)接Modbus協(xié)議代碼示例
一、Modbus含義
Modbus是一種單主站的主/從通信模式,它定義了一種通訊規(guī)范,用于在工業(yè)自動(dòng)化系統(tǒng)中實(shí)現(xiàn)設(shè)備之間的數(shù)據(jù)交換。Modbus網(wǎng)絡(luò)上只能有一個(gè)主站存在,主站在Modbus網(wǎng)絡(luò)上沒(méi)有地址,而從站的地址范圍為0-247,其中0為廣播地址,從站的實(shí)際地址范圍為1-247。
Modbus通信協(xié)議可以通過(guò)多種傳輸方式傳播,如RS232C、RS485、光纖和無(wú)線電等。它具有兩種串行傳輸模式,即ASCII和RTU,它們定義了數(shù)據(jù)如何打包和解碼的方式。一般來(lái)說(shuō),支持Modbus協(xié)議的設(shè)備都會(huì)支持RTU格式,通信雙方必須同時(shí)支持這兩種模式中的一種。
總結(jié)來(lái)說(shuō),Modbus是一種用于工業(yè)自動(dòng)化系統(tǒng)的通信協(xié)議,它定義了通信格式和規(guī)范,可以通過(guò)不同的傳輸方式進(jìn)行數(shù)據(jù)交換
二、Java如何對(duì)接Modbus
1、讀取數(shù)據(jù)
public class Modbus4jUtils { /** * 工廠。 */ static ModbusFactory modbusFactory; static { if (modbusFactory == null) { modbusFactory = new ModbusFactory(); } } /** * 獲取master * * @return * @throws ModbusInitException */ public static ModbusMaster getMaster() throws ModbusInitException { IpParameters params = new IpParameters(); params.setHost("你的硬件ip"); params.setPort("端口號(hào)"); // // modbusFactory.createRtuMaster(wapper); //RTU 協(xié)議 // modbusFactory.createUdpMaster(params);//UDP 協(xié)議 // modbusFactory.createAsciiMaster(wrapper);//ASCII 協(xié)議 ModbusMaster master = modbusFactory.createTcpMaster(params, false);// TCP 協(xié)議 master.init(); return master; } /** * 讀取[01 Coil Status 0x]類型 開(kāi)關(guān)數(shù)據(jù) * * @param slaveId * slaveId * @param offset * 位置 * @return 讀取值 * @throws ModbusTransportException * 異常 * @throws ErrorResponseException * 異常 * @throws ModbusInitException * 異常 */ public static Boolean readCoilStatus(int slaveId, int offset) throws ModbusTransportException, ErrorResponseException, ModbusInitException { // 01 Coil Status BaseLocator<Boolean> loc = BaseLocator.coilStatus(slaveId, offset); Boolean value = getMaster().getValue(loc); return value; } /** * 讀取[02 Input Status 1x]類型 開(kāi)關(guān)數(shù)據(jù) * * @param slaveId * @param offset * @return * @throws ModbusTransportException * @throws ErrorResponseException * @throws ModbusInitException */ public static Boolean readInputStatus(int slaveId, int offset) throws ModbusTransportException, ErrorResponseException, ModbusInitException { // 02 Input Status BaseLocator<Boolean> loc = BaseLocator.inputStatus(slaveId, offset); Boolean value = getMaster().getValue(loc); return value; } /** * 讀取[03 Holding Register類型 2x]模擬量數(shù)據(jù) * * @param slaveId * slave Id * @param offset * 位置 * @param dataType * 數(shù)據(jù)類型,來(lái)自com.serotonin.modbus4j.code.DataType * @return * @throws ModbusTransportException * 異常 * @throws ErrorResponseException * 異常 * @throws ModbusInitException * 異常 */ public static Number readHoldingRegister(int slaveId, int offset, int dataType) throws ModbusTransportException, ErrorResponseException, ModbusInitException { // 03 Holding Register類型數(shù)據(jù)讀取 BaseLocator<Number> loc = BaseLocator.holdingRegister(slaveId, offset, dataType); Number value = getMaster().getValue(loc); return value; } /** * 讀取[04 Input Registers 3x]類型 模擬量數(shù)據(jù) * * @param slaveId * slaveId * @param offset * 位置 * @param dataType * 數(shù)據(jù)類型,來(lái)自com.serotonin.modbus4j.code.DataType * @return 返回結(jié)果 * @throws ModbusTransportException * 異常 * @throws ErrorResponseException * 異常 * @throws ModbusInitException * 異常 */ public static Number readInputRegisters(int slaveId, int offset, int dataType) throws ModbusTransportException, ErrorResponseException, ModbusInitException { // 04 Input Registers類型數(shù)據(jù)讀取 BaseLocator<Number> loc = BaseLocator.inputRegister(slaveId, offset, dataType); Number value = getMaster().getValue(loc); return value; } }
2.寫(xiě)入數(shù)據(jù)
public class Modbus4jWriteUtils { static Log log = LogFactory.getLog(Modbus4jWriteUtils.class); /** * 工廠。 */ static ModbusFactory modbusFactory; static { if (modbusFactory == null) { modbusFactory = new ModbusFactory(); } } /** * 獲取tcpMaster * * @return * @throws ModbusInitException */ public static ModbusMaster getMaster() throws ModbusInitException { IpParameters params = new IpParameters(); params.setHost("你的硬件地址"); params.setPort("端口號(hào)"); ModbusMaster tcpMaster = modbusFactory.createTcpMaster(params, false); tcpMaster.init(); return tcpMaster; } /** * 寫(xiě) [01 Coil Status(0x)]寫(xiě)一個(gè) function ID = 5 * * @param slaveId * slave的ID * @param writeOffset * 位置 * @param writeValue * 值 * @return 是否寫(xiě)入成功 * @throws ModbusTransportException * @throws ModbusInitException */ public static boolean writeCoil(int slaveId, int writeOffset, boolean writeValue) throws ModbusTransportException, ModbusInitException { // 獲取master ModbusMaster tcpMaster = getMaster(); // 創(chuàng)建請(qǐng)求 WriteCoilRequest request = new WriteCoilRequest(slaveId, writeOffset, writeValue); // 發(fā)送請(qǐng)求并獲取響應(yīng)對(duì)象 WriteCoilResponse response = (WriteCoilResponse) tcpMaster.send(request); if (response.isException()) { return false; } else { return true; } } /** * 寫(xiě)[01 Coil Status(0x)] 寫(xiě)多個(gè) function ID = 15 * * @param slaveId * slaveId * @param startOffset * 開(kāi)始位置 * @param bdata * 寫(xiě)入的數(shù)據(jù) * @return 是否寫(xiě)入成功 * @throws ModbusTransportException * @throws ModbusInitException */ public static boolean writeCoils(int slaveId, int startOffset, boolean[] bdata) throws ModbusTransportException, ModbusInitException { // 獲取master ModbusMaster tcpMaster = getMaster(); // 創(chuàng)建請(qǐng)求 WriteCoilsRequest request = new WriteCoilsRequest(slaveId, startOffset, bdata); // 發(fā)送請(qǐng)求并獲取響應(yīng)對(duì)象 WriteCoilsResponse response = (WriteCoilsResponse) tcpMaster.send(request); if (response.isException()) { return false; } else { return true; } } /*** * 寫(xiě)[03 Holding Register(4x)] 寫(xiě)一個(gè) function ID = 6 * * @param slaveId * @param writeOffset * @param writeValue * @return * @throws ModbusTransportException * @throws ModbusInitException */ public static boolean writeRegister(int slaveId, int writeOffset, short writeValue) throws ModbusTransportException, ModbusInitException { // 獲取master ModbusMaster tcpMaster = getMaster(); // 創(chuàng)建請(qǐng)求對(duì)象 WriteRegisterRequest request = new WriteRegisterRequest(slaveId, writeOffset, writeValue); WriteRegisterResponse response = (WriteRegisterResponse) tcpMaster.send(request); if (response.isException()) { log.error(response.getExceptionMessage()); return false; } else { return true; } } /** * * 寫(xiě)入[03 Holding Register(4x)]寫(xiě)多個(gè) function ID=16 * * @param slaveId * modbus的slaveID * @param startOffset * 起始位置偏移量值 * @param sdata * 寫(xiě)入的數(shù)據(jù) * @return 返回是否寫(xiě)入成功 * @throws ModbusTransportException * @throws ModbusInitException */ public static boolean writeRegisters(int slaveId, int startOffset, short[] sdata) throws ModbusTransportException, ModbusInitException { // 獲取master ModbusMaster tcpMaster = getMaster(); // 創(chuàng)建請(qǐng)求對(duì)象 WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, sdata); // 發(fā)送請(qǐng)求并獲取響應(yīng)對(duì)象 ModbusResponse response = tcpMaster.send(request); if (response.isException()) { log.error(response.getExceptionMessage()); return false; } else { return true; } } /** * 寫(xiě)入數(shù)字類型的模擬量(如:寫(xiě)入Float類型的模擬量、Double類型模擬量、整數(shù)類型Short、Integer、Long) * * @param slaveId * @param offset * @param value * 寫(xiě)入值,Number的子類,例如寫(xiě)入Float浮點(diǎn)類型,Double雙精度類型,以及整型short,int,long * @param registerCount * ,com.serotonin.modbus4j.code.DataType * @throws ModbusTransportException * @throws ErrorResponseException * @throws ModbusInitException */ public static void writeHoldingRegister(int slaveId, int offset, Number value, int dataType) throws ModbusTransportException, ErrorResponseException, ModbusInitException { // 獲取master ModbusMaster tcpMaster = getMaster(); // 類型 BaseLocator<Number> locator = BaseLocator.holdingRegister(slaveId, offset, dataType); tcpMaster.setValue(locator, value); } }
總結(jié)
到此這篇關(guān)于java對(duì)接Modbus協(xié)議的文章就介紹到這了,更多相關(guān)java對(duì)接Modbus內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳談Java泛型中T和問(wèn)號(hào)(通配符)的區(qū)別
下面小編就為大家?guī)?lái)一篇詳談Java泛型中T和問(wèn)號(hào)(通配符)的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10SpringBoot多線程進(jìn)行異步請(qǐng)求的處理方式
這篇文章主要介紹了SpringBoot多線程進(jìn)行異步請(qǐng)求的處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜2021-12-12JavaSwing基礎(chǔ)之Layout布局相關(guān)知識(shí)詳解
上次我們說(shuō)到View的Mearsure流程,今天接著說(shuō)說(shuō)layout. 關(guān)于layout,很多朋友知道它是負(fù)責(zé)布局的,那么具體是怎么布局的?viewGroup和view的layout方法又有什么不同?一起來(lái)看看吧,需要的朋友可以參考下2021-05-05JavaWeb中導(dǎo)出excel文件的簡(jiǎn)單方法
下面小編就為大家?guī)?lái)一篇JavaWeb中導(dǎo)出excel文件的簡(jiǎn)單方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10基于Springboot+Netty實(shí)現(xiàn)rpc的方法 附demo
這篇文章主要介紹了基于Springboot+Netty實(shí)現(xiàn)rpc功能,在父項(xiàng)目中引入相關(guān)依賴結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02