Java实现使用jlibmodbus读取Modbus TCP数据

这篇具有很好参考价值的文章主要介绍了Java实现使用jlibmodbus读取Modbus TCP数据。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

提示:可以使用Modbus slave工具模拟Modbus数据站并添加一些数据。
1、pom引入依赖

<dependency>
	 <groupId>com.intelligt.modbus</groupId>
	 <artifactId>jlibmodbus</artifactId>
	 <version>1.2.9.7</version>
</dependency>

2、创建modbus主机连接

public class JlibModbusBase {
    static ModbusMaster modbusMaster;
    public static void initJlibModbusMaster(String ip) {
        // 如果连接不存在,创建一个主机连接
        if (ObjectUtils.isEmpty(modbusMaster)) {
            // 设置主机TCP参数
            TcpParameters tcpParameters = new TcpParameters();
            // 设置TCP的ip地址-本地地址
            InetAddress address = null;
            try {
                address = InetAddress.getByName(ip);
            } catch (UnknownHostException e) {
                throw new RuntimeException(e);
            }
            tcpParameters.setHost(address);
            // TCP设置长连接
            tcpParameters.setKeepAlive(true);
            // TCP设置端口,这里设置是默认端口502
            tcpParameters.setPort(502);
            modbusMaster = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
            Modbus.setAutoIncrementTransactionId(true);
        }
    }
    public static void release() {
        if (modbusMaster != null) {
            try {
                modbusMaster.disconnect();
            } catch (ModbusIOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

3、通过连接获取功能码0x04与0x03的数据

public class JlibModbusBaseTool {
    /**
     * "功能码0x04"
     * 读取HoldingRegister数据
     *
     * @param slaveId  寄存器地址ID
     * @param offset   寄存器读取开始地址
     * @param quantity 读取寄存器数量
     * @return int数组
     */
    public static int[] readInputRegisters(int slaveId, int offset, int quantity) {
        try {
            return modbusMaster.readInputRegisters(slaveId, offset, quantity);
        } catch (ModbusProtocolException | ModbusNumberException | ModbusIOException e) {
            throw new RuntimeException(e);
        } finally {
            release();
        }
    }
    /**
     * "功能码0x03"
     * 读取HoldingRegister数据
     *
     * @param slaveId  寄存器地址ID
     * @param offset   寄存器读取开始地址
     * @param quantity 读取寄存器数量
     * @return int数组
     */
    public static int[] readHoldingRegisters(int slaveId, int offset, int quantity) {
        try {
            return modbusMaster.readHoldingRegisters(slaveId, offset, quantity);
        } catch (ModbusProtocolException | ModbusNumberException | ModbusIOException e) {
            throw new RuntimeException(e);
        } finally {
            release();
        }
    }

4、根据具体业务情况,进行方法的调用与数据解析。在本人实际业务中,存在两个IP地址(实际中上文的主机连接,可以根据IP的不同,实时创建不同的连接)。因为读取寄存器数量时,最多可以读取124个寄存器。所以根据业务实际情况,进行多次的循环取数。

//读取的寄存器数量,一次读取两台设备寄存器数据
//因为实际使用中数据为float数据,下文还会进行数据的转换
int quantity = 96;
int[] result = null;
int salveId = 0;
//获取数据
result = JlibModbusBaseTool.readInputRegisters(salveId,offset,quantity);
//首先将int[]转化为集合,然后将读取到的数据集合,分成两个集合
List<Integer> intList = Arrays.stream(result).boxed().toList();
int LIMIT_TOW = 48;
ArrayList<List<Integer>> dataList = new ArrayList<>();
Stream.iterate(0, n -> n + 1).limit(countStep(intList.size(), LIMIT_TOW)).forEach(i -> {
  dataList.add(intList.stream().skip(i * LIMIT_TOW).limit(LIMIT_TOW).collect(Collectors.toList()));
});
//计算分组数量
public static Integer countStep(Integer size,int limt) {
   return (size + limt - 1) / limt;
}
//然后读取int[]数据,转化为浮点类型
// 两个数据一组,组成16进制字符转,转化为float数据类型
public static CcElectricityMeterNew convertFloat(int[] array, CcElectricityMeterNew meterNew){
   for (int i = 0; i < array.length; i++) {
       if ((i+1)%2==0) {
           int first = array[i-1];
           int second = array[i];
           //在进行字符串转化时,转化的16进制会存在缺少一位的情况,进行左侧补零操作
           String hexStr = addZeroForStr(Integer.toHexString(first),4,1)+""+addZeroForStr(Integer.toHexString(second),4,1);
           System.out.println(new BigDecimal(sfloat(hexStr)));
       }
   }
   return meterNew;
}
//将字符串类型的16进制数据,转化为float字符串
private static String sfloat(String str){
      Float value =  Float.intBitsToFloat(new BigInteger(str, 16).intValue());
      return String.valueOf(value);
  }

/**
  * 给字符串的左补0或右补0
  * @param str  要处理的字符串
  * @param length 补0后字符串总长度
  * @return 返回补零字符串
  */
 public static String addZeroForStr(String str, int length,int type) {
     int strLen = str.length();
     if (strLen < length) {
         while (strLen < length) {
             StringBuffer sb = new StringBuffer();
           		if(type==1){
                    // 左补0
                    sb.append("0").append(str);
                }else if(type==2){
                    //右补0
                    sb.append(str).append("0");
                }
             str = sb.toString();
             strLen = str.length();
         }
     }
     return str;
 }

备注:使用jlibmodbus读取Modbus TCP数据是非常简单的,在使用中需要根据自己需要的数据类型进行转化;同时一次获取寄存器的数量需要注意,合理进行循环的数据获取。在进行modbus数据获取时,碰到一个问题,在大量进行重复连接数据获取时,modbus存在Connection reset 的问题,导致数据获取无法进行后续数据获取中断,暂时没有找到问题的原因,如果有知道原理的大神,希望给与解答!!!文章来源地址https://www.toymoban.com/news/detail-508200.html

到了这里,关于Java实现使用jlibmodbus读取Modbus TCP数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JAVA modbus4j 实现modbus tcp通讯

    1.maven依赖 2.在modbus进行读写之前,需要先建立连接,例如:建立modbus tcp通讯  3.modbus4j 读工具类 4. modbus4j 写工具类

    2024年02月16日
    浏览(36)
  • 【2023】java通过modbus4j实现modus TCP通讯

    主要分为三个子协议 RTU ASCII TCP Modbus RTU:——传输的是字节数组(bit[]) 通信:读写 输出:可以读写 输入:只能读 存储区:输出线圈、输入线圈、输出寄存器、输入寄存器 线圈:代表一个布尔量、最小单位是一个布尔(1或者0), 寄存器:一个寄存器代表16个最小单位,主

    2024年02月12日
    浏览(31)
  • C++基于开源Modbus Tcp 通讯应用客户端(稳定高效,多线程后台状态读取,不卡顿)

    使用多线程后台批量刷寄存器的状态,在某种程度上保证了上层接口读取的时候,不会卡顿, 整体应用效果比较友好。程序应用简单稳定高效,是一个比较不错的尝试。 代码如下: 代码如下: https://download.csdn.net/download/u013083044/87062401

    2024年02月16日
    浏览(34)
  • Java实现Modbus读写数据

    由于当时项目周期赶,引入了一个PLC4X组件,上手快。接下来就是使用这个组件遇到的一些问题: 关闭连接NioEventLoop没有释放导致oom 设计思想是一个设备一个连接,而不是一个网关一个连接 连接断开后客户端无从感知 前两个问题解决方案参考上篇文章,最后一个问题虽然可

    2024年02月09日
    浏览(32)
  • Java 整合 Modbus TCP

    概念 Modbus 是一种 串行通信协议 ,是Modicon公司(现在的施耐德电气 Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。Modbus已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式。 优势 Modbus协议标准开放、公开发

    2024年02月13日
    浏览(19)
  • Java与Modbus-TCP/IP网络通讯

    通过Java与Modbus-TCP/IP网络通讯实现举例5中的功能

    2024年02月10日
    浏览(36)
  • LabVIEW实现Modbus-TCP通信

    Modbus协议是一种已广泛应用于当今工业控制领域的通用通讯协议,按其格式可分为Modbus-RTU、Modbus-ASCII和Modbus-TCP。其中,前两者适用于串行通信控制网络中,例如RS485、RS232等,而Modbus-TCP主要应用于基于以太网TCP/IP通信的控制网络中。通过此协议,控制器相互之间、或控制器经

    2024年02月15日
    浏览(35)
  • MODBUS TCP协议实例数据帧详细分析

    Modbus由MODICON公司于1979年开发,是一种工业现场总线协议标准。1996年施耐德公司推出基于以太网TCP/IP的Modbus协议:ModbusTCP。Modbus协议是一项应用层报文传输协议,包括ASCII、RTU、TCP三种报文类型。标准的Modbus协议物理层接口有RS232、RS422、RS485和以太网接口,采用master/slave方式

    2024年02月05日
    浏览(54)
  • C# 使用NModbus4进行TCP读取,并且实现自动断线重连

    C# 使用NModbus4进行TCP读取,并且实现自动断线重连

    2024年02月09日
    浏览(34)
  • python使用pymodbus库进行modbus tcp通信

    使用python解决工业通信问题是一个非常好的选择,python具有丰富的生态,可以轻松解决工业通信的各种问题。本篇主要介绍使用pymodbus库进行modbus tcp仿真,实现pc端读取plc或工业设备modbus变量。 安装pymodbus: 这里我们先创建一个虚拟的modbus设备,如果你手里有一个plc或者工业

    2024年01月22日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包