本帖最后由 w494143467 于 2021-3-11 09:09 编辑
1.介绍
上一篇说明了Demo的设计方案,今天这一篇就专门来写一个上位机,主要分为数据显示和数据通信部分,同时通过波形图显示出当时的速度,同时还需要设计一下与下位机的通信协议,这个只做一个简单的设计,因为通信的内容不多,所以采用简单的方案。
2.界面设计
对电机的主要设计四个按钮【开始】、【停止】、【正转】和【反转】,同时有一个滑杆用于控制速度,速度波形图采用QWT插件中的【QwtPlot】控件,如下图1所示。
图1
界面设计完成如下图2所示。
图2
这里创建一个类来对串口进行扫描,这样就可以动态的选择插入的串口设备了,代码如下所示。
- //默认构造
- SerialPortList::SerialPortList()
- {
- timer = new QTimer;
- scanCycleMs = 1000;
- oldPortStringList.clear();
- connect(timer, SIGNAL(timeout()), this, SLOT(onTimeOut()));
- }
- //自定义扫描周期构造
- SerialPortList::SerialPortList(quint16 CycleMs)
- {
- timer = new QTimer;
- scanCycleMs = CycleMs;
- oldPortStringList.clear();
- connect(timer, SIGNAL(timeout()), this, SLOT(onTimeOut()));
- }
- SerialPortList::~SerialPortList()
- {
- delete timer;
- }
- //开始扫描
- void SerialPortList::ScanStart()
- {
- timer->stop();
- timer->start(scanCycleMs);
- }
- //停止扫描
- void SerialPortList::ScanStop(){
- timer->stop();
- }
- //周期扫描服务
- void SerialPortList::onTimeOut(){
- QStringList newPortStringList;
- //搜索串口
- foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){
- #if DEBUG_INFOR_EN
- qDebug() << "Name : " << info.portName();
- qDebug() << "Description : " << info.description();
- qDebug() << "Manufacturer: " << info.manufacturer();
- #endif
- newPortStringList += info.portName();
- }
- //更新旧的串口列表
- if(newPortStringList.size() != oldPortStringList.size())
- {
- oldPortStringList = newPortStringList;
- emit onNewSerialPort(oldPortStringList);
- }
- }
然后创建自定义的串口扫描类,再添加上串口通信对象,同时绑定串口接收信号槽,最后设置一下波形图的上下限,初始化代码如下所示。
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- serial = new QSerialPort; //声明对象
- curve = new QwtPlotCurve();
- portList = new SerialPortList(200); //创建串口数据
- QObject::connect(portList, SIGNAL(onNewSerialPort(QStringList)), this, SLOT(onNewPortList(QStringList)));
- QObject::connect(serial,SIGNAL(readyRead()), this, SLOT(SerialReadData()),Qt::UniqueConnection); //绑定串口接收服务信号槽
- ui->qwtPlot->setAxisScale(QwtPlot::xBottom, 0, 100);
- ui->qwtPlot->setAxisScale(QwtPlot::yLeft, 0, 100);
- portList->ScanStart(); //开始串口扫描
- }
最后实现按钮发送字符串,接收串口过来的数据即可,接收的处理函数如下所示。
- /*
- 0~100:速度
- 255:反转
- 254:正转
- 253:停止
- 252:开始
- */
- void MainWindow::SerialReadData()
- {
- QByteArray readArray = serial->readAll();
- quint8 readInt = quint8(readArray.at(0));
- if(readInt <= 100) //小于100是速度
- {
- ui->lblMotorSpeed->setText(QString::number(readInt, 10) + "km/h");
- xdata.append(xdata.size()+1);
- ydata.append(readInt);
- curve->setSamples(xdata,ydata);
- curve->attach(ui->qwtPlot);
- ui->qwtPlot->replot();
- }
- else if(readInt == 252)
- {
- ui->lblMotorState->setText("开始");
- }
- else if(readInt == 253)
- {
- ui->lblMotorState->setText("停止");
- }
- else if(readInt == 254)
- {
- ui->lblMotorDirection->setText("正转");
- }
- else if(readInt == 255)
- {
- ui->lblMotorDirection->setText("反转");
- }
- }
发送的就根据协议进行发送即可,运行后的界面如下图3所示。
图3
接收一定数据后的波形图如下图4和图5所示。
图4 图5
3.总结
上位机基本可以说是完成了,就剩下位机的程序+联调了,上位机设计还是比较简单的,如果设计好了,给大家录一个视频看看,分享一下上位机的程序,不过需要安装QWT插件,大家自行百度哈,如果真的需要安装教程,我后面出一个,希望大家能够继续支持我哈!
下位机程序:
|