凡诺企业网站管理系统,wordpress 头像加载慢,天行健公司网站建设,公司网站用wordpress系列文章目录 提示#xff1a;这里是该系列文章的所有文章的目录 第一章#xff1a;Qt下使用ModbusTcp通信协议进行PLC线圈/保持寄存器的读写#xff08;32位有符号数#xff09; 第二章#xff1a;Qt下使用modbus-c库实现PLC线圈/保持寄存器的读写 文章目录 系列文章目录…系列文章目录 提示这里是该系列文章的所有文章的目录 第一章Qt下使用ModbusTcp通信协议进行PLC线圈/保持寄存器的读写32位有符号数 第二章Qt下使用modbus-c库实现PLC线圈/保持寄存器的读写 文章目录 系列文章目录前言一、下载modbus-c库二、实现ModbusLib类三、使用ModbusLib类四、下载链接总结 前言
在上一篇文章中提到了使用Qt下的Modbus模块来进行ModbusTcp的通信采用QModbusTcpClient类作为Modbus客户端主站与PLC读写正常情况下是可以满足读写需求的但是使用过程中发现读写频率较高时会出现写入延迟等问题后面发现使用这个C语言写的第三方Modbus库来与PLC通信会更加稳定性能更优越这里将结合相应的示例进行讲解以便大家学习如有错误之处欢迎大家批评指正。
项目效果 提示以下是本篇文章正文内容下面案例可供参考
一、下载modbus-c库
通过参考博客中的下载链接到官网下载https://sourceforge.net/projects/libmodbus/似乎失效了下载不了或者通过下文中我的百度网盘链接下载压缩包文件内容如下其中包含相关源码和ws2_32.dll在lib中依赖该动态库
二、实现ModbusLib类
这里我实现了自己的ModbusLib类的封装使用了pri子模块的方式也是方便日后进行此模块的复用 这里我使用的是tcp的方式来通信pri内容如下 ModbusLib.pri
HEADERS \$$PWD/modbus.h \$$PWD/modbus-private.h \#$$PWD/modbus-rtu.h \#$$PWD/modbus-rtu-private.h \$$PWD/modbus-tcp.h \$$PWD/modbus-tcp-private.h \$$PWD/mymodbuslib.hSOURCES \$$PWD/modbus.c \$$PWD/modbus-data.c \#$$PWD/modbus-rtu.c \$$PWD/modbus-tcp.c \$$PWD/mymodbuslib.cppLIBS -L$$PWD/lib/ -lws2_32这里会看到将modbus-c库的源码加入到工程中所以添加好相关的头文件就可以调用库函数了这里相关函数的使用见下文代码 1.mymodbusLib.h
#ifndef MYMODBUSLIB_H
#define MYMODBUSLIB_H#include QObject
#include QDateTime
#include QTimer
#include QThread
#include QEventLoop
#include QCoreApplication
#include QDebug
#include modbus.h
#include modbus-private.h
#include modbus-tcp.h
#include modbus-tcp-private.h#define LOGDEBUG qDebug()QTime::currentTime().toString([hh:mm:ss:zzz])class MyModbusLib : public QObject
{Q_OBJECTpublic:explicit MyModbusLib(QObject *parent nullptr);~MyModbusLib();bool initConnect(QString tcpIP,int tcpPort);bool readCoil(int readAdd);void writeCoil(int writeAdd,int writeNum);int readRegister(int writeAdd);void writeRegister32(int writeAdd,int writeNum);private:modbus_t *m_modbus;
};#endif // MYMODBUSLIB_H2.mymodbusLib.cpp
#include mymodbuslib.hMyModbusLib::MyModbusLib(QObject *parent) : QObject(parent)
{}MyModbusLib::~MyModbusLib()
{modbus_close(m_modbus);modbus_free(m_modbus);
}//初始化
bool MyModbusLib::initConnect(QString tcpIP,int tcpPort)
{m_modbus modbus_new_tcp(tcpIP.toLatin1().data(),tcpPort);modbus_set_slave(m_modbus,1);if(modbus_connect(m_modbus) -1){return false;}//设置modbus超时时间为1000毫秒struct timeval t;t.tv_sec 0;t.tv_usec 1000000;modbus_set_response_timeout(m_modbus,t.tv_sec,t.tv_usec);return true;
}bool MyModbusLib::readCoil(int readAdd)
{uint8_t bitsr[1]{0};int rNum modbus_read_bits(m_modbus,readAdd,1,bitsr);if(rNum -1){LOGDEBUG读取线圈readAdd失败!;return false;}else{//LOGDEBUG读取线圈readAdd成功!;if(bitsr[0] 1){return true;}}return false;
}void MyModbusLib::writeCoil(int writeAdd,int writeNum)
{uint8_t bitsw[1]{0};bitsw[0] writeNum;int rNum modbus_write_bits(m_modbus,writeAdd,1,bitsw);if(rNum -1){LOGDEBUG线圈writeAdd写入writeNum失败!;}else{LOGDEBUG线圈writeAdd写入writeNum成功!;}
}int MyModbusLib::readRegister(int readAdd)
{uint16_t regsr[2]{0};int rNum modbus_read_registers(m_modbus,readAdd,2,regsr);if(rNum -1){LOGDEBUG读取寄存器readAdd失败!;}else{//LOGDEBUG读取寄存器readAdd成功!;int readNum regsr[0] | (regsr[1] 16);return readNum;}return 0;
}void MyModbusLib::writeRegister32(int writeAdd,int writeNum)
{uint16_t regsw[2]{0};regsw[0] writeNum 0xffff;regsw[1] (writeNum 16) 0xffff;int rNum modbus_write_registers(m_modbus,writeAdd,2,regsw);if(rNum -1){LOGDEBUG寄存器writeAdd写入writeNum失败!;}else{LOGDEBUG寄存器writeAdd写入writeNum成功!;}
}三、使用ModbusLib类
工程结构如图下面可以直接在主界面使用封装好的ModbusLib类详细内容见代码
1.ModbusTest.pro
QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11DEFINES QT_DEPRECATED_WARNINGS#设置字符
contains( CONFIG,msvc ):QMAKE_CXXFLAGS /source-charset:utf-8 /execution-charset:utf-8
contains( CONFIG,msvc ):QMAKE_CFLAGS /source-charset:utf-8 /execution-charset:utf-8#包含子模块
include (./ModbusLib/ModbusLib.pri) #libmodbus库SOURCES \main.cpp \mainwindow.cppHEADERS \mainwindow.hFORMS \mainwindow.ui# Default rules for deployment.
qnx: target.path /tmp/$${TARGET}/bin
else: unix:!android: target.path /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS target2.mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include QMainWindow
#include QTime
#include QDebug
#include ModbusLib/mymodbuslib.hQT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWindow();void initWidget();private slots:void on_pb_connect_clicked();void on_pb_readC_clicked();void on_pb_writeC_clicked();void on_pb_readH_clicked();void on_pb_writeH_clicked();private:Ui::MainWindow *ui;MyModbusLib *m_myModbus;};
#endif // MAINWINDOW_H3.mainwindow.cpp
#include mainwindow.h
#include ui_mainwindow.hMainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);this-initWidget();
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::initWidget()
{//使能按钮ui-pb_readC-setEnabled(false);ui-pb_writeC-setEnabled(false);ui-pb_readH-setEnabled(false);ui-pb_writeH-setEnabled(false);//创建modbus对象m_myModbus new MyModbusLib();
}void MainWindow::on_pb_connect_clicked()
{QString tcpIP ui-le_ip-text();int tcpPort ui-le_port-text().toInt();if(m_myModbus-initConnect(tcpIP,tcpPort)){ui-lb_state-setText(连接成功);LOGDEBUGModbusTCP连接成功!;//使能按钮ui-pb_readC-setEnabled(true);ui-pb_writeC-setEnabled(true);ui-pb_readH-setEnabled(true);ui-pb_writeH-setEnabled(true);}else{ui-lb_state-setText(连接失败);LOGDEBUGModbusTCP连接失败!;}
}void MainWindow::on_pb_readC_clicked()
{int readAdd ui-le_addC-text().toInt();ui-lb_numC-setText(QString::number(m_myModbus-readCoil(readAdd)));
}void MainWindow::on_pb_writeC_clicked()
{int writeAdd ui-le_addC-text().toInt();int writeNum ui-le_writeNumC-text().toInt();m_myModbus-writeCoil(writeAdd,writeNum);
}void MainWindow::on_pb_readH_clicked()
{int readAdd ui-le_addH-text().toInt();ui-lb_numH-setText(QString::number(m_myModbus-readRegister(readAdd)));
}void MainWindow::on_pb_writeH_clicked()
{int writeAdd ui-le_addH-text().toInt();int writeNum ui-le_writeNumH-text().toInt();m_myModbus-writeRegister32(writeAdd,writeNum);
}4.mainwindow.ui
四、下载链接
modbus-c库下载链接https://pan.baidu.com/s/1rBQzOhwPIrRxL_f2CofJxQ 提取码xxcj 总结
后续在使用modbus-c库的测试中发现读写的效率是比Qt自带的modbus模块要高并且稳定的建议在需要与PLC进行tcp通信时使用这种方式。这里我的ModbusLib类封装在一个文件夹内要调用直接在工程pro中添加pri子模块就可以使用比较方便。 hello 共同学习共同进步如果还有相关问题可在评论区留言进行讨论。
参考博客QT 使用第三方C库实现Modbus通讯