Qt开发中的485串口控制代码

  • Post author:
  • Post category:其他

需求

通过USB转485串口控制哈美顿的注射泵,需要一个串口控制界面,里面主要包括串口扫描获取串口信息,串口数据下发,串口数据读取以及串口连接。

初步设计

串口控制网上有很多,如果不是要做单独的控制系统的话,只要下载一个使用就好了。因为目标串口已经确定,这是一个目标型的串口控制软件,所以还是需要自己写一份封装。
大体设计思路是:

1.自动检测串口,匹配到目标串口自动连接
2.监控窗口,显示所有的操作记录
3.控制按钮,非指令式操作,给出复位校准按钮,开始按钮,停止按钮,以及速度选择器,运行时间选择器

代码

头文件

#ifndef HAMILTON_H
#define HAMILTON_H

#include <QWidget>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QtCore>

namespace Ui {
class Hamilton;
}

class Hamilton : public QWidget
{
    Q_OBJECT

    enum REPORT_TYPE{ Connect,DisConnect,Reset,Start,Stop,Continue,Outbubble,Syringedown};

public:
    explicit Hamilton(QWidget *parent = 0);
    ~Hamilton();

private slots:
    void onTimeout();
    void onStopCommand();

    void on_btnStart_clicked();

    void on_btnStop_clicked();

    void on_btnReset_clicked();

    void on_btnOutBubble_clicked();

    void on_btnDown_clicked();

private:
    Ui::Hamilton *ui;
    QTimer* timer1;
    QTimer* timer2;
    QSerialPort* serial;
    QSerialPortInfo* serialInfo = nullptr;
    bool flag = false;

    void report(REPORT_TYPE type, QString descripe = "");
};

#endif // HAMILTON_H


主体文件

#include "hamilton.h"
#include "ui_hamilton.h"
#include "commandhelper.h"
#include <QTime>

Hamilton::Hamilton(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Hamilton)
{
    ui->setupUi(this);
    ui->btnStart->setEnabled(false);
    ui->btnStop->setEnabled(false);
    ui->textEditReport->setReadOnly(true);

    timer1 = new QTimer(this);
    timer1->start(1000);
    connect(timer1,SIGNAL(timeout()),this,SLOT(onTimeout()));

    timer2 = new QTimer(this);
}

Hamilton::~Hamilton()
{
    delete ui;
}


//扫描串口并自动匹配连接
void Hamilton::onTimeout()
{
    foreach (QSerialPortInfo info, QSerialPortInfo::availablePorts())
    {
        serialInfo = nullptr;
        if(info.description() == tr("USB Serial Port"))
        {
            serialInfo = &info;
        }
    }

    if(serialInfo)
    {
        if(flag)
            return;
        serial = new QSerialPort();
        serial->setBaudRate(9600);
        serial->setPortName(serialInfo->portName());
        serial->setDataBits(QSerialPort::Data8);
        serial->setParity(QSerialPort::NoParity);
        serial->setStopBits(QSerialPort::OneStop);
        serial->setFlowControl(QSerialPort::NoFlowControl);
        if(serial->open(QIODevice::ReadWrite))
            report(Connect);
        if(serial->write(CommandHelper::getResetCommand().toLatin1()))
            report(Reset);
        ui->btnStart->setEnabled(true);
        ui->btnStop->setEnabled(true);
        ui->btnDown->setEnabled(true);
        ui->btnOutBubble->setEnabled(true);
        ui->btnReset->setEnabled(true);
        flag = true;
    }
    else
    {
       ui->btnStart->setEnabled(false);
       ui->btnStop->setEnabled(false);
       ui->btnDown->setEnabled(false);
       ui->btnOutBubble->setEnabled(false);
       ui->btnReset->setEnabled(false);
       flag = false;
       serial = nullptr;
       report(DisConnect);
    }
}

