Funpack2-3: 基于FreeRTOS和LVGL8.3的动态声音数据显示和IoT监测设计
基于FireBeetle ESP-E的声音传感器采集以及IOT网站动态显示。 主控单元:FireBeetle ESP32-E开发板 传感器:SKU_DFR0034_模拟声音传感器_V2 IOT网站:thingSpeak.com
标签
Funpack活动
Funpack2-3
ESP32-E
playlikework
更新2023-01-03
789

大家好,我这次非常开心能够参加本期有硬禾学堂和得捷电子联合举办的Fun pack活动,我对物联网开发经验较少,之前在网络上学习了一些ESP8266的基础知识,不过一直没有接触过ESP32,购物平台上ESP32质量参差不齐,这次刚好是DFROBOT的主控FIREBEETLE ESP32作为本期的主角,非常开心。下面就和大家来分享一下我的设计思路。

0、FireBeetle ESP32-E 简介

FireBeetle ESP32-E深度支持ArduinoIDE,还可以使用MicroPython、Mind+图形化等编程环境来操控板载硬件资源。DFRobot公司提供上千种免焊接的Gravity接口传感器与执行器

一、题目方向选择

本期活动的自由度非常大,主办方给了大家非常充足的时间,多样化的项目视角来让大家好好玩起来。我自己对LVGL和iot非常感兴趣,也不太清楚该从哪里入手。结合这次的Funpack活动,我给自己设定的目标是

1)能够初步使用LVGL来动态显示一个传感器的数据

2)能够把数据透过MQTT协议来上传到IoT网站,实现动态显示

综合起来看,比较贴近任务6.

任务六:开放性题目
用FireBeetle ESP32-E开发板,再任选一个及以上传感器 + 一个屏幕搭配完成任务,难度不低于以上题目难度。

二、LVGL方面设计

我选择了在Arduino中使用LVGL。目前网络上对这部分的介绍也比较多,我使用的版本在目前比较新的8.3版本,在使用LVGL之前,需要先把屏幕驱动库安装,调试好。

采用的屏幕是:SPI接口的240 X 320分辨率电阻触摸屏。

FqDIt6iDregq0stbNLmrPeizTNc5

这里用到的驱动是Arduino环境下提供的TFT_eSPI库,可以非常方便在库管理器中搜索“TFT_eSPI”这里安装的版本是2.4.72.

Fj73SBU8r8CbWz6LHhMOlMcpxBdv

安装好库文件后,要根据自己的屏幕去修改一些配置,比如:

FqiwvTRq3ylxeHPYI9bVrBEveIkk

之后安装LVGL,版本选择8.3.0

Fr8PO8VEOrOov5WiZ45mr1F3-hJ4

安装好后,需要进行一些配置参数的设定:

FryftAjUKbNLuXWOevYxERU1CoV4

这里屏幕用于动态显示采集的声音传感器数据,所以自然而然的想起用图表来展示数据,LVGL有个自带的小组件“Chart”,核心的代码如下。

主要思路是:1)先创建一个Chart,然后再创建几个“标签”来显示一些文字信息。

 /*Create a chart to show voice data*/
    Chart_VoiceSensor = lv_chart_create(lv_scr_act());

    //lv_obj_set_size(Chart_VoiceSensor, 100, 130);
    lv_obj_set_size(Chart_VoiceSensor, 180, 150);
    lv_obj_center(Chart_VoiceSensor);

    lv_chart_set_type(Chart_VoiceSensor, LV_CHART_TYPE_LINE);   /*Show lines and points too*/
    lv_chart_set_div_line_count(Chart_VoiceSensor, 3, 5);

    lv_chart_set_axis_tick(Chart_VoiceSensor, LV_CHART_AXIS_PRIMARY_Y, 6, 3, 9, 1, true, 30);
    lv_chart_set_axis_tick(Chart_VoiceSensor, LV_CHART_AXIS_PRIMARY_X, 6, 3, 5, 1, true, 10);

    lv_obj_add_event_cb(Chart_VoiceSensor, draw_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
    lv_chart_set_update_mode(Chart_VoiceSensor, LV_CHART_UPDATE_MODE_SHIFT);

    ser1 = lv_chart_add_series(Chart_VoiceSensor, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);

    uint32_t i;
    for (i = 0; i < 10; i++) {
        lv_chart_set_next_value(Chart_VoiceSensor, ser1, lv_rand(20, 90));
    }

    lv_timer_create(add_data, 100, NULL);  

    lv_obj_t * label = lv_label_create(lv_scr_act());
    lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 5);
    lv_label_set_recolor(label, true); 
    lv_label_set_text(label, "#0000ff FireBeetle# #ff00ff ESP32-E# & DFR0034");

    lv_obj_t * label2 = lv_label_create(lv_scr_act());
    lv_obj_align(label2, LV_ALIGN_LEFT_MID, 0, 0);
    lv_label_set_recolor(label2, true); 
    lv_label_set_text(label2, "#ff00ff 2048#"); 

    
    lv_obj_t * label1 = lv_label_create(lv_scr_act());
    lv_label_set_recolor(label1, true); 
    lv_obj_align_to(label1, Chart_VoiceSensor, LV_ALIGN_OUT_BOTTOM_LEFT, -60, -20);
    lv_label_set_text(label1, "#0000ff 0#"); 

    lv_obj_t * label3 = lv_label_create(lv_scr_act());
    lv_obj_align_to(label3, Chart_VoiceSensor, LV_ALIGN_OUT_TOP_LEFT, -70, 18);
    lv_label_set_recolor(label3, true); 
    lv_label_set_text(label3, "#ff0000 4095 #"); 

