广东学校网站建设公司,网站推广的方法有sem推广,企业网站意思,网站的竞争对手java实现Modbus通信
参考链接: https://www.cnblogs.com/ioufev/p/10831289.html https://blog.csdn.net/ioufev/article/details/100554691
Modbus协议
Modbus由MODICON公司于1979年开发#xff0c;是一种工业现场总线协议标准。1996年施耐德公司推出基于以太网TCP/IP的Mo…java实现Modbus通信
参考链接: https://www.cnblogs.com/ioufev/p/10831289.html https://blog.csdn.net/ioufev/article/details/100554691
Modbus协议
Modbus由MODICON公司于1979年开发是一种工业现场总线协议标准。1996年施耐德公司推出基于以太网TCP/IP的Modbus协议ModbusTCP。
Modbus协议是一项应用层报文传输协议包括ASCII、RTU、TCP三种报文类型。
标准的Modbus协议物理层接口有RS232、RS422、RS485和以太网接口采用master/slave方式通信。
Modbus和RS485的关系Modbus是协议物理层接口有RS232、RS422、RS485和以太网接口几种
仿真软件和程序下载: 百度网盘提供
使用jlibmodbus
maven配置
dependencygroupIdcom.intelligt.modbus/groupIdartifactIdjlibmodbus/artifactIdversion1.2.9.7/version/dependencyjava代码从Modbus读取数据
package com.ioufev;import java.net.InetAddress;import com.intelligt.modbus.jlibmodbus.Modbus;
import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusNumberException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusProtocolException;
import com.intelligt.modbus.jlibmodbus.master.ModbusMaster;
import com.intelligt.modbus.jlibmodbus.master.ModbusMasterFactory;
import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters;/*** Hello world!**/
public class App {public static void main(String[] args) {try {// 设置主机TCP参数TcpParameters tcpParameters new TcpParameters();// 设置TCP的ip地址InetAddress adress InetAddress.getByName(192.168.3.16);// TCP参数设置ip地址// tcpParameters.setHost(InetAddress.getLocalHost());tcpParameters.setHost(adress);// TCP设置长连接tcpParameters.setKeepAlive(true);// TCP设置端口这里设置是默认端口502tcpParameters.setPort(Modbus.TCP_PORT);// 创建一个主机ModbusMaster master ModbusMasterFactory.createModbusMasterTCP(tcpParameters);Modbus.setAutoIncrementTransactionId(true);int slaveId 1;//从机地址int offset 0;//寄存器读取开始地址int quantity 10;//读取的寄存器数量try {if (!master.isConnected()) {master.connect();// 开启连接}// 读取对应从机的数据readInputRegisters读取的写寄存器功能码04int[] registerValues master.readInputRegisters(slaveId, offset, quantity);// 控制台输出for (int value : registerValues) {System.out.println(Address: offset , Value: value);}} catch (ModbusProtocolException e) {e.printStackTrace();} catch (ModbusNumberException e) {e.printStackTrace();} catch (ModbusIOException e) {e.printStackTrace();} finally {try {master.disconnect();} catch (ModbusIOException e) {e.printStackTrace();}}} catch (RuntimeException e) {throw e;} catch (Exception e) {e.printStackTrace();}}
}
使用modbus4j
maven配置
dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.13-beta-3/versionscopetest/scope/dependencydependencygroupIdcom.infiniteautomation/groupIdartifactIdmodbus4j/artifactIdversion3.0.3/version/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-lang3/artifactIdversion3.9/version/dependency!-- 若想引用modbus4j需要引入下列repository id:ias-snapshots id:ias-releases 两个 使用默认仓库下载不要使用阿里云仓库--repositoriesrepositoryreleasesenabledfalse/enabled/releasessnapshotsenabledtrue/enabled/snapshotsidias-snapshots/idnameInfinite Automation Snapshot Repository/nameurlhttps://maven.mangoautomation.net/repository/ias-snapshot//url/repositoryrepositoryreleasesenabledtrue/enabled/releasessnapshotsenabledfalse/enabled/snapshotsidias-releases/idnameInfinite Automation Release Repository/nameurlhttps://maven.mangoautomation.net/repository/ias-release//url/repository/repositoriesjava使用modbus4j读取数据
package com.ioufev;import com.serotonin.modbus4j.BatchRead;
import com.serotonin.modbus4j.BatchResults;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.ip.IpParameters;
import com.serotonin.modbus4j.locator.BaseLocator;/*** modbus通讯工具类,采用modbus4j实现**/
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(10.211.55.4);params.setPort(502);//// modbusFactory.createRtuMaster(wapper); //RTU 协议// modbusFactory.createUdpMaster(params);//UDP 协议// modbusFactory.createAsciiMaster(wrapper);//ASCII 协议ModbusMaster master modbusFactory.createTcpMaster(params, false);// TCP 协议master.init();return master;}/*** 读取[01 Coil Status 0x]类型 开关数据** 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 StatusBaseLocatorBoolean loc BaseLocator.coilStatus(slaveId, offset);Boolean value getMaster().getValue(loc);return value;}/*** 读取[02 Input Status 1x]类型 开关数据** 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 StatusBaseLocatorBoolean loc BaseLocator.inputStatus(slaveId, offset);Boolean value getMaster().getValue(loc);return value;}/*** 读取[03 Holding Register类型 2x]模拟量数据** param slaveId* slave Id* param offset* 位置* param dataType* 数据类型,来自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类型数据读取BaseLocatorNumber loc BaseLocator.holdingRegister(slaveId, offset, dataType);Number value getMaster().getValue(loc);return value;}/*** 读取[04 Input Registers 3x]类型 模拟量数据** param slaveId* slaveId* param offset* 位置* param dataType* 数据类型,来自com.serotonin.modbus4j.code.DataType* return 返回结果* throws ModbusTransportException* 异常* throws ErrorResponseException* 异常* throws ModbusInitException* 异常*/public static Number readInputRegisters(int slaveId, int offset, int dataType)throws ModbusTransportException, ErrorResponseException, ModbusInitException {// 04 Input Registers类型数据读取BaseLocatorNumber loc BaseLocator.inputRegister(slaveId, offset, dataType);Number value getMaster().getValue(loc);return value;}/*** 批量读取使用方法** throws ModbusTransportException* throws ErrorResponseException* throws ModbusInitException*/public static void batchRead() throws ModbusTransportException, ErrorResponseException, ModbusInitException {BatchReadInteger batch new BatchReadInteger();batch.addLocator(0, BaseLocator.holdingRegister(1, 1, DataType.FOUR_BYTE_FLOAT));batch.addLocator(1, BaseLocator.inputStatus(1, 0));ModbusMaster master getMaster();batch.setContiguousRequests(false);BatchResultsInteger results master.send(batch);System.out.println(results.getValue(0));System.out.println(results.getValue(1));}/*** 测试** param args*/public static void main(String[] args) {try {// 01测试Boolean v011 readCoilStatus(1, 0);Boolean v012 readCoilStatus(1, 1);Boolean v013 readCoilStatus(1, 6);System.out.println(v011: v011);System.out.println(v012: v012);System.out.println(v013: v013);// 02测试Boolean v021 readInputStatus(1, 0);Boolean v022 readInputStatus(1, 1);Boolean v023 readInputStatus(1, 2);System.out.println(v021: v021);System.out.println(v022: v022);System.out.println(v023: v023);// 03测试Number v031 readHoldingRegister(1, 1, DataType.FOUR_BYTE_FLOAT);// 注意,floatNumber v032 readHoldingRegister(1, 3, DataType.FOUR_BYTE_FLOAT);// 同上System.out.println(v031: v031);System.out.println(v032: v032);// 04测试Number v041 readInputRegisters(1, 0, DataType.FOUR_BYTE_FLOAT);//Number v042 readInputRegisters(1, 2, DataType.FOUR_BYTE_FLOAT);//System.out.println(v041: v041);System.out.println(v042: v042);// 批量读取batchRead();} catch (Exception e) {e.printStackTrace();}}
}
java通过modbus4j对数据的写入
package com.ioufev;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.ip.IpParameters;
import com.serotonin.modbus4j.locator.BaseLocator;
import com.serotonin.modbus4j.msg.ModbusResponse;
import com.serotonin.modbus4j.msg.WriteCoilRequest;
import com.serotonin.modbus4j.msg.WriteCoilResponse;
import com.serotonin.modbus4j.msg.WriteCoilsRequest;
import com.serotonin.modbus4j.msg.WriteCoilsResponse;
import com.serotonin.modbus4j.msg.WriteRegisterRequest;
import com.serotonin.modbus4j.msg.WriteRegisterResponse;
import com.serotonin.modbus4j.msg.WriteRegistersRequest;/*** modbus4j写入数据**/
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(10.211.55.4);params.setPort(502);ModbusMaster tcpMaster modbusFactory.createTcpMaster(params, false);tcpMaster.init();return tcpMaster;}/*** 写 [01 Coil Status(0x)]写一个 function ID 5** param slaveId* slave的ID* param writeOffset* 位置* param writeValue* 值* return 是否写入成功* throws ModbusTransportException* throws ModbusInitException*/public static boolean writeCoil(int slaveId, int writeOffset, boolean writeValue)throws ModbusTransportException, ModbusInitException {// 获取masterModbusMaster tcpMaster getMaster();// 创建请求WriteCoilRequest request new WriteCoilRequest(slaveId, writeOffset, writeValue);// 发送请求并获取响应对象WriteCoilResponse response (WriteCoilResponse) tcpMaster.send(request);if (response.isException()) {return false;} else {return true;}}/*** 写[01 Coil Status(0x)] 写多个 function ID 15** param slaveId* slaveId* param startOffset* 开始位置* param bdata* 写入的数据* return 是否写入成功* throws ModbusTransportException* throws ModbusInitException*/public static boolean writeCoils(int slaveId, int startOffset, boolean[] bdata)throws ModbusTransportException, ModbusInitException {// 获取masterModbusMaster tcpMaster getMaster();// 创建请求WriteCoilsRequest request new WriteCoilsRequest(slaveId, startOffset, bdata);// 发送请求并获取响应对象WriteCoilsResponse response (WriteCoilsResponse) tcpMaster.send(request);if (response.isException()) {return false;} else {return true;}}/**** 写[03 Holding Register(4x)] 写一个 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 {// 获取masterModbusMaster tcpMaster getMaster();// 创建请求对象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;}}/**** 写入[03 Holding Register(4x)]写多个 function ID16** param slaveId* modbus的slaveID* param startOffset* 起始位置偏移量值* param sdata* 写入的数据* return 返回是否写入成功* throws ModbusTransportException* throws ModbusInitException*/public static boolean writeRegisters(int slaveId, int startOffset, short[] sdata)throws ModbusTransportException, ModbusInitException {// 获取masterModbusMaster tcpMaster getMaster();// 创建请求对象WriteRegistersRequest request new WriteRegistersRequest(slaveId, startOffset, sdata);// 发送请求并获取响应对象ModbusResponse response tcpMaster.send(request);if (response.isException()) {log.error(response.getExceptionMessage());return false;} else {return true;}}/*** 写入数字类型的模拟量如:写入Float类型的模拟量、Double类型模拟量、整数类型Short、Integer、Long** param slaveId* param offset* param value* 写入值,Number的子类,例如写入Float浮点类型,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 {// 获取masterModbusMaster tcpMaster getMaster();// 类型BaseLocatorNumber locator BaseLocator.holdingRegister(slaveId, offset, dataType);tcpMaster.setValue(locator, value);}public static void main(String[] args) {try {//formatter:off// 测试01
// boolean t01 writeCoil(1, 0, true);
// System.out.println(T01: t01);// 测试02
// boolean t02 writeCoils(1, 0, new boolean[] { true, false, true });
// System.out.println(T02: t02);// 测试03
// short v -3;
// boolean t03 writeRegister(1, 0, v);
// System.out.println(T03: t03);// 测试04
// boolean t04 writeRegisters(1, 0, new short[] { -3, 3, 9 });
// System.out.println(t04: t04);//写模拟量writeHoldingRegister(1,0, 10.1f, DataType.FOUR_BYTE_FLOAT);//formatter:on} catch (Exception e) {e.printStackTrace();}}}使用modbus-master-tcp
modbus-master-tcp项目的底层是基于netty框架开发。天然的支持异步处理。在性能方面有很好的提升。
maven配置
dependencygroupIdcom.digitalpetri.modbus/groupIdartifactIdmodbus-master-tcp/artifactIdversion1.1.0/version/dependencyjava使用modbus-master-tcp读取数据
package com.ioufev;import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;import com.digitalpetri.modbus.codec.Modbus;
import com.digitalpetri.modbus.master.ModbusTcpMaster;
import com.digitalpetri.modbus.master.ModbusTcpMasterConfig;
import com.digitalpetri.modbus.requests.ReadCoilsRequest;
import com.digitalpetri.modbus.requests.ReadDiscreteInputsRequest;
import com.digitalpetri.modbus.requests.ReadHoldingRegistersRequest;
import com.digitalpetri.modbus.requests.ReadInputRegistersRequest;
import com.digitalpetri.modbus.responses.ReadCoilsResponse;
import com.digitalpetri.modbus.responses.ReadDiscreteInputsResponse;
import com.digitalpetri.modbus.responses.ReadHoldingRegistersResponse;
import com.digitalpetri.modbus.responses.ReadInputRegistersResponse;import io.netty.buffer.ByteBuf;
import io.netty.util.ReferenceCountUtil;/**** modbus TCP协议Java通讯读取例子***/
public class ModbusMasterTCPDemo {static ModbusTcpMaster master;/*** 获取TCP协议的Master** return*/public static void initModbusTcpMaster() {if (master null) {// 创建配置ModbusTcpMasterConfig config new ModbusTcpMasterConfig.Builder(10.211.55.4).setPort(502).build();master new ModbusTcpMaster(config);}}/**** 释放资源*/public static void release() {if (master ! null) {master.disconnect();}Modbus.releaseSharedResources();}/*** 读取Coils开关量** param address* 寄存器开始地址* param quantity* 数量* param unitId* ID* return 读取值* throws InterruptedException* 异常* throws ExecutionException* 异常*/public static Boolean readCoils(int address, int quantity, int unitId)throws InterruptedException, ExecutionException {Boolean result null;CompletableFutureReadCoilsResponse future master.sendRequest(new ReadCoilsRequest(address, quantity),unitId);ReadCoilsResponse readCoilsResponse future.get();// 工具类做的同步返回.实际使用推荐结合业务进行异步处理if (readCoilsResponse ! null) {ByteBuf buf readCoilsResponse.getCoilStatus();result buf.readBoolean();ReferenceCountUtil.release(readCoilsResponse);}return result;}/*** 读取readDiscreteInputs开关量** param address* 寄存器开始地址* param quantity* 数量* param unitId* ID* return 读取值* throws InterruptedException* 异常* throws ExecutionException* 异常*/public static Boolean readDiscreteInputs(int address, int quantity, int unitId)throws InterruptedException, ExecutionException {Boolean result null;CompletableFutureReadDiscreteInputsResponse future master.sendRequest(new ReadDiscreteInputsRequest(address, quantity), unitId);ReadDiscreteInputsResponse discreteInputsResponse future.get();// 工具类做的同步返回.实际使用推荐结合业务进行异步处理if (discreteInputsResponse ! null) {ByteBuf buf discreteInputsResponse.getInputStatus();result buf.readBoolean();ReferenceCountUtil.release(discreteInputsResponse);}return result;}/*** 读取HoldingRegister数据** param address* 寄存器地址* param quantity* 寄存器数量* param unitId* id* return 读取结果* throws InterruptedException* 异常* throws ExecutionException* 异常*/public static Number readHoldingRegisters(int address, int quantity, int unitId)throws InterruptedException, ExecutionException {Number result null;CompletableFutureReadHoldingRegistersResponse future master.sendRequest(new ReadHoldingRegistersRequest(address, quantity), unitId);ReadHoldingRegistersResponse readHoldingRegistersResponse future.get();// 工具类做的同步返回.实际使用推荐结合业务进行异步处理if (readHoldingRegistersResponse ! null) {ByteBuf buf readHoldingRegistersResponse.getRegisters();result buf.readFloat();ReferenceCountUtil.release(readHoldingRegistersResponse);}return result;}/*** 读取InputRegisters模拟量数据** param address* 寄存器开始地址* param quantity* 数量* param unitId* ID* return 读取值* throws InterruptedException* 异常* throws ExecutionException* 异常*/public static Number readInputRegisters(int address, int quantity, int unitId)throws InterruptedException, ExecutionException {Number result null;CompletableFutureReadInputRegistersResponse future master.sendRequest(new ReadInputRegistersRequest(address, quantity), unitId);ReadInputRegistersResponse readInputRegistersResponse future.get();// 工具类做的同步返回.实际使用推荐结合业务进行异步处理if (readInputRegistersResponse ! null) {ByteBuf buf readInputRegistersResponse.getRegisters();result buf.readDouble();ReferenceCountUtil.release(readInputRegistersResponse);}return result;}public static void main(String[] args) {try {// 初始化资源initModbusTcpMaster();// 执行操作// 读取开关量System.out.println(readCoils(0, 1, 1));System.out.println(readDiscreteInputs(0, 1, 1));System.out.println(readDiscreteInputs(1, 1, 1));// 读取模拟量System.out.println(readHoldingRegisters(0, 2, 1));System.out.println(readHoldingRegisters(2, 2, 1));System.out.println(readHoldingRegisters(4, 2, 1));System.out.println(readInputRegisters(2, 4, 1));System.out.println(readInputRegisters(6, 4, 1));// 释放资源release();} catch (Exception e) {e.printStackTrace();}}
}
总结
jlibmodbus集成多个串口通信开源库有意思modbus4j很有名modbus-master-tcp底层netty支持异步JamodGithub上安卓开发modbus通信用的多