Qt modbus通讯写上位

来源:互联网 发布:微淘加粉软件 编辑:程序博客网 时间:2024/06/13 20:52

Qt modbus通讯写上位

继上次PLC展厅,通过北辰网关的转Modbus功能,使用Qt写一个简单的S7-300的上位程序,可以查看正转时间,反转时间,还可以控制电机启停。

北辰网关设置

北辰网关的设置可以参考这篇文章西门子PLC实现modbusTCP通讯
我的设置如下图:
这里写图片描述

UI界面

这里写图片描述

计时器的实现

构造函数中

timer1 = new QTimer(this);  //timer1为QTimer类型connect(timer1, SIGNAL(timeout()), this, SLOT(showTime()));timer1->start(1000);

showTime()中

 time=time.addSecs(60);//time为QTime类型 QString text = time.toString("hh:mm"); if ((time.second() % 2) == 0)        text[2] = ' '; ui->lcdNumber->display(text);

Modbus通讯

modbus通讯可以参考我之前的文章QModbusClient

QObject::sender()

因为有正转时间,反转时间,停止时间三个时间需要计时

 connect(timer1, SIGNAL(timeout()), this, SLOT(showTime())); connect(timer2, SIGNAL(timeout()), this, SLOT(showTime())); connect(timer3, SIGNAL(timeout()), this, SLOT(showTime()));

它们都连接到槽showTime();因此,需要在showTime()中判断是哪个对象发出了timeout()信号,这个是通过QObject::sender()来实现的。
在showTime()中

 QTimer *t=qobject_cast<QTimer *>(sender()); if(t==timer1)        ui->lcdNumber->display(text);    else if (t==timer2)        ui->lcdNumber_2->display(text);    else        ui->lcdNumber_3->display(text);

控制电机启停

因为通过北辰的网关没有读出M区的变量,采取通过控制DB块来控制电机启停。
修改PLC起保停程序如下:
这里写图片描述
I0.0和I0.1是通过PLC按钮启停。在Qt上位中可以向DB3.DBX0.0写入1和0来控制PLC启停。为什么是DB3,因为在北辰网关的设置中,ModbusTcp映射DB号为3

源程序

mymodbus.h

#ifndef MYMODBUS_H#define MYMODBUS_H#include <QWidget>#include <QLCDNumber>#include <QModbusDataUnit>#include <QTimer>#include <QTime>#include <QModbusTcpClient>#include <QDebug>class ModbusRly;class QModbusTcpClient;namespace Ui {class MyModbus;}class MyModbus : public QWidget{    Q_OBJECTpublic:    explicit MyModbus(QWidget *parent = 0);    ~MyModbus();private:    QModbusTcpClient *client;    QTime time;    QString entry[5];    QTimer *timer1;    QTimer *timer2;    QTimer *timer3;    Ui::MyModbus *ui;public slots:    void showTime();private slots:    void on_pushButton_clicked();    void on_pushButton_2_clicked();    void readReady();    void on_pushButton_3_clicked();    void on_pushButton_4_clicked();    void on_pushButton_5_clicked();};#endif // MYMODBUS_H

mymodbus.cpp

