Qt 串口通信之使用三菱PLC控制程序

作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

前言

上位机与PLC通信有很多种方式,比如CPU编程口、网口、串口、总线连接等等。本章节记录一下如何通过串口让PLC控制程序执行操作。博主之前写过一章使用网口与PLC通信,具体请参考:Qt使用 MX Component 插件与三菱PLC通信

功能预览

在这里插入图片描述

通信协议

所谓通信协议是指通信双方的一种约定。约定包括对数据格式、同步方式、传送速度、传送步骤、检纠错方式以及控制字符定义等问题做出统一规定,通信双方必须共同遵守,属于OSI七层参考模型中的数据链路层。目前,采用的通信协议有两类:异步协议和同步协议。

总的来说,通讯协议就是通讯双方共同遵循的一套规则,定义协议的原则是尽可能的简单以提高传输率,尽可能的具有安全性保证数据传输完整正确。基于这2点规则,我们一个通讯协议应该是这样的:
头 + 数据长度 + 数据正文 + 校验

查看端口在这里插入图片描述

我的代码

需要在 pro 文件中导入串口模块:
QT += serialport

serialportcontrol.h

#ifndef SERIALPORTCONTROL_H
#define SERIALPORTCONTROL_H

#include <QThread>
#include <QSerialPort>
#include <QSerialPortInfo>

class SerialPortControl : public QThread
{
    Q_OBJECT
public:
    explicit SerialPortControl();

    bool open(QString portName);
    void close();
    void writeResult(QString ret);

    virtual void run() override;

signals:
    void startWork();

private:
    QSerialPort m_serialPort;
    bool isStarted;
};

#endif // SERIALPORTCONTROL_H

serialportcontrol.cpp

#include "serialportcontrol.h"
#include "globalfun.h"

SerialPortControl::SerialPortControl()
{
    isStarted = false;
}

bool SerialPortControl::open(QString portName)
{
    // 设置串口名称
    m_serialPort.setPortName(portName);

    // 设置波特率
    switch (GlobalValue::atm_bte) {
    case 0: m_serialPort.setBaudRate(QSerialPort::Baud1200); break;
    case 1: m_serialPort.setBaudRate(QSerialPort::Baud2400); break;
    case 2: m_serialPort.setBaudRate(QSerialPort::Baud4800); break;
    case 3: m_serialPort.setBaudRate(QSerialPort::Baud9600); break;
    case 4: m_serialPort.setBaudRate(QSerialPort::Baud19200); break;
    case 5: m_serialPort.setBaudRate(QSerialPort::Baud38400); break;
    case 6: m_serialPort.setBaudRate(QSerialPort::Baud57600); break;
    case 7: m_serialPort.setBaudRate(QSerialPort::Baud115200); break;
    default: m_serialPort.setBaudRate(QSerialPort::UnknownBaud); break;
    }

    // 设置数据位
    switch (GlobalValue::atm_dbt) {
    case 0: m_serialPort.setDataBits(QSerialPort::Data5); break;
    case 1: m_serialPort.setDataBits(QSerialPort::Data6); break;
    case 2: m_serialPort.setDataBits(QSerialPort::Data7); break;
    case 3: m_serialPort.setDataBits(QSerialPort::Data8); break;
    default: m_serialPort.setDataBits(QSerialPort::UnknownDataBits); break;
    }

    // 设置奇偶校验
    switch (GlobalValue::atm_cbt) {
    case 0: m_serialPort.setParity(QSerialPort::NoParity); break;
    case 1: m_serialPort.setParity(QSerialPort::EvenParity); break;
    case 2: m_serialPort.setParity(QSerialPort::OddParity); break;
    case 3: m_serialPort.setParity(QSerialPort::SpaceParity); break;
    case 4: m_serialPort.setParity(QSerialPort::MarkParity); break;
    default: m_serialPort.setParity(QSerialPort::UnknownParity); break;
    }

    // 设置停止位
    switch (GlobalValue::atm_sbt) {
    case 0: m_serialPort.setStopBits(QSerialPort::OneStop); break;
    case 1: m_serialPort.setStopBits(QSerialPort::OneAndHalfStop); break;
    case 2: m_serialPort.setStopBits(QSerialPort::TwoStop); break;
    default: m_serialPort.setStopBits(QSerialPort::UnknownStopBits); break;
    }

    // 设置流控制
    switch (GlobalValue::atm_fcl) {
    case 0: m_serialPort.setFlowControl(QSerialPort::NoFlowControl); break;
    case 1: m_serialPort.setFlowControl(QSerialPort::HardwareControl); break;
    case 2: m_serialPort.setFlowControl(QSerialPort::SoftwareControl); break;
    default: m_serialPort.setFlowControl(QSerialPort::UnknownFlowControl); break;
    }

    // 打开串口
    isStarted = m_serialPort.open(QIODevice::ReadWrite);
    return isStarted;
}

void SerialPortControl::close()
{
    // 关闭串口
    isStarted = false;
    m_serialPort.close();
}

void SerialPortControl::writeResult(QString ret)
{
    if ( m_serialPort.isOpen() ) {
        m_serialPort.write(ret.toLatin1());
    }
}

void SerialPortControl::run()
{
    while ( isStarted )
    {
        // 读取串口
        QByteArray buffer = m_serialPort.readAll();
        QString str = QString(buffer);
        if ( str == "do" ) {
            emit startWork();
        }

        GlobalFun::bsleep(100);
    }
}

