串口温度采集
F:\学科、技能、编程\【编程-文件\proj\串口温度采集软件
使用说明
#include "mainwindow.h" #include "ui_mainwindow.h" /////////////////////////////////////// MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ui->closeMyComBtn->setEnabled(false); //开始“关闭串口”按钮不可用 ui->sendMsgBtn->setEnabled(false); //开始“发送数据”按钮不可用 ff=0; LenChaosheng = 0; setWindowTitle("数据采集系统 "); helpAction = new QAction(tr("&Information"), this); Help = menuBar()->addMenu(tr("系统说明")); //创建菜单项 Help->addAction(helpAction); //添加动作 connect(helpAction, SIGNAL(triggered()), this, SLOT(help())); connect(this,SIGNAL(showtemperature()),this,SLOT(showtemp()));//连接信号与槽,更新右边项; connect(this,SIGNAL(showLength()),this,SLOT(showLen()));//连接信号与槽,更新右边项; //绘图测试 // QwtPlotCurve *cSin = new QwtPlotCurve("y = sin(x)"); QwtPlot * plot = ui->qwtPlot; plot->setTitle( "Temperature" );//标题 plot->setCanvasBackground( Qt::yellow );//背景颜色 plot->setAxisScale( QwtPlot::yLeft, 0.0, 40 );//纵轴数据范围 plot->setAxisScale( QwtPlot::xBottom, 0.0, 20 );//横轴数据范围 plot->insertLegend( new QwtLegend() ); //图例 plot->setAxisTitle(QwtPlot::yLeft,tr("温度/°C")); plot->resize( 550, 350 ); //添加网格 QwtPlotGrid *grid = new QwtPlotGrid(); grid->attach( plot ); //为曲线设置样式 curve = new QwtPlotCurve();// curve2 = new QwtPlotCurve();// curve->setTitle( "temperature" ); curve->setPen( Qt::blue, 1 ); curve->setRenderHint( QwtPlotItem::RenderAntialiased, true ); //为曲线设置点的样式 QwtSymbol *symbol = new QwtSymbol( QwtSymbol::Ellipse, QBrush( Qt::blue ), QPen( Qt::red, 1 ), QSize( 2, 4 ) ); curve->setSymbol( symbol ); //为曲线设置数据点 // QPolygonF points; // points << QPointF( 0.0, 4.4 ) << QPointF( 1.0, 3.0 ) // << QPointF( 2.0, 4.5 ) << QPointF( 3.0, 6.8 ) // << QPointF( 4.0, 7.9 ) << QPointF( 5.0, 7.1 ); // curve->setSamples( points ); // // curve->attach( plot ); } MainWindow::~MainWindow() { delete ui; } //读取串口槽函数 void MainWindow::readMyCom()//读串口函数 { QByteArray temp = myCom->readAll(); //读取串口缓冲区的所有数据给临时变量temp ui->textBrowser->insertPlainText(temp); //将串口的数据显示在窗口的文本浏览器中 // QByteArray* addr = &temp; //解析 serialData.append(temp.constData()); serialProcess(); tempShow(); } //打开串口 void MainWindow::on_openMyComBtn_clicked() { QString portName = ui->portNameComboBox->currentText(); //获取串口名 myCom = new Win_QextSerialPort(portName,QextSerialBase::EventDriven); //定义串口对象,并传递参数,在构造函数里对其进行初始化 myCom ->open(QIODevice::ReadWrite); //打开串口 if(ui->baudRateComboBox->currentText()==tr("9600")) //根据组合框内容对串口进行设置 myCom->setBaudRate(BAUD9600); else if(ui->baudRateComboBox->currentText()==tr("115200")) myCom->setBaudRate(BAUD115200); if(ui->dataBitsComboBox->currentText()==tr("8")) myCom->setDataBits(DATA_8); else if(ui->dataBitsComboBox->currentText()==tr("7")) myCom->setDataBits(DATA_7); if(ui->parityComboBox->currentText()==tr("无")) myCom->setParity(PAR_NONE); else if(ui->parityComboBox->currentText()==tr("奇")) myCom->setParity(PAR_ODD); else if(ui->parityComboBox->currentText()==tr("偶")) myCom->setParity(PAR_EVEN); if(ui->stopBitsComboBox->currentText()==tr("1")) myCom->setStopBits(STOP_1); else if(ui->stopBitsComboBox->currentText()==tr("2")) myCom->setStopBits(STOP_2); myCom->setFlowControl(FLOW_OFF); myCom->setTimeout(500); connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom())); //信号和槽函数关联,当串口缓冲区有数据时,进行读串口操作 ui->openMyComBtn->setEnabled(false); //打开串口后“打开串口”按钮不可用 ui->closeMyComBtn->setEnabled(true); //打开串口后“关闭串口”按钮可用 ui->sendMsgBtn->setEnabled(true); //打开串口后“发送数据”按钮可用 ui->baudRateComboBox->setEnabled(false); //设置各个组合框不可用 ui->dataBitsComboBox->setEnabled(false); ui->parityComboBox->setEnabled(false); ui->stopBitsComboBox->setEnabled(false); ui->portNameComboBox->setEnabled(false); } //关闭串口 void MainWindow::on_closeMyComBtn_clicked() { myCom->close(); ui->openMyComBtn->setEnabled(true); //关闭串口后“打开串口”按钮可用 ui->closeMyComBtn->setEnabled(false); //关闭串口后“关闭串口”按钮不可用 ui->sendMsgBtn->setEnabled(false); //关闭串口后“发送数据”按钮不可用 ui->baudRateComboBox->setEnabled(true); //设置各个组合框可用 ui->dataBitsComboBox->setEnabled(true); ui->parityComboBox->setEnabled(true); ui->stopBitsComboBox->setEnabled(true); ui->portNameComboBox->setEnabled(true); } //串口界面发送数据 void MainWindow::on_sendMsgBtn_clicked() { myCom->write(ui->sendMsgLineEdit->text().toAscii()); //以ASCII码形式将数据写入串口 } //文本框数据变化后的槽函数 void MainWindow::on_textBrowser_textChanged() { } //串口数据处理 void MainWindow::serialProcess() { qDebug()<<"receive1."; qDebug()<<serialData; // char * ch="##"; QByteArray ch; ch.append('#'); ch.append('#'); if(serialData.contains(ch)) { qDebug()<<"receivech"; // int i = serialData.count(ch); for(;serialData.count(ch)>1;)//读取温度数据包,至少有一个 { qDebug()<<"2222222"; int ind = serialData.indexOf(ch); // 第一个ind if(ind > 0)// 去除前面的非完整数据 { serialData.remove(0,ind); } ind = serialData.indexOf(ch); int ind2 = serialData.indexOf(ch,ind+2); //第二个ind qDebug()<<"ind "<<ind<<" "<<ind2; if(ind2 - ind >=6)//可能有数据 { ind = serialData.indexOf(ch); ind = ind+2; unsigned char flag = serialData.at(ind); if(flag == '0')//表示接收到温度 { ind ++; int M = (unsigned char)serialData.at(ind); ind ++; int L = (unsigned char)serialData.at(ind); ind ++; // if((unsigned char)serialData.at(ind) == (unsigned char)(~(L + M)) ) // { // int t = M*256 + L; // tempList.append(t);//保存温度值 // } qreal t = (M*256 + L)*0.0625; qDebug()<<"wendudd"<<t; tempList.append(t);//保存温度值 } if(flag == '1') { ind ++; int M = (unsigned char)serialData.at(ind); ind ++; int L = (unsigned char)serialData.at(ind); ind ++; qreal t = (M*256 + L)*1.87/100.0; qDebug()<<"超声"<<t; LenChaosheng = t; emit showLength(); // tempList.append(t);//保存温度值 } } //去除ind到ind2之间的数据 serialData.remove(ind,ind2-ind); } } } void MainWindow::tempShow() { if(tempList.size()<1) return; QwtPlot * plot = ui->qwtPlot; //qDebug()<<"tmep"<<tempList<< tempList.size(); //为曲线设置数据点 QPolygonF points; int size = tempList.size(); for (int i=0;i<size;i++) { points<< QPointF( i, tempList.at(i)); } curve->setSamples( points ); plot->setAxisScale( QwtPlot::yLeft, 0, 40 );//纵轴数据范围 plot->setAxisScale( QwtPlot::xBottom, 0.0, size );//横轴数据范围 curve->attach( plot ); plot->replot(); emit showtemperature(); //显示当前温度 // ui->lineEdit_currentTemp->setText(QString("1%").arg(tempList.at(size-1))); } //显示当前温度 void MainWindow::showtemp() { if(tempList.size()>0) { ui->lineEdit_currentTemp->setText(QString("%1%2").arg(tempList.at(tempList.size()-1)).arg("°C")); } } //保存数据至文本文件 void MainWindow::on_pushButton_savedata_clicked() { //保存数据 QString name = "温度数据"; // QTime current_time = QTime::currentTime(); // int hour = current_time.hour(); //int minute = current_time.minute(); //int second = current_time.second(); QDateTime current_date_time = QDateTime::currentDateTime(); //获取当前时间 QString str = current_date_time.toString("yyyy-MM-dd hh-mm-ss"); name.append(str); name.append(".txt"); QFile file(name); if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) return; QTextStream out(&file); out<<"Temprature data save at:"<<str<<endl; int size = tempList.size(); for (int i=0;i<size;i++) { out<<tempList.at(i)<<endl; } file.close(); // // out << "The magic number is: " << 49 << "\n"; // QString str1 = "温度数据成功保存至文件"; str1.append(name); QMessageBox::about(NULL, "保存数据成功", str1); } //保存温度曲线至pdf文件 void MainWindow::on_pushButton_savecurve_clicked() { QwtPlot * plot = ui->qwtPlot; QwtPlotRenderer renderer1; renderer1.exportTo( plot, "temprature.pdf" ); // // // QPrinter printer( QPrinter::HighResolution ); // printer.setOrientation( QPrinter::Landscape ); // printer.setOutputFileName( "wendu.pdf" ); // // QPrintDialog dialog( &printer ); // if ( dialog.exec() ) // { // QwtPlotRenderer renderer; // // if ( printer.colorMode() == QPrinter::GrayScale ) // { // renderer.setDiscardFlag( QwtPlotRenderer::DiscardBackground ); // renderer.setDiscardFlag( QwtPlotRenderer::DiscardCanvasBackground ); // renderer.setDiscardFlag( QwtPlotRenderer::DiscardCanvasFrame ); // renderer.setLayoutFlag( QwtPlotRenderer::FrameWithScales ); // } // // renderer.renderTo( ui->qwtPlot, printer ); // } } void MainWindow::on_pushButton_4_clicked() { //文件获取对话框 QString fileName = QFileDialog::getOpenFileName(this,tr("文件对话框"), "..",tr("温度文件(*txt)")); //获取模型文件 qDebug()<< "fileNames:" << fileName; QFile f(fileName); if(!f.open(QIODevice::ReadOnly | QIODevice::Text)) { // cout << "Open failed." << endl; QErrorMessage dialog(this); dialog.setWindowTitle(tr("Erro")); dialog.showMessage(tr("文件打开失败!")); return ; } tempLoad.clear();//加载的数据存储在列表中 QTextStream txtInput(&f); QString lineStr; while(!txtInput.atEnd()) { lineStr = txtInput.readLine(); qDebug()<< lineStr; if(lineStr.startsWith("T")) { continue; } tempLoad.append( lineStr.toDouble()); qDebug()<< lineStr.toDouble(); //cout << lineStr << endl; } f.close(); //加载完毕之后进行显示 //绘图测试 // QwtPlotCurve *cSin = new QwtPlotCurve("y = sin(x)"); QwtPlot * plot = ui->qwtPlot_2; plot->setTitle( "Temperature—_Loaded" );//标题 plot->setCanvasBackground( Qt::yellow );//背景颜色 plot->setAxisScale( QwtPlot::yLeft, 0.0, 40 );//纵轴数据范围 plot->setAxisScale( QwtPlot::xBottom, 0.0, 20 );//横轴数据范围 plot->insertLegend( new QwtLegend() ); //图例 plot->setAxisTitle(QwtPlot::yLeft,"温度/°C"); // plot->resize( 400, 250 ); //添加网格 // QwtPlotGrid *grid = new QwtPlotGrid(); // grid->attach( plot ); //为曲线设置样式 // curve->setTitle( "temperature" ); curve2->setPen( Qt::blue, 1 ); // curve2->setRenderHint( QwtPlotItem::RenderAntialiased, true ); //为曲线设置点的样式 // QwtSymbol *symbol = new QwtSymbol( QwtSymbol::Ellipse, // QBrush( Qt::blue ), QPen( Qt::red, 1 ), QSize( 2, 4 ) ); // curve2->setSymbol( symbol ); //为曲线设置数据点 //qDebug()<<"tmep"<<tempList<< tempList.size(); //为曲线设置数据点 QPolygonF points; int size = tempLoad.size(); for (int i=0;i<size;i++) { points<< QPointF( i, tempLoad.at(i)); } curve2->setSamples( points ); plot->setAxisScale( QwtPlot::yLeft, 0, 30 );//纵轴数据范围 plot->setAxisScale( QwtPlot::xBottom, 0.0, size );//横轴数据范围 curve2->attach( plot ); plot->replot(); //表格绘制 tableWidget QTableWidget *table = ui->tableWidget; table->setColumnCount(2); table->setRowCount(size); table->setColumnWidth(0,50); //设置表格行标题 QStringList headerLabels; headerLabels << "Index" << "Temp data"; table->setHorizontalHeaderLabels(headerLabels); //设置表格行标题的对齐方式 table->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); //设置表格的内容 for (int i=0;i<size;i++) { table->setRowHeight(i, 22);//设置每一行的高度 table->setItem(i,0,new QTableWidgetItem(QString::number(i+1))); table->setItem(i,1,new QTableWidgetItem(QString::number(tempLoad.at(i))+" °C" )); } ////设置行表题 //QStringList rowLabels; //rowLabels << "Line1" << "Line2" << "Line3" << "Line4"; //table->setVerticalHeaderLabels(rowLabels); //自动调整最后一列的宽度使它和表格的右边界对齐 table->horizontalHeader()->setStretchLastSection(true); //设置表格的选择方式 table->setSelectionBehavior(QAbstractItemView::SelectItems); //设置编辑方式 table->setEditTriggers(QAbstractItemView::DoubleClicked); //查询操作,求平均值、最大值、最小值等 int currentindex = ui->comboBox->currentIndex(); if(currentindex == 0) //平均值 { qreal sum = 0; for (int i=0;i<size;i++) { sum+=tempLoad.at(i); } ui->lineEdit->setText(QString("%1%2").arg(sum/size).arg("°C")); } if(currentindex == 1) //平均值 { qreal max = tempLoad.at(0); for (int i=0;i<size;i++) { if(tempLoad.at(i) > max) { max = tempLoad.at(i) ; } } ui->lineEdit->setText(QString("%1%2").arg(max).arg("°C")); } if(currentindex == 2) //最小值 { qreal min = tempLoad.at(0); for (int i=0;i<size;i++) { if(tempLoad.at(i) < min) { min = tempLoad.at(i) ; } } ui->lineEdit->setText(QString("%1%2").arg(min).arg("°C")); } } void MainWindow::on_comboBox_currentIndexChanged(int index) { //查询操作,求平均值、最大值、最小值等 int size = tempLoad.size(); int currentindex = ui->comboBox->currentIndex(); if(currentindex == 0) //平均值 { qreal sum = 0; for(int i=0;i<size;i++) { sum+=tempLoad.at(i); } ui->lineEdit->setText(QString("%1%2").arg(sum/size).arg("°C")); } if(currentindex == 1) //平均值 { qreal max = tempLoad.at(0); for (int i=0;i<size;i++) { if(tempLoad.at(i) > max) { max = tempLoad.at(i) ; } } ui->lineEdit->setText(QString("%1%2").arg(max).arg("°C")); } if(currentindex == 2) //最小值 { qreal min = tempLoad.at(0); for (int i=0;i<size;i++) { if(tempLoad.at(i) < min) { min = tempLoad.at(i) ; } } ui->lineEdit->setText(QString("%1%2").arg(min).arg("°C")); } } void MainWindow::closeEvent(QCloseEvent *event)//关闭窗口前检查 { if( ui->openMyComBtn->isEnabled()) return; QMessageBox::StandardButton button; button = QMessageBox::question(this, tr("退出程序"), QString(tr("串口未断开连接,是否结束操作退出?")), QMessageBox::Yes| QMessageBox::No); //QMessageBox::Yes | QMessageBox::No); if (button == QMessageBox::No) { event->ignore(); //忽略退出信号,程序继续运行 } else if (button == QMessageBox::Yes) { event->ignore(); //忽略退出信号,程序继续运行 //event->accept(); //接受退出信号,程序退出 } } void MainWindow::on_pushButton_control_clicked() { char a[] = "1"; myCom->write(a); //以ASCII码形式将数据写入串口 } void MainWindow::help() //帮助菜单的动作响应槽函数 { QString local_path = QString("Information.txt"); //a.txt、a.exe、a.mp3、a.mp4、a.rmvb等 // QString path = QString("file:///") + local_path; QDesktopServices::openUrl(QUrl(local_path, QUrl::TolerantMode)); //打开帮助文档 } //显示当前温度 void MainWindow::showLen() { if(LenChaosheng >0) { ui->lineEdit_chaosheng->setText(QString("%1%2").arg( LenChaosheng).arg(" CM")); } }