基于小熊派光强传感器BH1750状态机驱动项目再度升级(带上位机曲线显示)

简介: 基于小熊派光强传感器BH1750状态机驱动项目再度升级(带上位机曲线显示)

上次我们基于小熊派光强传感器项目实现了光强读取并在LCD上显示,文章链接如下:

基于小熊派光强传感器BH1750状态机驱动项目升级(带LCD屏显示)

这一节,我们再次对这个项目升级下,配个带可缩放曲线的上位机读取光强进行显示吧!


本节,你将了解工作中上位机和MCU的是如何来配合使用的。


在工作中,我们常常需要对一些传感器的某些数值进行长时间的测试和观察,以了解传感器的性能,在电子工程里,我们经常听到的测试曲线莫过于电池充放电曲线了,通过电池充放电曲线,我们很容易可以知道电池在实际使用过程中满电和馈电的状态以及电池的使用周期等等,今晚,我们就让光强通过曲线显示出来,用QT+QCustomPlot来实现,最终效果如下视频操作所示:

640.png

一、QCustomPlot简介

以下是QCustomPlot的官网:

https://www.qcustomplot.com/


640.png640.png

QCustomPlot是一个小型的Qt画图标类,支持绘制静态曲线、动态曲线、多重坐标曲线,柱状图,蜡烛图等。只需要在项目中加入头文件qcustomplot.h和qcustomplot.cpp文件,然后使一个widget提升为QCustomPlot类,即可使用。

二、更改上节的MCU端程序

这次,我们选用串口和上位机进行通信,所以我们需要设计一个传感器和上位机通信的协议,协议如下:

序号 光强值 \r\n

当序号大于等于65535时,自动清0。


修改上节的main函数为如下:

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
    /* USER CODE BEGIN 1 */
    /*流水号*/
    int serial_number = 0;
    char display_buf[20] = {0};
    char procol_buf[20] = {0};
    /* USER CODE END 1 */
    /* MCU Configuration--------------------------------------------------------*/
    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    HAL_Init();
    /* USER CODE BEGIN Init */
    /* USER CODE END Init */
    /* Configure the system clock */
    SystemClock_Config();
    /* USER CODE BEGIN SysInit */
    /* USER CODE END SysInit */
    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_I2C1_Init();
    MX_USART1_UART_Init();
    MX_SPI2_Init();
    /* USER CODE BEGIN 2 */
    /*串口初始化后加这个延时,防止后面的printf打印乱码*/
    HAL_Delay(200);
    LCD_Init();
    LCD_Clear(BLACK);//清屏为黑色
    LCD_ShowString(5, 10, 240, 32, 32, "BearPi LuxTest");//显示字符串,字体大小32*32
    Init_BH750();
    timer_init(&lsensor.timer1, lsensor.timeout_cb, 1, 1);
    timer_start(&lsensor.timer1);
    /* USER CODE END 2 */
    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
        /* USER CODE END WHILE */
        /* USER CODE BEGIN 3 */
        ReadBH1750(LUX_1_MODE);
        if(1 == lsensor.Conver_completed)
        {
            ++serial_number ;
            if(65535 == serial_number)
                serial_number = 0 ;
            sprintf(display_buf, "%d%d%d%dLux", lsensor.Lux / 1000 % 100, lsensor.Lux / 100 % 10, lsensor.Lux / 10 % 10, lsensor.Lux % 10);
            LCD_ShowString(80, 50 + 24 + 32, 240, 32, 32, display_buf); //显示字符串,字体大小32*32
            if(lsensor.Lux > LIGHT_SENSOR_THREHOLD)
            {
                HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
            }
            else
            {
                HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
            }
            sprintf(procol_buf, "%d%d%d%d%d %d%d%d%d%d",
                    serial_number / 10000,
                    serial_number / 1000 % 100 % 10,
                    serial_number / 100 % 10,
                    serial_number / 10 % 10,
                    serial_number % 10,
                    lsensor.Lux / 10000,
                    lsensor.Lux / 1000 % 100 % 10,
                    lsensor.Lux / 100 % 10,
                    lsensor.Lux / 10 % 10,
                    lsensor.Lux % 10
                   );
            printf("%s \r\n", procol_buf);
        }
        timer_loop();
    }
    /* USER CODE END 3 */
}

下载后,打开串口调试助手可以看到:

640.png

三、光强曲线显示上位机应用开发

下面我先用QT画出一个简单的界面(已经将QCustomPlot用上了),如下:

640.png

这里我们需要使用QT5的串口库,还有QCustomPlot库,所以在.pro中需要添加对应的库:

#-------------------------------------------------
#
# Project created by QtCreator 2020-04-13T20:46:41
#
#-------------------------------------------------
QT       += core gui serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
TARGET = BearPi_QT
TEMPLATE = app
RC_FILE += app.rc
# 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 \
        mainwindow.cpp \
    qcustomplot.cpp
HEADERS += \
        mainwindow.h \
    qcustomplot.h
FORMS += \
        mainwindow.ui

在mainwindow.h中,需要添加头文件及变量还有相关的普通函数和槽函数的定义:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QDebug>
#include <QMainWindow>
#include <QSerialPort>        //提供访问串口的功能
#include <QSerialPortInfo>    //提供系统中存在的串口的信息
#include "qcustomplot.h"      //包含Qcustomplot库
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    /*初始化串口参数*/
    void Init_Serial_Para();
    /*传感器数据画图前的处理*/
    void sensor_data_preprocess(int x, int y) ;
    /*画曲线函数*/
    void Sensor_Draw_Plot(QCustomPlot *customPlot, QVector<double> x, QVector<double> y);
