Funpack2-3活动ESP32-E采用LVGL显示温湿度及环境声音音量值
Funpack2-3活动ESP32-E采用LVGL显示温湿度及环境声音音量值
标签
Funpack活动
lvgl
温湿度
ESP32-E
声音传感器
Snapdragon
更新2023-01-06
1179

一、项目要求及简介

    1、项目要求

        本次活动我选择的是:任务二:lvgl图形库和应用。

         官方要求:
         用FireBeetle-E开发板作为控制单元,搭配显示屏移植lvgl图形库,动态显示任意一个及以上传感器采集到的数据,或者使用触摸屏对执行器进行控制。

    2、使用的模块

        ①主控:DFRobot的FireBeetle ESP32-E IOT开发板

FtMuOMwNI7AKiIggc3nugvdNWZ26

        ②声音传感器:DFRobot的Analog Sound Sensor

FtKT6XymEbCAgrBw3rI5SyrFA54_

        ③ 温湿度传感器模块 DHT11

FoLDtAnlvZj3waFvxLEyVu-5hPY4

        ④ 显示模块:ST7789v2 240*240 IPS液晶屏

Fm6FyJ2lhcy_ijbtqpVLst5wXTyi

     3、具体完成的项目

        通过lvgl在LCD上面分成四块区域,分别显示标题、环境声音强度、环境温度、环境湿度;其中除标题外,其余部分背景色分别是蓝、绿、红。下图为ui展示,具体的详见第五部分(实物展示)。

Ft9S-GXXzm-CR5nV9NAoZDPm23JH

二、开发环境搭建

    1、Arduino开发环境

         去官网https://www.arduino.cc/en/software下载Arduino2.0.3,这个开发环境相较于        Arduino1.x来说,增加了代码提示和跳转功能,开发起来更加的方便。

      2、DFRobot官方资料

            官方中文Wiki地址https://wiki.dfrobot.com.cn,大部分资料可以通过左侧的索引找到。但根据个人经验,FireBettle ESP32-E IOT开发板需要手动搜索货号:DFR0654才能找到。下面附加用到的资料链接。

    开发板资料:https://wiki.dfrobot.com.cn/_SKU_DFR0654_FireBeetle_Board_ESP32_E

    声音传感器资料:https://wiki.dfrobot.com.cn/_SKU_DFR0034_%E6%A8%A1%E6%8B%9F%E5%A3%B0%E9%9F%B3%E4%BC%A0%E6%84%9F%E5%99%A8_V2

    DHT11温湿度传感器资料:https://wiki.dfrobot.com.cn/_SKU_DFR0067_DHT11%E6%95%B0%E5%AD%97%E6%B8%A9%E6%B9%BF%E5%BA%A6%E4%BC%A0%E6%84%9F%E5%99%A8V2

    ST7789 240*240分辨率LCD资料:https://wiki.dfrobot.com.cn/1.54_240x240_IPS_LCD_SKU_DFR0649

      3、TFT-eSPI资料

          本次活动采用的LCD是ST7789v2控制器,用官方资料无法正常驱动,所以采用第三方的TFT-eSPI驱动库。链接地址:https://github.com/Bodmer/TFT_eSPI

      3、LVGL资料

         lvgl源码:https://github.com/lvgl/lvgl/tree/release/v8.2

          lvgl Arduino移植教程:https://docs.lvgl.io/master/get-started/platforms/arduino.html

          lvgl Arduino简易Demo:https://github.com/lvgl/lvgl/blob/master/examples/arduino/LVGL_Arduino/LVGL_Arduino.ino

三、外设驱动及LVGL移植

    1、添加驱动到libraries文件夹下

          根据Arduino的安装位置(比如默认安装目录下,库目录为:C:\Users\xxx\AppData\Local\Arduino15\packages\DFRobot\hardware\esp32\0.2.1\libraries)将前面下载的zip驱动包解压至此根目录即可。注:LVGL要将lv_conf.h单独复制到此目录下。

      2、修改驱动

          首先根据LCD的信息修改TFT-eSPI的User_Setup.h文件,如下:

