赞
踩
虽然在以前的文章中多次描述过,那么本文使用开源库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;
//uint16_t par100WriteArray[10000];// 用于写寄存器的数据到服务端
// 写入保持寄存器的数据(示例:从地址0开始写入100个寄存器)
for(int i=0;i<100;i++)//写100次
{ //写入保持寄存器的数据,modbus_write_registers(连接指针,起始地址,长度,源数组)
rw=modbus_write_registers(ctx2,0, 100, write_buffer_16);//地址0,100个寄存器
// for(int i=0;j<100;j++)//写100次
//{
/// par100WriteArray=i*100+j;//准备数组
//}
// rw=modbus_write_registers(ctx2,i*100, 100, par100WriteArray);//写0~100,100~200....
//被注释的上行,一次发送100个寄存器,发送完,下次,起始地址增加100,
//把几千上万寄存器,发送出去,解决了modbus 发送长度限制的问题
}
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,可用以下软件模拟服务端
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。