赞
踩
与下位机,单片机通信少不了使用串口进行通信,Qt 也提供了串口通信的类。
使用的时候在 pro 添加这句导入模块
QT += serialport
1.连接串口 第一步就是 要先获取到 可连接的所有的串口的名字
获取到串口名字列表以后,我们需要选择一个需要连接的 (自行根据选择)
- foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
- {
- QSerialPort serial;
- serial.setPort(info);
- if (serial.open(QIODevice::ReadWrite))
- {
- portList.push_back(serial.portName());
- serial.close();
- }
- }
2.根据串口名字 打开串口
进行初始化串口
- void frmserialport::inialSerialPort() //初始化串口(串口号、波特率、数据位、停止位、流控制)
- {
- m_flag = 0;
- QList<QString> portList;
- QStringList baudList;
- QStringList parityList;
- QStringList dataBitList;
- QStringList stopBitList;
- QStringList flowList;
-
- baudList<<"9600"<<"115200"<<"460800";
- dataBitList<<"8";
- parityList<<"无";
- stopBitList<<"1";
- flowList<<"无";
- }
- void frmserialport::on_btn_Open_clicked() //打开串口
- {
- m_pSerialPort = new QSerialPort(this);
- m_pSerialPort->setPortName(ui->cbox_PortName->currentText()); //串口名
- m_pSerialPort->setBaudRate(ui->cbox_BaudRate->currentText().toInt()); //波特率
- switch (ui->cbox_DataBit->currentIndex()) {
- case 0:
- m_pSerialPort->setDataBits(QSerialPort::Data8); //数据位为8位
- break;
- default:
- break;
- }
-
- switch (ui->cbox_Parity->currentIndex()) {
- case 0:
- m_pSerialPort->setParity(QSerialPort::NoParity); //无校验位
- break;
- default:
- break;
- }
-
- switch (ui->cbox_StopBit->currentIndex()) {
- case 0:
- m_pSerialPort->setStopBits(QSerialPort::OneStop); //一位停止位
- break;
- default:
- break;
- }
-
- switch (ui->cbox_Flow->currentIndex()) {
- case 0:
- m_pSerialPort->setFlowControl(QSerialPort::NoFlowControl); //无流控制
- break;
- default:
- break;
- }
-
- if (!m_pSerialPort->open(QIODevice::ReadWrite)){
- QMessageBox::information(this,"提示","串口连接失败");
- }
- else{
- QMessageBox::information(this,"提示",ui->cbox_PortName->currentText() + tr("连接成功"));
- ui->btn_Open->setEnabled(false);
- ui->btn_Close->setEnabled(true);
- ui->btn_Send->setEnabled(true);
- }
- connect(m_pSerialPort,&QSerialPort::readyRead,this,&frmserialport::serialReadData);
-
3.发送数据和清除数据
- void frmserialport::on_btn_Send_clicked() //发送数据
- {
- QString strMessage = ui->txt_Send->toPlainText();
- sendCMD(strMessage);
- }
-
- void frmserialport::on_btn_Clear_clicked() //清除
- {
- if (!ui->txt_Receive->toPlainText().isEmpty()){
- ui->txt_Receive->clear();
- ui->btn_Clear->setEnabled(false);
- }
- }
4.关闭串口
- void frmserialport::on_btn_Close_clicked() //关闭串口
- {
- m_pSerialPort->clear();
- m_pSerialPort->close();
- delete m_pSerialPort;
- m_pSerialPort = nullptr;
- m_flag = 0;
-
- ui->btn_Open->setEnabled(true);
- ui->btn_Close->setEnabled(false);
- ui->btn_Send->setEnabled(false);
- }
1.QCharts的使用可以参考《Qt开发技术:QCharts》
2.想要绘制曲线图需要定义画布 , 线 , 轴 ,我的x轴是用实时时间所以要加多一个定时器
- //绘图变量和坐标
- QDateTimeAxis *axisX_aX; //用时间表示x轴
- QDateTimeAxis *axisX_aY;
- QDateTimeAxis *axisX_aZ;
- QValueAxis *axisY_aX; //aX数据,表示y轴
- QValueAxis *axisY_aY; //aY数据
- QValueAxis *axisY_aZ; //aZ数据
- QTimer *timer; //图表的计时器
- QChart *chart;
- QSplineSeries *series_aX; //数据点
- QSplineSeries *series_aY;
- QSplineSeries *series_aZ;
3.设置数据,定义绘图
- axisX_aX->setFormat("hh:mm:ss");
- axisY_aX->setRange(-3,3);
- chart->addSeries(series_aX);
- axisX_aX->setTickCount(10);
- axisY_aX->setTickCount(10);
- axisX_aX->setTitleText("实时时间");
- axisY_aX->setTitleText("加速度A(G):");
- series_aX->setPen(QColor(Qt::red));
- axisY_aX->setLinePen(peny);
- axisX_aX->setLinePen(peny);
- chart->addAxis(axisX_aX , Qt::AlignBottom);
- chart->addAxis(axisY_aX , Qt::AlignLeft);
- series_aX->attachAxis(axisX_aX);
- series_aX->attachAxis(axisY_aX);
- QDateTime currentTime = QDateTime::currentDateTime(); //实时时间
-
- chart->axisX()->setMin(QDateTime::currentDateTime().addSecs(-60*1));
- chart->axisX()->setMax(QDateTime::currentDateTime().addMSecs(0));
-
- qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
- series_aX->append(currentTime.toMSecsSinceEpoch() , aX); //提供x,y轴数据
最后就实现啦!
我是qt小白,刚开始学习qt不久,如果有问题请大家多多指教,感谢大家阅读,觉得不错的话点个赞收藏下呗!!最后列出几个我写这个项目时遇到的问题吧!
解决方案:串口延时接收数据
处理思路:创建两个槽函数(SLOT),当串口有数据应答时系统会给一个 readyRead()信号,用槽函数接收一个信号,并处理。在进入到这个槽函数后设置一个定时,当定时走完会有一个timeout()信号,用另一个槽函数处理定时完成后的事情。
这里感谢Humboldt大佬的思路。
- //connect(timer,SIGNAL(timeout()),this,SLOT(RealtimeDataSlot())); 没有延时接受数据前的槽函数
-
- connect(timer,SIGNAL(timeout()),this,SLOT(DrawLine()));
-
-
- //connect(m_pSerialPort,&QSerialPort::readyRead,this,&frmserialport::serialReadData); //没有延时接受数据前的槽函数
-
- //延时接收数据
- connect(m_pSerialPort,SIGNAL(readyRead()),this,SLOT(on_serialReadData())); //当有数据来是显示
- connect(&timer1,SIGNAL(timeout()),this,SLOT(serialReadData())); //当定时结束时进入
2.分离串口数据
我采用的是字符串分隔的方法
因为串口读取到的数据转成QString后长度是不一定的,所以用到了索引的方法解决。
- QByteArray receiveData;
- receiveData = m_pSerialPort->readAll();
- qDebug()<<"Re:"<<receiveData;
-
- QString str=receiveData;
- int x1=str.indexOf(":");
- int x=str.indexOf("G");
- int x2=x-x1-1;
成功截取到后就转成Double类型提供Y轴数据给曲线。
如果侵犯版权等问题,私聊马上删除。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。