// Only define one driver, the other ones must be commented out
//#define ILI9341_DRIVER       // Generic driver for common displays
//#define ILI9341_2_DRIVER     // Alternative ILI9341 driver, see https://github.com/Bodmer/TFT_eSPI/issues/1172
//#define ST7735_DRIVER      // Define additional parameters below for this display
//#define ILI9163_DRIVER     // Define additional parameters below for this display
//#define S6D02A1_DRIVER
//#define RPI_ILI9486_DRIVER // 20MHz maximum SPI
//#define HX8357D_DRIVER
//#define ILI9481_DRIVER
//#define ILI9486_DRIVER
//#define ILI9488_DRIVER     // WARNING: Do not connect ILI9488 display SDO to MISO if other devices share the SPI bus (TFT SDO does NOT tristate when CS is high)
//#define ST7789_DRIVER      // Full configuration option, define additional parameters below for this display
#define ST7789_2_DRIVER    // Minimal configuration option, define additional parameters below for this display
//#define R61581_DRIVER
//#define RM68140_DRIVER
//#define ST7796_DRIVER
//#define SSD1351_DRIVER
//#define SSD1963_480_DRIVER
//#define SSD1963_800_DRIVER
//#define SSD1963_800ALT_DRIVER
//#define ILI9225_DRIVER
//#define GC9A01_DRIVER


// For ST7789, ST7735, ILI9163 and GC9A01 ONLY, define the pixel width and height in portrait orientation
// #define TFT_WIDTH  80
// #define TFT_WIDTH  128
// #define TFT_WIDTH  172 // ST7789 172 x 320
#define TFT_WIDTH  240 // ST7789 240 x 240 and 240 x 320
// #define TFT_HEIGHT 160
// #define TFT_HEIGHT 128
#define TFT_HEIGHT 240 // ST7789 240 x 240
// #define TFT_HEIGHT 320 // ST7789 240 x 320
// #define TFT_HEIGHT 240 // GC9A01 240 x 240


// For NodeMCU - use pin numbers in the form PIN_Dx where Dx is the NodeMCU pin designation
// #define TFT_CS   PIN_D8  // Chip select control pin D8
// #define TFT_DC   PIN_D3  // Data Command control pin
// #define TFT_RST  PIN_D4  // Reset pin (could connect to NodeMCU RST, see next line)
#define TFT_MISO 19
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_CS   27
#define TFT_DC   25
#define TFT_RST  26

 

      根据官方教程修改lv_conf.h文件

/* clang-format off */
#if 1 /*Set it to "1" to enable content*/

#ifndef LV_CONF_H
#define LV_CONF_H

#include <stdint.h>

/*====================
   COLOR SETTINGS
 *====================*/

/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
#define LV_COLOR_DEPTH 16

/*Swap the 2 bytes of RGB565 color. Useful if the display has an 8-bit interface (e.g. SPI)*/
#define LV_COLOR_16_SWAP 1

 

需要使能文件,修改颜色深度为16,并使能字节交换(SPI是8位传输,颜色数据是16位)

 

四、业务代码

    1、添加lvgl底层显示函数

static const uint16_t screenWidth = 240;
static const uint16_t screenHeight = 240;

static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[screenWidth * 10];

TFT_eSPI tft = TFT_eSPI(screenWidth, screenHeight);  // Create object "tft"
dht11 dht;

void my_disp_flush(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p)
{
  uint32_t w = (area->x2 - area->x1 + 1);
  uint32_t h = (area->y2 - area->y1 + 1);

  tft.startWrite();
  tft.setAddrWindow(area->x1, area->y1, w, h);
  tft.pushColors((uint16_t*)&color_p->full, w * h, false);
  tft.endWrite();

  lv_disp_flush_ready(disp);
}