void Hamilton::on_btnStart_clicked()
{
    if(ui->comBox_Runtime->currentText() != tr("None"))
    {
        int time = ui->comBox_Runtime->currentText().toInt() * 60000;
        timer2->start(time);
        connect(timer2,SIGNAL(timeout()),this,SLOT(onStopCommand()));
    }

    if(serial->write(CommandHelper::getStartCommand(
                      ui->comboBox_Volume->currentText(),
                      ui->lineEditSpeed->text())
                     .toLatin1()))
        report(Start,ui->lineEditSpeed->text());
}

void Hamilton::onStopCommand()
{
    if(serial->write(CommandHelper::getStopCommand().toLatin1()))
        report(Stop);
    timer2->stop();
}


void Hamilton::on_btnStop_clicked()
{
    if(ui->btnStop->text() == tr("停止")){
        if(serial->write(CommandHelper::getStopCommand().toLatin1()))
            report(Stop);
        ui->btnStop->setText("继续");
    }else{
        if(serial->write(CommandHelper::getContinueCommand().toLatin1()))
            report(Continue);
        ui->btnStop->setText("停止");
    }
}

void Hamilton::on_btnReset_clicked()
{
    if(serial->write(CommandHelper::getResetCommand().toLatin1()))
        report(Reset);
}

void Hamilton::report(REPORT_TYPE type,QString descripe)
{
    QString time = QTime::currentTime().toString("HH:mm:ss");
    switch (type) {
    case Connect:
        ui->textEditReport->append(time + ": SerialPort connect successfully...");
        break;
    case DisConnect:
        ui->textEditReport->append(time + ": SerialPort wait for connection...");
        break;
    case Reset:
        ui->textEditReport->append(time + ": SerialPort reset successfully...");
        break;
    case Start:
        ui->textEditReport->append(time + QString(": Syringe start with %1 successfully...").arg(descripe));
        break;
    case Stop:
        ui->textEditReport->append(time + ": Syringe stop successfully...");
        break;
    case Continue:
        ui->textEditReport->append(time + ": SerialPort continue successfully...");
        break;
    case Outbubble:
        ui->textEditReport->append(time + ": Syringe is out bubble...");
        break;
    case Syringedown:
        ui->textEditReport->append(time + ": Syringe is down...");
        break;
    default:
        break;
    }
}

void Hamilton::on_btnOutBubble_clicked()
{
    if(serial->write(CommandHelper::getOutBubbleCommand().toLatin1()))
        report(Outbubble);
}

void Hamilton::on_btnDown_clicked()
{
    if(serial->write(CommandHelper::getSyringeDownCommand().toLatin1()))
        report(Syringedown);
}

指令生成函数

#ifndef COMMANDHELPER_H
#define COMMANDHELPER_H
#include <QString>
#include <QStringList>

class CommandHelper
{
public:
    static QString getResetCommand()
    {
        return QString("/1ZR\r\n");
    }


    //1.9 3.7 10 35.5 50 86 300 600
    static QString getStartCommand(QString volume,QString speed)
    {
        //int sumtime[8] = {2,4,10,35,50,86,300,600};
        if(speed.isEmpty())
            return "";
        QStringList tempList = volume.split(" ");
        double volumeTemp = tempList[0].toDouble();
        QString type = tempList[1];
        if(type == "ul")
            volumeTemp *= 1;
        else if(type == "ml")
            volumeTemp *= 1000;

        double speedTemp = speed.toDouble();
        double syringTime = volumeTemp/speedTemp*60;
        int syringeSpeed = 3000/syringTime;

        return QString("/1S1IA3000V%1OA0G65535R\r\n")
                    .arg(syringeSpeed);
    }

    static QString getStopCommand()
    {
        return QString("/1T\r\n");
    }

    static QString getContinueCommand()
    {
        return QString("/1R\r\n");
    }

    static QString getOutBubbleCommand()
    {
        return QString("/1S1IA3000OA0G5R\r\n");
    }

    static QString getSyringeDownCommand()
    {
        return QString("/1S1IA3000R\r\n");
    }

};

#endif // COMMANDHELPER_H

UI界面
在这里插入图片描述

这段代码可以适用已知端口的控制,只需要改变波特率,端口名称,数据位,校验位和停止位,还有改变相应的控制指令既可以使用。


版权声明:本文为u013850566原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。