需求
通过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 版权协议,转载请附上原文出处链接和本声明。