此函数是lvgl需要底层显示的时候回调的

    2、初始化屏幕、lvgl等

  Serial.begin(115200);
  lv_init();
  tft.init();
  tft.setRotation(3);

  pinMode(15, ANALOG);

  lv_disp_draw_buf_init( &draw_buf, buf, NULL, screenWidth * 10 );
  
  static lv_disp_drv_t disp_drv;
  lv_disp_drv_init( &disp_drv );
  disp_drv.hor_res = screenWidth;
  disp_drv.ver_res = screenHeight;
  disp_drv.flush_cb = my_disp_flush;
  disp_drv.draw_buf = &draw_buf;
  lv_disp_drv_register( &disp_drv );

    3、lvgl设置区域,分别显示标题、声音大小、温度和湿度,每块区域都有不同的背景色。

  title = lv_obj_create(lv_scr_act());
  lv_obj_set_style_bg_color(title, lv_color_hex(0xFFFFFF), LV_STATE_DEFAULT);
  lv_obj_set_size(title, 240, 20);
  title_label = lv_label_create(title);
  static String title_str = "Funpack2.3";
  lv_label_set_text( title_label, title_str.c_str() );
  lv_obj_align( title_label, LV_ALIGN_CENTER, 0, 0 );

 /*声音传感器*/
  sound = lv_obj_create(lv_scr_act());
  lv_obj_set_style_bg_color(sound, lv_color_hex(0xFF0000), LV_STATE_DEFAULT);
  lv_obj_set_size(sound, 240, 60);
  lv_obj_set_pos(sound, 0, 40);
  sound_label = lv_label_create(sound);
  lv_label_set_text( sound_label, sound_str.c_str() );
  lv_obj_align( sound_label, LV_ALIGN_CENTER, 0, 0 );

/*温度*/
  temp = lv_obj_create(lv_scr_act());
  lv_obj_set_style_bg_color(temp, lv_color_hex(0x00FF00), LV_STATE_DEFAULT);
  lv_obj_set_size(temp, 240, 60);
  lv_obj_set_pos(temp, 0, 110);
  temp_label = lv_label_create(temp);
  lv_label_set_text( temp_label, temp_str.c_str() );
  lv_obj_align( temp_label, LV_ALIGN_CENTER, 0, 0 );

/*湿度*/
  humi = lv_obj_create(lv_scr_act());
  lv_obj_set_style_bg_color(humi, lv_color_hex(0x0000FF), LV_STATE_DEFAULT);
  lv_obj_set_size(humi, 240, 60);
  lv_obj_set_pos(humi, 0, 180);
  humi_label = lv_label_create(humi);
  lv_label_set_text( humi_label, humi_str.c_str() );
  lv_obj_align( humi_label, LV_ALIGN_CENTER, 0, 0 );

 

4、主循环中每隔5毫秒调用一次lvgl处理函数,每隔1000ms读取一次传感器的值(声音传感器及DHT11为慢速设备,读取过快会造成读取错误或者数值不准确)并更新lvgl显示。

volatile uint32_t tickms = 0;
void loop()
{
  while (1)
  {
    lv_timer_handler();
    delay(5);
    tickms += 5;

    if (tickms % 1000 == 0)
    {
      int val = analogRead(15);
      Serial.println(val, DEC);
      sound_str = "sound: ";
      sound_str += val;
      lv_label_set_text( sound_label, sound_str.c_str() );

      int status = dht.read(2);
      if (status == DHTLIB_OK) {
        temp_str = "temp: ";
        temp_str += dht.temperature;
        lv_label_set_text( temp_label, temp_str.c_str() );

        humi_str = "humi: ";
        humi_str += dht.humidity;
        lv_label_set_text( humi_label, humi_str.c_str() );
      } else {
        Serial.println("dht error");
      }
    }
  }
}

五、实物演示

1、正常状态

FoHPPsFxXki79EALem2iKCJpQXit

       如上图所示,此为上电2分钟后的稳定状态,此时环境声音强度为0,温度为29.5度,湿度为29%。符合冬天有暖气的室内温度和相对干燥的环境湿度。

2、有外部噪音

FknJ_5lMUhtNT6ZeERRw3SAcObHJ

        如上图所示,这是存在外部噪音的显示状况,此时环境声音强度由0变为了834。环境温湿度不受影响。

3、手动影响温湿度传感器测试

Fom-fpcxIXJXojIO6SBoCkJEhUg4        如上图所示,这是用手手动干预温湿度传感器后的结果。此时温度上升到30.8℃,湿度变化更明显,上升到95%。而环境声音强度未受影响。

六、心得体会

     这次活动深刻感受到了esp32的arduino环境下的开发速度与便捷。也对dfrobot的各种模块好评,开发简单,资料齐全。

附件下载
Funpack2-3.zip
源代码
团队介绍
团队成员
Snapdragon
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号