我这里采用的是FreeRTOS,然后把MQTT相关的工作放入了一个单独的Task中,这个Task是分配在Core1上运行的。然后LVGL相关的工作是分配在Core0上运行的。下面是创建两个Task,分别分配到Core1和Core0.

void setup{
...
// Now set up two tasks to run independently.
  xTaskCreatePinnedToCore(
    TaskMqtt
    ,  "TaskMqtt"   // A name just for humans
    ,  10240  // This stack size can be checked & adjusted by reading the Stack Highwater
    ,  NULL
    ,  1  // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,  NULL 
    ,  1);

  xTaskCreatePinnedToCore(
    TaskReadA0_GUI
    ,  "TaskReadA0_GUI"
    ,  10240  // Stack size
    ,  NULL
    ,  1  // Priority
    ,  NULL 
    ,  0);
...
}
void TaskReadA0_GUI(void *pvParameters)  // This is a task.
{
  (void) pvParameters;
  Serial.print("TaskReadA0_GUI 在核心 ");Serial.print(xPortGetCoreID());Serial.println(" 上运行");

  for (;;)
  {
    lv_timer_handler(); /* let the GUI do its work */
    delay(5);
  }
}

效果如下:

FjRwsBDyei_599Y4ARQhz0abQR4F

三、IOT方面设计

IoT网站方面,自己之前了解过thingSpeak.com这个物联网平台,可以使用MQTT来上传数据。

第一步:注册一个免费的MQTT服务器,这里我使用的是ThingSpeak.

LBd9hGJq9gAAAABJRU5ErkJggg==

然后新建一个Channel:

 

wPobPBfxFpYeQAAAABJRU5ErkJggg==

 

然后建立两个栏位,第一个LED主要是希望通过MQTT来控制Fire Beetle板载的LED;第二个栏位“VOICE_SENSOR”主要是用于接收声音传感器通过ESP32-MQTT上传来的数据。

Abncn2PKiuQ7AAAAAElFTkSuQmCC

然后点击Save:

tZq0ySn6d2AAAAAASUVORK5CYII=

EaAAAAAAAA70K8BgAAAAAAwLsQrwEAAAAAAPAuxGsAAAAAAAC8iaL8fz9hRHcrafn6AAAAAElFTkSuQmCC

在API KEYS,比较重要的是Write API KEy和 Read API Keys,分别对应向MQTT服务器写入数据以及从MQTT服务器读取数据时候用到。比如下面的ThingSpeak()API在调用的时候,需要填写你自己的writeAPIKey,否则上传数据失败的。我这里采用的是FreeRTOS,然后把MQTT相关的工作放入了一个单独的Task中,这个Task是分配在Core1上运行的。然后LVGL相关的工作是分配在Core0上运行的。

Ft3_ZdlWiKhlI6XkI0pCm-WEQtAw

void TaskMqtt(void *pvParameters)  // This is a task.
{
  (void) pvParameters;
  Serial.print("TaskMqtt 在核心 ");Serial.print(xPortGetCoreID());Serial.println(" 上运行");
      // Connect or reconnect to WiFi

      // Connect or reconnect to WiFi
      if(WiFi.status() != WL_CONNECTED){
        Serial.print("Attempting to connect to SSID: ");
        Serial.println(SECRET_SSID);
        while(WiFi.status() != WL_CONNECTED){
          WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. Change this line if using open or WEP network
          Serial.print(".");
          delay(5000);    
        } 
        Serial.println("\nConnected.");
      }      

  for (;;) // A Task shall never return or exit.
  {     
      // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different
      // pieces of information in a channel.  Here, we write to field 1.
      tempValtoIOT = tempVal;
      int x = ThingSpeak.writeField(myChannelNumber, 1, tempValtoIOT, myWriteAPIKey);
      if(x == 200){
        Serial.print("------------Channel update successful----Value: ");
        Serial.print(tempValtoIOT);
        Serial.println(" -------------------.");
      }
      else{
        Serial.println("Problem updating channel. HTTP error code " + String(x));
      }
      delay(20000); // Wait 20 seconds to update the channel again
  }

}

一些遇到的栈溢出错误:这个是由于LVGL和WIFI相关的库运行需要比较大的RAM,我使用的默认的值比较小,从1024字节改为10240字节后,程序运行正常。

Pw7DiQi79qWTAAAAAElFTkSuQmCC

四、结果展示

请大家跟我一起看一下我的项目展示。其中左侧的4095,2048,0分别是纵坐标对应的ADC采样值,纵坐标0-100是一个百分比,比如100,对应的ADC采样值是4095。这款声音传感器在没有声音输入的情况下,ADC值是0。

lmCzyXfbhIHJ51-qqdk6D_7Vw4hg

下面是上传到IoT网站:

FmDS8NhksVIcQnpd8m-EvcwTP5VS

总结:

衷心的感谢硬禾学堂和得捷电子联合举办的这次Firebeetle ESP32-E活动,让我能够静下心来学习如何使用ESP32开发板来搭建一个简单的声音数据采集,屏幕展示,上传到IoT网站整个过程。希望这个活动可以越办越好!

 

附件下载
Hello_MQTT_WriteSingleField_Z_FreeRTOS_Ver0.3.zip
项目的Arduino代码,相关的库可以从Arduino下载,没有包含在zip文件中
团队介绍
ee爱好者!
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号