既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
(3)、搜索串口代码
void Widget::on\_btn\_search\_port\_clicked()
{
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())//读取串口信息
{
myserial->setPort(info);//这里相当于自动识别串口号之后添加到了cmb,如果要手动选择可以用下面列表的方式添加进去
if(myserial->open(QIODevice::ReadWrite))
{
ui->comboBox->addItem(myserial->portName());//将串口号添加到cmb
myserial->close();//关闭串口等待人为(打开串口按钮)打开
}
}
}
(4)、打开串口代码
void Widget::on\_btn\_open\_port\_clicked()
{
if(serial_flag)
{
ui->comboBox->setDisabled(true); //禁止修改串口
myserial->setPortName(ui->comboBox->currentText()); //设置串口号
myserial->setBaudRate(QSerialPort::Baud115200); //设置波特
myserial->setDataBits(QSerialPort::Data8); //设置数据位数
myserial->setParity(QSerialPort::NoParity);//设置奇偶校验
myserial->setStopBits(QSerialPort::OneStop);//设置停止位
myserial->setFlowControl(QSerialPort::NoFlowControl);//非流控制
if(myserial->open(QIODevice::ReadWrite))
{
connect(myserial,&QSerialPort::readyRead,this,&Widget::AnalyzeData);
mystarttime = QDateTime::currentDateTime();//图像横坐标初始值参考点,读取初始时间
qDebug()<<"串口打开成功";
}
else
{
qDebug()<<"串口打开失败";
//QMessageBox::warning(this,tr("waring"),tr("串口打开失败"),QMessageBox::Close);
}
ui->btn_open_port->setText("关闭串口");
serial_flag = false;//串口标志位置失效
}
else
{
ui->comboBox->setEnabled(true);//串口号下拉按钮使能工作
myserial->close();
ui->btn_open_port->setText("打开串口");//按钮显示“打开串口”
serial_flag = true;//串口标志位置工作
}
}
(5)、数据分析代码
首先咱们先对串口发送过来的数据进行定义;
QByteArray mytemp = myserial->readAll();//定义mytemp为串口读取的所有数据
为了方便在控制台进行观测,我加了一句(这一句可有可无)
qDebug()<<"mytemp:"<<mytemp;
当有数据传输过来时,咱们先对数据进行拆分,因为有两个数据:温度数据和湿度数据,因此咱们先对数据进行一个简单的协议设定:数据中T与P中间的是温度数据,H与I之间的是湿度数据;当然这个数据协议也得在下位机程序里面同样设定;
QString StrI1=tr(mytemp.mid(mytemp.indexOf("T")+1,mytemp.indexOf("P")-mytemp.indexOf("T")-1));//自定义了简单协议,通过前面字母读取需要的数据
QString StrI2=tr(mytemp.mid(mytemp.indexOf("H")+1,mytemp.indexOf("I")-mytemp.indexOf("H")-1));
这个是stm32程序里面对串口发送的数据的协议设定;
然后两个文本框显示相对应的实时数据;
ui->line_Temp->setText(StrI1);//显示读取温度值
ui->line_Humi->setText(StrI2);//显示读取湿度值
由于串口发送过来的是字符串,因此咱们需要将字符串穿换成浮点数的数据格式;
float dataI1=StrI1.toFloat();//将字符串转换成float类型进行数据处理
float dataI2=StrI2.toFloat();//将字符串转换成float类型进行数据处理
获取系统时间;
mycurrenttime = QDateTime::currentDateTime();//获取系统时间
double xzb = mystarttime.msecsTo(mycurrenttime)/1000.0;//获取横坐标,相对时间就是从0开始
将转换好的数据发给坐标系显示;
ui->widget_plot->graph(0)->addData(xzb,dataI1);//添加数据1到曲线1
ui->widget_plot->graph(1)->addData(xzb,dataI2);//添加数据1到曲线1
最后设定横坐标显示范围;
if(xzb>30)
{
ui->widget_plot->xAxis->setRange((double)qRound(xzb-30),xzb);//设定x轴的范围
}
else ui->widget_plot->xAxis->setRange(0,30);//设定x轴的范围
ui->widget_plot->replot();//每次画完曲线一定要更新显示
(6)、坐标系的曲线显示代码
具体的就不分析了,里面都有注释;
void Widget::setupPlot()
{
//设置曲线一
ui->widget_plot->addGraph();//添加一条曲线
QPen pen;
pen.setWidth(1);//设置画笔线条宽度
pen.setColor(Qt::blue);
ui->widget_plot->graph(0)->setPen(pen);//设置画笔颜色
ui->widget_plot->graph(0)->setBrush(QBrush(QColor(0, 0, 255, 20))); //设置曲线画刷背景
ui->widget_plot->graph(0)->setName("0-100");
ui->widget_plot->graph(0)->setAntialiasedFill(false);
ui->widget_plot->graph(0)->setLineStyle((QCPGraph::LineStyle)1);//曲线画笔
ui->widget_plot->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssNone,5));//曲线形状
ui->widget_plot->addGraph();//添加一条曲线
pen.setColor(Qt::red);
ui->widget_plot->graph(1)->setPen(pen);//设置画笔颜色
ui->widget_plot->graph(1)->setBrush(QBrush(QColor(0, 0, 255, 20))); //设置曲线画刷背景
ui->widget_plot->graph(1)->setName("0-100");
ui->widget_plot->graph(1)->setAntialiasedFill(false);
ui->widget_plot->graph(1)->setLineStyle((QCPGraph::LineStyle)1);//曲线画笔
ui->widget_plot->graph(1)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssNone,5));//曲线形状
//设置图表
ui->widget_plot->xAxis->setLabel(QStringLiteral("时间/s"));//设置x坐标轴名称
ui->widget_plot->xAxis->setLabelColor(QColor(20,20,20));//设置x坐标轴名称颜色
ui->widget_plot->xAxis->setAutoTickStep(false);//设置是否自动分配刻度间距
ui->widget_plot->xAxis->setTickStep(2);//设置刻度间距5
ui->widget_plot->xAxis->setRange(0,30);//设定x轴的范围
ui->widget_plot->yAxis->setLabel(QStringLiteral("PH & TDS"));//设置y坐标轴名称
ui->widget_plot->yAxis->setLabelColor(QColor(20,20,20));//设置y坐标轴名称颜色
ui->widget_plot->yAxis->setAutoTickStep(false);//设置是否自动分配刻度间距
ui->widget_plot->yAxis->setTickStep(10);//设置刻度间距1
ui->widget_plot->yAxis->setRange(0,100);//设定y轴范围
ui->widget_plot->axisRect()->setupFullAxesBox(true);//设置缩放,拖拽,设置图表的分类图标显示位置
ui->widget_plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom| QCP::iSelectAxes);
ui->widget_plot->axisRect()->insetLayout()->setInsetAlignment(0,Qt::AlignTop | Qt::AlignRight);//图例显示位置右上
ui->widget_plot->legend->setVisible(true);//显示图例
ui->widget_plot->replot();
}
到此,所有代码就编写完成。运行一下:
如果咱们需要给它换个名称,便在ui->setupUi(this);下面添加这么一句话即可;这样的话就可以更改标题了,至于更换软件图标(左上角那个东东),也很简单,自己去搜一下如何添加ico文件,我这里就不多说了;
this->setWindowTitle(QString("温湿度监测系统")); //设置标题
3、测试结果
将制作的基于STM32的温湿度系统通过串口与电脑连接,打开上位机,点击搜索串口,然后点击打开串口,这样数据就会慢慢传递过来,同时也会绘制出两个参数的变化曲线;
效果如下
4、相关代码
4.1、tempandhumi.pro
#-------------------------------------------------
#
# Project created by QtCreator 2020-08-29T10:38:04
#
#-------------------------------------------------
QT += core gui
QT += serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
TARGET = tempandhumi
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT\_DISABLE\_DEPRECATED\_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
widget.cpp \
qcustomplot.cpp
HEADERS += \
widget.h \
qcustomplot.h
FORMS += \
widget.ui
4.2、widget.h
#ifndef WIDGET\_H
#define WIDGET\_H
#include <QWidget>
/\*------------------------用户代码头文件---------------------------\*/
#include <QtSerialPort/QSerialPort>//串口
#include <QtSerialPort/QSerialPortInfo>//串口
#include <QDebug>//用于在控制台输出调试信息
#include <QTime>//定时器
#include <QPainter>//坐标系绘图
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget \*parent = 0);
~Widget();
private slots:
void on\_btn\_search\_port\_clicked();
void on\_btn\_open\_port\_clicked();
void AnalyzeData();//数据读取
void setupPlot();//初始化
private:
Ui::Widget \*ui;
QSerialPort \*myserial;//声明串口类,myserial是QSerialPort的实例
bool serial_flag,start_flag;//定义两个标志位
QByteArray alldata;//接收串口数据
//绘图函数
QDateTime mycurrenttime;//系统当前时间
QDateTime mystarttime;//系统开始时间
};
#endif // WIDGET\_H
4.3、main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char \*argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
4.4、widget.cpp
#include "widget.h"
#include "ui\_widget.h"
#include <QVector>
#include <QMessageBox>
Widget::Widget(QWidget \*parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle(QString("温湿度监测系统")); //设置标题
myserial = new QSerialPort();
serial_flag = true;
start_flag = true;
setupPlot();//图形界面初始化函数
}
Widget::~Widget()
{
delete ui;
}
void Widget::on\_btn\_search\_port\_clicked()
{
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())//读取串口信息
{
myserial->setPort(info);//这里相当于自动识别串口号之后添加到了cmb,如果要手动选择可以用下面列表的方式添加进去
if(myserial->open(QIODevice::ReadWrite))
{
ui->comboBox->addItem(myserial->portName());//将串口号添加到cmb
myserial->close();//关闭串口等待人为(打开串口按钮)打开
}
}
}
void Widget::on\_btn\_open\_port\_clicked()
{
if(serial_flag)
{
ui->comboBox->setDisabled(true); //禁止修改串口
myserial->setPortName(ui->comboBox->currentText()); //设置串口号
myserial->setBaudRate(QSerialPort::Baud115200); //设置波特
myserial->setDataBits(QSerialPort::Data8); //设置数据位数
myserial->setParity(QSerialPort::NoParity);//设置奇偶校验
myserial->setStopBits(QSerialPort::OneStop);//设置停止位
myserial->setFlowControl(QSerialPort::NoFlowControl);//非流控制
if(myserial->open(QIODevice::ReadWrite))
{
connect(myserial,&QSerialPort::readyRead,this,&Widget::AnalyzeData);
mystarttime = QDateTime::currentDateTime();//图像横坐标初始值参考点,读取初始时间
qDebug()<<"串口打开成功";
}
else
{
qDebug()<<"串口打开失败";
//QMessageBox::warning(this,tr("waring"),tr("串口打开失败"),QMessageBox::Close);
}
ui->btn_open_port->setText("关闭串口");
serial_flag = false;//串口标志位置失效
}
else
{
ui->comboBox->setEnabled(true);//串口号下拉按钮使能工作
myserial->close();
ui->btn_open_port->setText("打开串口");//按钮显示“打开串口”
serial_flag = true;//串口标志位置工作
}
}
void Widget::AnalyzeData()
{
QByteArray mytemp = myserial->readAll();//定义mytemp为串口读取的所有数据
qDebug()<<"mytemp:"<<mytemp;
if(!mytemp.isEmpty())
{
QString StrI1=tr(mytemp.mid(mytemp.indexOf("T")+1,mytemp.indexOf("P")-mytemp.indexOf("T")-1));//自定义了简单协议,通过前面字母读取需要的数据
QString StrI2=tr(mytemp.mid(mytemp.indexOf("H")+1,mytemp.indexOf("I")-mytemp.indexOf("H")-1));
ui->line_Temp->setText(StrI1);//显示读取温度值
ui->line_Humi->setText(StrI2);//显示读取湿度值
float dataI1=StrI1.toFloat();//将字符串转换成float类型进行数据处理
float dataI2=StrI2.toFloat();//将字符串转换成float类型进行数据处理
mycurrenttime = QDateTime::currentDateTime();//获取系统时间
double xzb = mystarttime.msecsTo(mycurrenttime)/1000.0;//获取横坐标,相对时间就是从0开始
qDebug()<<"xzb:"<<xzb;
//注:下位机每隔10ms发送一次数据
ui->widget_plot->graph(0)->addData(xzb,dataI1);//添加数据1到曲线1
ui->widget_plot->graph(1)->addData(xzb,dataI2);//添加数据1到曲线1
if(xzb>30)
{
ui->widget_plot->xAxis->setRange((double)qRound(xzb-30),xzb);//设定x轴的范围
}
else ui->widget_plot->xAxis->setRange(0,30);//设定x轴的范围
ui->widget_plot->replot();//每次画完曲线一定要更新显示
}
}
void Widget::setupPlot()
{
//设置曲线一
ui->widget_plot->addGraph();//添加一条曲线
QPen pen;
pen.setWidth(1);//设置画笔线条宽度
pen.setColor(Qt::blue);
ui->widget_plot->graph(0)->setPen(pen);//设置画笔颜色
ui->widget_plot->graph(0)->setBrush(QBrush(QColor(0, 0, 255, 20))); //设置曲线画刷背景
ui->widget_plot->graph(0)->setName("0-100");
ui->widget_plot->graph(0)->setAntialiasedFill(false);
ui->widget_plot->graph(0)->setLineStyle((QCPGraph::LineStyle)1);//曲线画笔
ui->widget_plot->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssNone,5));//曲线形状
ui->widget_plot->addGraph();//添加一条曲线
pen.setColor(Qt::red);
ui->widget_plot->graph(1)->setPen(pen);//设置画笔颜色
ui->widget_plot->graph(1)->setBrush(QBrush(QColor(0, 0, 255, 20))); //设置曲线画刷背景
ui->widget_plot->graph(1)->setName("0-100");
ui->widget_plot->graph(1)->setAntialiasedFill(false);
ui->widget_plot->graph(1)->setLineStyle((QCPGraph::LineStyle)1);//曲线画笔
ui->widget_plot->graph(1)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssNone,5));//曲线形状
//设置图表
ui->widget_plot->xAxis->setLabel(QStringLiteral("时间/s"));//设置x坐标轴名称
ui->widget_plot->xAxis->setLabelColor(QColor(20,20,20));//设置x坐标轴名称颜色
ui->widget_plot->xAxis->setAutoTickStep(false);//设置是否自动分配刻度间距
ui->widget_plot->xAxis->setTickStep(2);//设置刻度间距5
ui->widget_plot->xAxis->setRange(0,30);//设定x轴的范围
ui->widget_plot->yAxis->setLabel(QStringLiteral("PH & TDS"));//设置y坐标轴名称
ui->widget_plot->yAxis->setLabelColor(QColor(20,20,20));//设置y坐标轴名称颜色
ui->widget_plot->yAxis->setAutoTickStep(false);//设置是否自动分配刻度间距
ui->widget_plot->yAxis->setTickStep(10);//设置刻度间距1
ui->widget_plot->yAxis->setRange(0,100);//设定y轴范围
ui->widget_plot->axisRect()->setupFullAxesBox(true);//设置缩放,拖拽,设置图表的分类图标显示位置
ui->widget_plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom| QCP::iSelectAxes);
ui->widget_plot->axisRect()->insetLayout()->setInsetAlignment(0,Qt::AlignTop | Qt::AlignRight);//图例显示位置右上
ui->widget_plot->legend->setVisible(true);//显示图例


**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**
**[如果你需要这些资料,可以戳这里获取](https://gitee.com/vip204888)**