private:
    Ui::MainWindow *ui;
    QSerialPort *Serial ;
    long last_index ;
    QVector<double> display_x;
    QVector<double> display_y;
    QString Serial_Port , Serial_Bauardate,Serial_PariteyBit,Serial_DataBit,Serial_StopBit ;
private slots:
    void Update_Serial_Port(QString Currnet_Select);
    void Update_Serial_Baurdrate(QString Currnet_Select);
    void Update_Serial_ParityBit(QString Currnet_Select);
    void Update_Serial_DataBit(QString Currnet_Select);
    void Update_Serial_StopBit(QString Currnet_Select);
    void on_Connect_Device_clicked();
    void on_Disconnect_Device_clicked();
    void cmd_recv_process();
};
#endif // MAINWINDOW_H

在mainwindow.cpp太长我就不全贴出来了,解读一下核心的实现思路:

1、用户配置完串口参数,然后 连接信号与槽:

connect(this->Serial,SIGNAL(readyRead()),this,SLOT(cmd_recv_process()));

2、当上位机接受到MCU端发来的数据时,会触发readyRead()信号,进而调用cmd_recv_process()槽函数,实现如下:

/*数据接收*/
void MainWindow::cmd_recv_process()
{
    QString data ;
    QStringList list    ;
    /*光强传感器序号*/
    QString Sensor_Serial_Number ;
    /*光强传感器光强值*/
    QString Sensor_light_Value ;
    long int s1 = 0, v1 = 0;
    last_index =0;
    if(Serial->canReadLine())
    {
        QByteArray temp = Serial->readAll();
        if(!temp.isEmpty())
        {
            data = temp ;
            list = data.split(" ");
            if(3 == list.length())
            {
                Sensor_Serial_Number = list[0];
                Sensor_light_Value   = list[1];
                /*取到对应参数后立刻开始画图*/
                s1 = Sensor_Serial_Number.toInt();
                v1 = Sensor_light_Value.toInt();
                ui->light_sensor_value->setText(QString::number(v1));
                if (last_index == 0  || (last_index < s1 &&  s1 - last_index >=1 && s1 - last_index <= 10 ))
                {
                    last_index = s1;
                    sensor_data_preprocess(s1,v1);
                }
            }
        }
    }
}

这里会判断是否满足读取一行数据的条件,如果满足则会读取一行数据,接下来对数据进行分割,取出传感器上报的序号、光强两个字段,序号作为曲线图的横坐标,光强作为曲线图的纵坐标进行显示。

例程下载

链接:https://pan.baidu.com/s/1ujo0TE3pS-1RFVvylnCyKQ
提取码:48jp
复制这段内容后打开百度网盘手机App,操作更方便哦

往期精彩

网红物联网开发板小熊派使用评测


超轻量级网红软件定时器multi_timer(51+stm32双平台实战)


基于小熊派光强传感器BH1750实践(multi_timer+状态机工程应用)


基于小熊派光强传感器BH1750状态机驱动项目升级(带LCD屏显示)

目录
相关文章
|
8月前
2023年电赛---运动目标控制与自动追踪系统(E题)OpenART mini的代码移植到OpenMV
2023年电赛---运动目标控制与自动追踪系统(E题)OpenART mini的代码移植到OpenMV
102 0
|
7月前
|
传感器 数据采集 物联网
基于小熊派光强传感器BH1750状态机驱动项目升级(带LCD屏显示)
基于小熊派光强传感器BH1750状态机驱动项目升级(带LCD屏显示)
63 0
|
7月前
|
传感器 移动开发 缓存
基于小熊派WIFI-ESP8266实践(中)-多功能处理显示等大杂烩
基于小熊派WIFI-ESP8266实践(中)-多功能处理显示等大杂烩
97 0
|
8月前
【单片机期中测试】11.交通灯
【单片机期中测试】11.交通灯
30 0
|
9月前
正点原子战舰开发板---串口调试(硬件调试的一点经验吧)
正点原子战舰开发板---串口调试(硬件调试的一点经验吧)
130 0
|
数据管理 数据库
便携式钻孔测斜仪软件运行状态
设备启动后,自动进入测斜仪程序主界面(若设置了程序自动启动),主界面见图 5.1。若未设置程序自动启动,则可通过双击系统桌面上的测量【APP】程序快捷方式,进入软件。
便携式钻孔测斜仪软件运行状态
|
算法
基于双闭环PID控制器的永磁同步电机控制系统仿真
基于双闭环PID控制器的永磁同步电机控制系统仿真
259 0
基于双闭环PID控制器的永磁同步电机控制系统仿真
|
异构计算
stm32f407探索者开发板(一)——资源介绍(顺便说下无人机的进度状况)
stm32f407探索者开发板(一)——资源介绍(顺便说下无人机的进度状况)
228 0
stm32f407探索者开发板(一)——资源介绍(顺便说下无人机的进度状况)
|
传感器 存储 编解码
红外热成像仪模块工作流程和操作
MLX90640 的工作流程 (1) 上电,内部初始化(约 40ms) (2) 读取工作参数到控制和状态寄存器 (3) 开始以 2Hz 的速率测量实时数据并更新到 RAM,自动更新状态寄存器。
红外热成像仪模块工作流程和操作
|
芯片
单片机:蜂鸣器发声和自动关闭一站式教程:(附赠如何控制声音大小和音调)软件编程+硬件原理+注意事项
单片机:蜂鸣器发声和自动关闭一站式教程:(附赠如何控制声音大小和音调)软件编程+硬件原理+注意事项
477 0
单片机:蜂鸣器发声和自动关闭一站式教程:(附赠如何控制声音大小和音调)软件编程+硬件原理+注意事项