C++和python分别用Qt实现ModbusTcp通讯

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QModbusTcpClient>
#include<iostream>
using namespace std;

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_btnRead_clicked();

    void on_btnWrite_clicked();
    void replyData();

private:
    Ui::Widget *ui;
    QModbusTcpClient *client;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    client = new QModbusTcpClient(this);
    client->setConnectionParameter(QModbusDevice::NetworkAddressParameter,"192.168.5.20");
    client->setConnectionParameter(QModbusDevice::NetworkPortParameter,502);
    client->connectDevice();
}

Widget::~Widget()
{
    if (client->state()==QModbusTcpClient::ConnectedState){
        client->disconnectDevice();
    }
    delete ui;
}


void Widget::on_btnRead_clicked()
{
    QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters,0,1);
    QModbusReply* reply = client->sendReadRequest(unit,1);
    if (reply){
        if (!reply->isFinished()){
            //connect里面的参数必须全部是指针,B站视频里在这里有错误,可能是QT版本的问题
            connect(reply,&QModbusReply::finished,this,&Widget::replyData);
            return;

        }
    }
}

void Widget::on_btnWrite_clicked()
{
    QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters,0,1);
    unit.setValue(0,ui->lineEdit->text().toUInt());
    QModbusReply *reply = client->sendWriteRequest(unit,1);
    if (reply){
        reply->deleteLater();
    }

}

void Widget::replyData(){
//    cout<<123<<endl;

    QModbusReply* reply = (QModbusReply*)(sender());
    QModbusDataUnit unit = reply->result();
    reply->deleteLater();

    if (unit.valueCount()>0){
        ui->lineEdit->setText(QString::number(unit.value(0)));
    }

}

widget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>364</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <widget class="QWidget" name="horizontalLayoutWidget">
   <property name="geometry">
    <rect>
     <x>50</x>
     <y>60</y>
     <width>441</width>
     <height>80</height>
    </rect>
   </property>
   <layout class="QHBoxLayout" name="horizontalLayout">
    <property name="spacing">
     <number>33</number>
    </property>
    <item>
     <widget class="QLineEdit" name="lineEdit"/>
    </item>
    <item>
     <widget class="QPushButton" name="btnRead">
      <property name="text">
       <string>read</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QPushButton" name="btnWrite">
      <property name="text">
       <string>write</string>
      </property>
     </widget>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

python代码实现


import sys
from PySide6.QtWidgets import *
from PySide6.QtCore import *
from PySide6.QtSerialBus import QModbusTcpClient,QModbusReply,QModbusDataUnit,QModbusDevice




class Window(QWidget):
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.btn = QPushButton("read",self)
        self.btn2 = QPushButton("write",self)
        self.btn.move(50,50)
        self.btn2.move(150,50)

        self.btn.clicked.connect(self.on_btnRead)
        self.btn2.clicked.connect(self.on_btnWrite)

        self.client = QModbusTcpClient(self)
        self.client.setConnectionParameter(QModbusDevice.ConnectionParameter.NetworkAddressParameter,"192.168.5.20")
        self.client.setConnectionParameter(QModbusDevice.ConnectionParameter.NetworkPortParameter,502)

        if self.client.connectDevice():
            QMessageBox.information(self, "tips", "sucess")
        else:
            QMessageBox.information(self, "tips", "wrong")

    def on_btnRead(self):
        readunit:QModbusDataUnit = QModbusDataUnit(QModbusDataUnit.RegisterType.HoldingRegisters,0,10)
        reply:QModbusReply = self.client.sendReadRequest(readunit,1)
        if reply:
            while not reply.isFinished():
                QCoreApplication.processEvents()

            if reply.error() == QModbusDevice.Error.NoError:
                relustunit: QModbusDataUnit = reply.result()

                result: str = ""
                for i in range(relustunit.valueCount()):
                    result += str(relustunit.value(i)) + " "
                print(result)
            else:
                print(self.client.errorString())

            reply.deleteLater()

        else:
            print(self.client.errorString())


    def on_btnWrite(self):
        writeUnit :QModbusDataUnit = QModbusDataUnit(QModbusDataUnit.RegisterType.HoldingRegisters,0,3)
        #
        # value:int = int(self.lineEdit.text())
        # writeUnit.setValue(0,value) #写入单个寄存器
        writeUnit.setValues([23,4,67]) #写入多个寄存器

        reply = self.client.sendWriteRequest(writeUnit,1)
        if reply:
            while not reply.isFinished():
                QCoreApplication.processEvents()

            if reply.error()==QModbusDevice.Error.NoError:
                QMessageBox.information(self, "tips", "写入成功")
            else:
                QMessageBox.information(self, "tips", f"写入失败:+{reply.errorString()}")

            reply.deleteLater()


















if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = Window()
    win.show()
    sys.exit(app.exec())









  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Modbus TCP协议是一种基于TCP/IP协议的工业通信协议,可用于工业自动化领域中的数据采集、监控和控制。在QT实现Modbus TCP协议,可以使用第三方库QModbus。 QModbus是一个开源的Qt Modbus库,提供了Modbus TCP和RTU通讯协议的实现。下面是一个简单的Modbus TCP通讯的示例代码: ```c++ #include <QCoreApplication> #include <QDebug> #include <QModbusTcpClient> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 创建Modbus TCP客户端 QModbusTcpClient *client = new QModbusTcpClient(&a); // 连接到Modbus TCP服务器 client->setConnectionParameter(QModbusDevice::NetworkPortParameter, 502); client->setConnectionParameter(QModbusDevice::NetworkAddressParameter, "192.168.1.100"); client->connectDevice(); // 检查连接是否成功 if (!client->isConnected()) { qDebug() << "Modbus TCP连接失败:" << client->errorString(); return a.exec(); } // 读取Modbus寄存器的值 QModbusDataUnit readUnit(QModbusDataUnit::HoldingRegisters, 0, 1); if (auto *reply = client->sendReadRequest(readUnit, 1)) { // 等待响应 while (!reply->isFinished()) { qApp->processEvents(); } // 处理响应 if (reply->error() == QModbusDevice::NoError) { qDebug() << "Modbus寄存器值:" << reply->resultAt(0); } else { qDebug() << "读取Modbus寄存器失败:" << reply->errorString(); } // 释放响应 reply->deleteLater(); } else { qDebug() << "发送Modbus读取请求失败:" << client->errorString(); } // 断开连接 client->disconnectDevice(); delete client; return a.exec(); } ``` 上面的示例代码中,首先创建了一个QModbusTcpClient客户端,然后连接到Modbus TCP服务器。连接成功后,使用sendReadRequest()方法读取Modbus寄存器的值,并等待响应。如果响应无错误,则打印读取到的寄存器值。最后断开连接并释放客户端对象。 需要注意的是,QModbusTcpClient是异步的,需要等待响应才能处理结果。因此,在等待响应期间需要调用qApp->processEvents()方法处理事件队列。 除了读取寄存器的值,QModbus还提供了其他的Modbus TCP通讯方法,例如写入寄存器的值、读取线圈状态等。具体的使用方法可以参考QModbus的文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值