mainwindow.cpp

void MainWindow::initSerialport()
{
    qDebug() << "initSerialport !";
    m_spCtl = new SerialPortControl();

    // 获取可用串口号
    for ( auto &temp : QSerialPortInfo::availablePorts() )
    {
        ui->serialPortBox->addItem(temp.portName());
    }

    connect(m_spCtl, &SerialPortControl::startWork, this, [&](){ startCalculation(); }, Qt::QueuedConnection);
}
void MainWindow::on_fillData()
{
    ......
    
    QApplication::processEvents();
    
    // 往串口里写入计算结果
    if ( m_spCtl->isRunning() ) {
        QString totalRet = ui->data_table->item(dRow, 3)->text();
        m_spCtl->writeResult(totalRet);
    }
}
  • 14
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: QT是一种功能强大的跨平台应用程序开发框架,而三菱PLC是工业自动化中常用的一种可编程控制器。要实现在QT中与三菱PLC的通讯,可以通过以下步骤进行: 1. 确定通讯方式:三菱PLC支持多种通讯方式,如串口通讯、以太网通讯等。需要根据实际情况选择合适的通讯方式。 2. 编写通讯协议:在QT中,可以使用现有的三菱PLC通讯协议库(如MELSEC、MX Component等)或自己编写通讯协议库。编写通讯协议库的目的是实现与三菱PLC之间的数据交换。 3. 进行连接设置:在QT中,需要配置正确的通讯参数,如PLC的IP地址、端口号、通讯协议等。可以利用QT的网络编程功能来实现与三菱PLC的连接。 4. 实现数据读写:通过通讯协议库提供的接口函数,可以实现在QT中读取和写入三菱PLC的数据。可以根据实际需求,读取PLC的状态信息或控制PLC进行动作。 5. 处理通讯错误:在与三菱PLC通讯的过程中,可能会出现各种错误,如连接失败、通讯超时等。在QT中,可以通过异常处理机制来捕获并处理这些错误,确保通讯的稳定性。 综上所述,通过选择合适的通讯方式、编写通讯协议库,配置通讯参数,以及实现数据读写和错误处理等操作,就可以在QT中实现与三菱PLC的通讯。这样,可以方便地在QT应用程序中控制和监控三菱PLC的运行状态,实现更加灵活和自动化的工业控制应用。 ### 回答2: QT(即Qt)是一种跨平台的应用程序开发框架,可以用来开发各种类型的软件应用程序,包括与三菱PLC进行通信的应用程序。 与三菱PLC进行通信的主要方法是使用串行通信协议,一般是通过串口(RS232或RS485)连接PLC和计算机。以下是QT如何与三菱PLC进行通信的基本步骤: 1. 配置串口:首先,需要在QT应用程序中配置串口,包括串口的波特率、数据位、停止位等。可以使用QT提供的串口类(QSerialPort)进行串口配置。 2. 打开串口:使用QSerialPort类的open()函数打开配置好的串口,确保与PLC连接。 3. 设置数据传输:通过QSerialPort类的setBaudRate()、setDataBits()、setStopBits()等函数,设置好数据传输的相关参数。 4. 发送指令:使用QSerialPort类的write()函数将指令发送给PLC。具体的指令格式和协议依赖于PLC型号和通信协议,可以参考三菱PLC的通信协议文档。 5. 接收数据:使用QSerialPort类的read()函数接收来自PLC的响应数据。根据通信协议,解析并处理接收到的数据。 6. 关闭串口:通信完成后,使用QSerialPort类的close()函数关闭串口。 需要注意的是,与三菱PLC进行通信还需要了解PLC的通信协议和通信指令格式。不同的PLC型号和使用的通信协议可能有所不同,因此在实际开发过程中,需要仔细研究三菱PLC的通信文档和相关资料,根据具体情况进行配置和编程。 总之,使用QT进行与三菱PLC通信的关键是配置串口、发送与接收数据以及解析响应数据。 ### 回答3: Qt作为一种流行的跨平台应用程序开发框架,可以与三菱PLC进行通讯。下面是一个简单的示例来说明如何实现Qt三菱PLC的通讯。 首先,我们需要确保计算机(或嵌入式设备)上安装了三菱PLC的相关驱动程序。这些驱动程序通常由三菱PLC的制造商提供。 其次,我们需要在Qt项目中包含一个用于与PLC通讯的库文件。这个库文件是由PLC制造商提供的,并且会为不同的操作系统提供不同的版本。我们需要根据我们使用的操作系统选择正确的库文件。 然后,在Qt项目的源代码中,我们可以使用这个库文件提供的函数和类来实现与PLC的通讯。通过这些函数和类,我们可以读取和写入PLC中的数据,并且可以发送和接收PLC的控制命令。 最后,在Qt项目中,我们可以设计一个用户界面来显示从PLC读取的数据,并且可以通过按钮等操作元素来向PLC发送控制命令。通过这种方式,我们可以方便地监控和控制PLC的状态。 总的来说,Qt三菱PLC的通讯可以通过安装驱动程序、包含并使用PLC通讯库文件、编写相关代码来实现。这样,我们可以在Qt应用程序中方便地实现与三菱PLC的数据交互和控制。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值