有段時間,做電賽題的時候,在那看波形調PID參數,因爲要同時觀察電壓和兩路電流,無奈只有一臺示波器,遂有一想法,將單片機採集的電流數據通過串口發送給上位機,然後在上位機上以波形的形式顯示出來,方便觀察。因爲時間問題,都是現學現用,整體做的很簡陋,只是實現了要用到的功能,還請選擇性瀏覽。
1.上位機是基於Qt5編寫的,還用到了用於繪圖第三方庫--qcustomplot,具體使用可以百度,我這裏用的比較簡單,沒花時間去琢磨。首先用Qt創建一個項目,然後在項目的.pro文件裏添加,其中serialport是串口的,printsupport是繪圖庫qcustomplot的。
QT += serialport printsupport
2.相應的頭文件,第一個是對串口的設置,第二個是得到串口的信息,第三個自然就是用於繪圖的qcustomplot的頭文件了。
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include "qcustomplot.h"
3.定義相關變量,
private:
QSerialPort SerialPort; //用於設置串口
QSerialPortInfo SerialPortInfo;//用於得到串口信息
int Clk ; //x軸的時間數
QCustomPlot *Plot; //定義一個窗口繪圖的句柄
QVector <double> XData;//x軸數據
QVector <double> YData;//線1的y軸數據
QVector <double> Y1Data;//線2的y軸數據
QCustomPlot *PlotV; //定義另一個窗口繪圖的句柄
QVector <double> Y2Data;
QVector <double> Y3Data;
初始化相關變量
XData.resize(50); //分配空間
XData.value(0,1);
YData.resize(50);
Y1Data.resize(50);
Y2Data.resize(50);
Y3Data.resize(50);
ui->horizontalAMax->setRange(600,3000);
ui->horizontalAMax->setValue(600);
ui->horizontalAMin->setRange(0,600);
ui->horizontalAMin->setValue(0);
ui->horizontalVMax->setRange(500,800);
ui->horizontalVMax->setValue(600);
ui->horizontalVMin->setRange(0,500);
ui->horizontalVMin->setValue(400);
Plot = ui->widget; //指定窗口用於顯示波形
Plot->addGraph(); //添加一條線
Plot->addGraph(); //再添加一條線
Plot->graph(0)->setPen(QPen(Qt::red)); //設置第一根線的顏色爲紅色
Plot->graph(1)->setPen(QPen(Qt::blue)); //設置第二根線的顏色爲藍色
Plot->xAxis->setLabel("mS"); //設置x軸的標籤
Plot->yAxis->setLabel("mA"); //設置y軸的標籤
// Plot->rescaleAxes(true);
Plot->yAxis->setRange(0,700); //初始化y軸的範圍
Plot->xAxis->rescale(true); //讓x軸自動隨着數變化
PlotV = ui->widget_C;
PlotV->addGraph();
PlotV->addGraph();
PlotV->graph(0)->setPen(QPen(Qt::red));
PlotV->graph(1)->setPen(QPen(Qt::blue));
PlotV->xAxis->setLabel("mS");
PlotV->yAxis->setLabel("Count");
PlotV->yAxis->setRange(400,600);
PlotV->xAxis->rescale(true);
GraphShow(); //給圖形賦值
InitPort(); //初始化串口
QTimer::singleShot(80,this,&Widget::ReadPort);//定一定時器,方便接收數據
Clk = 0; //x軸的時間數,初試爲0
3.串口的初始化和出口數據的讀取
void Widget::InitPort() //判斷當前是否有效的串口,並得到相關得數據
{
//遍歷所有有效的串口,得到每個有效串口得數據
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
qDebug() << "Name :"<<info.portName();
qDebug() << "Description: "<<info.description();
qDebug() << "Manufacturer: "<<info.manufacturer();
QSerialPort serial;
serial.setPort(info);
if(serial.open(QIODevice::ReadWrite))
{//判斷是否能夠打開該串口,如果能,則將相應的串口名加到串口的下拉欄裏
ui->comboBoxCom->addItem(info.portName());
serial.close();//這裏只是起判定效果,不用以打開,還得關閉當前串口,方便查詢其他串口
}
}
}
//這個是開啓按鍵的槽函數,如果有有效的串口,然後進行打開操作,也可以充當關閉串口的作用
void Widget::on_pushButtonS_clicked()
{
//判斷當前程序處於什麼狀態中,如果沒有串口使用,則進入“開啓串口”
if(ui->pushButtonS->text() == "開啓串口")
{ //得到當前串口欄得數據
SerialPort.setPortName(ui->comboBoxCom->currentText());
if(SerialPort.open(QIODevice::ReadOnly))
{
SerialPort.setBaudRate(ui->comboBoxBaut->currentText().toInt());//設置波特率
SerialPort.setDataBits(QSerialPort::Data8);//設置數據位爲8位
SerialPort.setParity(QSerialPort::NoParity);//沒有奇偶校驗位
SerialPort.setFlowControl(QSerialPort::NoFlowControl);//沒有流控制
SerialPort.setStopBits(QSerialPort::OneStop);//設置一個停止位
ui->pushButtonS->setText("關閉串口"); //更改按鍵狀態
}
else{
qDebug() << "串口沒有打開";
return;
}
}else if(ui->pushButtonS->text() == "關閉串口")
{
SerialPort.close();
ui->pushButtonS->setText("開啓串口");
}
else{
qDebug() <<"無效操作";
}
}
//獲取串口數據,我這裏是採用每隔40ms來獲取一次數據
void Widget::ReadPort()
{
QTimer::singleShot(40,this,&Widget::ReadPort);
if(SerialPort.isOpen() == false)
return;
//得到串口數據
QByteArray temp = SerialPort.readAll();
if(temp.isEmpty())
return;
//將數據進行文本化顯示
ui->textEditR->append(QString(temp));
GetData(QString(temp));//處理當前數據,得出有效數據,這個函數實現是按要求來的,就不貼出來了
GraphShow();
}
4.波形的繪製--GraphShow函數的實現
void Widget::GraphShow()
{
Plot->graph(0)->setData(XData,YData);
Plot->graph(1)->setData(XData,Y1Data);
Plot->yAxis->setRange(Slither_aMin,Slither_aMax);
Plot->xAxis->rescale(true);
Plot->replot();//重新繪製
PlotV->graph(0)->setData(XData,Y2Data);
PlotV->graph(1)->setData(XData,Y3Data);
PlotV->yAxis->setRange(Slither_vMin,Slither_vMax);
PlotV->xAxis->rescale(true);
PlotV->replot();
}
5.另外就是一些按鍵和滑動欄的槽函數,視具體要求實現,就不貼出來了。其中刷新按鍵,是獲取當前有效串口,清除按鍵是清除text窗口的文本信息,四個滑行分別是調整相應窗口的y軸的上限和下限,方便觀察波形。
6.總結,其實qcustomplot和串口相關的函數使用還是挺簡單的,其中qcustomplot我只是用到了點皮毛,看官方提供的demo,可是非常好看和實用的。
最後用來觀察波形的時候,還是挺不錯的。因爲時間有點遠,沒有相應的圖貼出來了,還請見諒。學習,共勉。