QT6 libModbus 用于ModbusTcp客户端读写服务端

2024-03-03 19:04

本文主要是介绍QT6 libModbus 用于ModbusTcp客户端读写服务端,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

虽然在以前的文章中多次描述过,那么本文使用开源库libModbus,可得到更好的性能,也可移植到各种平台。

性能:读1次和写1次约各用时2ms

分别创建了读和写各1个连接指针,用于读100个寄存器和写100个寄存器,读写分离

客户端: win10 

                Intel(R) Pentium(R) Gold 8505   1.20 GHz

               Intel(R) Ethernet Controller I226

                QT6.2.4

服务端:信捷XDH PLC

测试读100次共200ms左右,写100次也共200ms左右。

 很容易移植到linux电脑、以及嵌入式系统 。       

1.前置条件:

   (1)需要头文件8个:

(2)还需要扩展名为.c的4个文件:

(3)把以上代码拷贝如你的项目文件中,并添加进去

(4)还有一个注意事项:在pro文件中需要添加这个:LIBS += -lWs2_32

这行是添加Windows socket库文件

2.代码:

   #include "modbus-tcp.h"
   #include <QElapsedTimer>

   //以下可放入你的按钮代码里

    uint16_t tab_reg[100];  // 用于保存读取到的寄存器的数据
     uint16_t write_buffer_16[100];// 用于写寄存器的数据到服务端

     modbus_t *ctx;//用于读
     modbus_t *ctx2;//用于写


    // 创建 Modbus 上下文
     QElapsedTimer time_m;
     time_m.start();
      ctx = modbus_new_tcp("192.168.6.6", 502);  // 服务器的 IP 地址和端口号

     //ctx2 = modbus_new_tcp("127.0.0.1", 502);  // 如果你没有这个PLC,用这行代替上行 
     if (ctx == NULL)

    {
         fprintf(stderr, "Unable to create the libmodbus context\n");
         return  ;
     }
     // 连接到 Modbus 服务器
     if (modbus_connect(ctx) == -1)

    {
         fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
         modbus_free(ctx);
         return  ;
     }

     int rc;
     // 读取保持寄存器的数据(示例:从地址0开始读取100个寄存器)
     for (int i = 0; i < 100; i++)//读100次
     {
         rc = modbus_read_registers(ctx, 0, 100, tab_reg);//读,地址0,100个寄存器
     }

     if (rc == -1) {
         fprintf(stderr, "Read registers failed: %s\n", modbus_strerror(errno));
         modbus_close(ctx);
         modbus_free(ctx);
         return  ;
     }

     qDebug()<<rc;
     modbus_close(ctx);
     modbus_free(ctx);
     qDebug()<<"read use:"<<time_m.elapsed()<<"ms";
  //--------------分割线-----------------------------------------
     time_m.start();
      ctx2 = modbus_new_tcp("192.168.6.6", 502);  // 服务器的 IP 地址和端口号

      //ctx2 = modbus_new_tcp("127.0.0.1", 502);  // 如果你没有这个PLC,用这行代替上行 

    if (ctx2 == NULL) {
        fprintf(stderr, "Unable to create the libmodbus context\n");
        return  ;
    }
    if (modbus_connect(ctx2) == -1) {
        fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
        modbus_free(ctx2);
        return  ;
    }

    for (int i = 0; i < 100; i++)
    {
        write_buffer_16[i]=i;
    }

    int rw=0;

   // 写入保持寄存器的数据(示例:从地址0开始写入100个寄存器)
    for(int i=0;i<100;i++)//写100次
    {
         rw=modbus_write_registers(ctx2,0, 100, write_buffer_16);//地址0,100个寄存器
    }


    if (rw == -1)
     {
        fprintf(stderr, "write registers failed: %s\n", modbus_strerror(errno));
        modbus_close(ctx2);
        modbus_free(ctx2);
        return  ;
    }
    qDebug()<<rw;
    // // 打印读取到的寄存器数据
    // for (int i = 0; i < 100; i++)
    // {
    //     printf("Register %d: %d\n", i, tab_reg[i]);
    // }

    // 关闭连接并释放资源

    modbus_close(ctx2);
    modbus_free(ctx2);
    qDebug()<<"write use:"<<time_m.elapsed()<<"ms";

3.库文件下载链接

https://download.csdn.net/download/weixin_39926429/88900380

4.如果你没有PLC,可用以下软件模拟服务端

https://download.csdn.net/download/weixin_39926429/88900693