#include "mymodbus.h"#include "ui_mymodbus.h"MyModbus::MyModbus(QWidget *parent) :    QWidget(parent),client(nullptr),time(QTime(0,0,0)),    ui(new Ui::MyModbus){    ui->setupUi(this);    ui->pushButton_2->setEnabled(false);    ui->pushButton_5->setEnabled(false);    ui->pushButton_3->setEnabled(false);    ui->pushButton_4->setEnabled(false);    timer1 = new QTimer(this);    timer2=new QTimer(this);    timer3=new QTimer(this);    connect(timer1, SIGNAL(timeout()), this, SLOT(showTime()));    connect(timer2, SIGNAL(timeout()), this, SLOT(showTime()));    connect(timer3, SIGNAL(timeout()), this, SLOT(showTime()));    if (ui->lineEdit->text().isEmpty())        ui->lineEdit->setText(QLatin1Literal("192.168.1.99"));}void MyModbus::showTime(){    QTimer *t=qobject_cast<QTimer *>(sender());    on_pushButton_2_clicked();    time=time.addSecs(60);    QString text = time.toString("hh:mm");    if ((time.second() % 2) == 0)        text[2] = ' ';    if(t==timer1)        ui->lcdNumber->display(text);    else if (t==timer2)        ui->lcdNumber_2->display(text);    //else      //  ui->lcdNumber_3->display(text);}MyModbus::~MyModbus(){    delete client;    delete ui;}void MyModbus::on_pushButton_clicked(){    client=new QModbusTcpClient(this);    client->setConnectionParameter(QModbusDevice::NetworkAddressParameter,ui->lineEdit->text());    client->setConnectionParameter(QModbusDevice::NetworkPortParameter, 502);    if(!client->connectDevice())    {        qDebug("failed");    }    else    {        qDebug("successed");        ui->pushButton_2->setEnabled(true);        ui->pushButton_5->setEnabled(true);        ui->pushButton_3->setEnabled(true);        ui->pushButton_4->setEnabled(true);    }}void MyModbus::on_pushButton_2_clicked(){    if(!client)        return;    QModbusDataUnit readUnit(QModbusDataUnit::Coils, 00000, 5);    if (auto *reply = client->sendReadRequest(readUnit, 2)) // client id 255    {        if (!reply->isFinished())        {            // connect the finished signal of the request to your read slot            connect(reply, &QModbusReply::finished, this, &MyModbus::readReady);        }        else        {            delete reply; // broadcast replies return immediately            qDebug("delete reply");        }    }    else    {       qDebug("request error"); // request error    }}void MyModbus::readReady(){    auto *reply = qobject_cast<QModbusReply *>(sender());    if (!reply)        return;    if (reply->error() == QModbusDevice::NoError) {        const QModbusDataUnit unit = reply->result();        for (uint i = 0; i < unit.valueCount(); i++) {        entry[i] = QString::number(unit.value(i),                                          unit.registerType() <= QModbusDataUnit::Coils ? 10 : 16);        qDebug()<<i<<entry[i];        }     if(entry[3].toInt()==1&&entry[2].toInt()==1)     {        timer1->start(1000);        timer2->stop();        timer3->stop();     }     else if(entry[3].toInt()==0&&entry[2].toInt()==1)     {        timer2->start(1000);        timer1->stop();        timer3->stop();     }     else if(entry[2].toInt()==0)     {         timer1->stop();         timer2->stop();         timer3->start(1000);         time.setHMS(0,0,0);     }    }    reply->deleteLater();}void MyModbus::on_pushButton_3_clicked(){    if(!client)        return;    QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters, 0, 1); // write 1 value in address 30000    writeUnit.setValue(0,256);    if (auto *reply = client->sendWriteRequest(writeUnit, 2))    {        if (!reply->isFinished())        {            connect(reply, &QModbusReply::finished, this, [this, reply]()            {                if (reply->error() != QModbusDevice::NoError)                        // error in reply                    qDebug("No Error");                    reply->deleteLater();                });        }        else        {            if (reply->error() != QModbusDevice::NoError)                // error in reply            qDebug("No Error1");            // broadcast replies return immediately            reply->deleteLater();        }    }    else    {        // error in request    }}void MyModbus::on_pushButton_4_clicked(){    if(!client)        return;    QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters, 0, 1); // write 1 value in address 30001    writeUnit.setValue(0,0);    if (auto *reply = client->sendWriteRequest(writeUnit, 2))    {        if (!reply->isFinished())        {            connect(reply, &QModbusReply::finished, this, [this, reply]()            {                if (reply->error() != QModbusDevice::NoError)                        // error in reply                    qDebug("No Error");                    reply->deleteLater();                });        }        else        {            if (reply->error() != QModbusDevice::NoError)                // error in reply            // broadcast replies return immediately            reply->deleteLater();        }    }    else    {        // error in request    }}void MyModbus::on_pushButton_5_clicked(){     client->disconnectDevice();     ui->pushButton_5->setEnabled(false);     ui->pushButton_2->setEnabled(false);     ui->pushButton_3->setEnabled(false);     ui->pushButton_4->setEnabled(false);     timer1->stop();     timer2->stop();     timer3->stop();}

main.cpp

#include "mymodbus.h"#include <QApplication>int main(int argc, char *argv[]){    QApplication a(argc, argv);    MyModbus w;    w.show();    return a.exec();}
原创粉丝点击