这篇关于QT6 libModbus 用于ModbusTcp客户端读写服务端的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/770584

相关文章

10. 文件的读写

10.1 文本文件 操作文件三大类: ofstream:写操作ifstream:读操作fstream:读写操作 打开方式解释ios::in为了读文件而打开文件ios::out为了写文件而打开文件,如果当前文件存在则清空当前文件在写入ios::app追加方式写文件ios::trunc如果文件存在先删除,在创建ios::ate打开文件之后令读写位置移至文件尾端ios::binary二进制方式

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

Java Websocket实例【服务端与客户端实现全双工通讯】

Java Websocket实例【服务端与客户端实现全双工通讯】 现很多网站为了实现即时通讯,所用的技术都是轮询(polling)。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发 出HTTP request,然后由服务器返回最新的数据给客服端的浏览器。这种传统的HTTP request 的模式带来很明显的缺点 – 浏 览器需要不断的向服务器发出请求,然而HTTP

JAVA用最简单的方法来构建一个高可用的服务端,提升系统可用性

一、什么是提升系统的高可用性 JAVA服务端,顾名思义就是23体验网为用户提供服务的。停工时间,就是不能向用户提供服务的时间。高可用,就是系统具有高度可用性,尽量减少停工时间。如何用最简单的方法来搭建一个高效率可用的服务端JAVA呢? 停工的原因一般有: 服务器故障。例如服务器宕机,服务器网络出现问题,机房或者机架出现问题等;访问量急剧上升,导致服务器压力过大导致访问量急剧上升的原因;时间和

关于使用cspreadsheet读写EXCEL表格数据的问题

前几天项目有读写EXCEL表格的需求,我就找了大概有几种,大致分为:COM方法、ODBC方法、OLE方法、纯底层格式分析方法。由于COM方法要求必须安装有OFFICE的EXCEL组件,纯底层格式分析方法又很多功能需要自行去完善,所有最终选择了数据库的方法,用数据库的方法去存取xls格式的数据。网上有一个高手写的CSpreedSheet,看了一下提供的接口,感觉挺好用的。在使用的过程中发现几个

linux 内核提权总结(demo+exp分析) -- 任意读写(四)

hijack_modprobe_path篇 本文转自网络文章,内容均为非盈利,版权归原作者所有。 转载此文章仅为个人收藏,分享知识,如有侵权,马上删除。 原文作者:jmpcall 专栏地址:https://zhuanlan.kanxue.com/user-815036.htm     原理同hijack_prctl, 当用户执行错误格式的elf文件时内核调用call_usermod

linux 内核提权总结(demo+exp分析) -- 任意读写(三)

hijack_prctl篇 本文转自网络文章,内容均为非盈利,版权归原作者所有。 转载此文章仅为个人收藏,分享知识,如有侵权,马上删除。 原文作者:jmpcall 专栏地址:https://zhuanlan.kanxue.com/user-815036.htm   prctl函数: 用户态函数,可用于定制进程参数,非常适合和内核进行交互 用户态执行prctl函数后触发prctl系统

linux 内核提权总结(demo+exp分析) -- 任意读写(二)

hijack_vdso篇 本文转自网络文章,内容均为非盈利,版权归原作者所有。 转载此文章仅为个人收藏,分享知识,如有侵权,马上删除。 原文作者:jmpcall 专栏地址:https://zhuanlan.kanxue.com/user-815036.htm     vdso: 内核实现的一个动态库,存在于内核,然后映射到用户态空间,可由用户态直接调用 内核中的vdso如果被修改

linux 内核提权总结(demo+exp分析) -- 任意读写(一)

cred篇 本文转自网络文章,内容均为非盈利,版权归原作者所有。 转载此文章仅为个人收藏,分享知识,如有侵权,马上删除。 原文作者:jmpcall 专栏地址:https://zhuanlan.kanxue.com/user-815036.htm   每个线程在内核中都对应一个线程结构块thread_infothread_info中存在task_struct类型结构体 struct t

Redis 客户端Jedis使用---连接池

Jedis 是Redis 的Java客户端,通过一段时间的使用,jedis基本实现redis的所有功能,并且jedis在客户端实现redis数据分片功能,Redis本身是没有数据分布功能。 一、下载jedis 代码 jedis 代码地址:https://github.com/xetorthio/jedis 再次感受到开源的强大。呵呵,大家有时间可以看看源码。 二、项目中如何使用Jedi