本项目使用FireBeetle ESP32-E板卡作为主控单元,HYLD9767 声音传感器用来采集声音的数值,OLED 屏幕作为人机对话单元,通过移植lvgl库来动态显示采集到的声音数值,完成了本次指定任务的任务二,下面是一些详细介绍。
一、FireBeetle ESP32-E板卡的硬件资源介绍
FireBeetle ESP32-E是一款使用ESP-WROOM-32E双核芯片的主控板,专门进行IoT相关设计。
FireBeetle ESP32-E支持WIFI和蓝牙双模通信、有一个GDI显示接口,单线连接显示屏,和板载充电电路以及PH2.0锂电池接口、体积小巧、超低功耗、板载充电电路、接口易用等。深度支持ArduinoIDE编程,并且即将支持Scratch图形化编程及MicroPython编程。
- 输入电压:3.3V~5V
- 支持低功耗:10uA
- 处理器:Tensilica LX6双核处理器(一核处理高速连接;一核独立应用开发)
- 主频:240MHz
- SRAM:520KB
- Flash:4MB
- 支持Arduino一键下载
二、完成任务二思路
(1)连接实物电路
与板卡连接的一共是两个外设,一个是HYLD9767 声音传感器,另一个是128*64的OLED屏幕。
FireBeetle ESP32-E | HYLD9767 声音 传感器 |
36 | 模拟信号输出口(蓝线) |
FireBeetle ESP32-E | 128*64OLED屏幕 |
21 | SDA |
22 | SCL |
其中的外设模块的VCC与使用板载的3.3V、VCC连接,GND与GND连接。
(2)程序设计
1.先从官网上下载lvgl的库,https://github.com/lvgl/lvgl。
2.在VScode中先配置好PlatformIO的编译环境。
3.在PIO Home中新建工程,名字需要英文,板卡选择“DOIT ESP32 DEVKIT V1",架构选择“Arduino”就可以了。
4.更改lvgl的配置,将“.../lvgl/lvgl”中的“lv_conf_template.h“文件拷贝到”.../lvgl“中,并且更改名字为”lv_conf_.h“,将lvgl整个文件夹复制到新建工程的”lib“中,配置对应的路径。
5.在“PIO Home”中下载“Adafruit_SSD1306”库,并添加到新建的工程中。
6.进行显示接口配置,初始化lv_disp_buf_t和lv_disp_drv_t变量,选择两个缓冲区的显示缓冲区函数配置,显示驱动器需要注意刷图函数的配置。
static void lvgl_init(void)
{
/* Initialize the lvgl */
lv_init();
lv_disp_draw_buf_init(&disp_buf, buf1, buf2, DISP_BUF_SIZE);
static lv_disp_drv_t disp_drv; /*A variable to hold the drivers. Must be static or global.*/
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
disp_drv.draw_buf = &disp_buf; /*Set an initialized buffer*/
disp_drv.flush_cb = my_flush_cb; /*Set a flush callback to draw to the display*/
disp_drv.hor_res = LV_HOR_MAX; /*Set the horizontal resolution in pixels*/
disp_drv.ver_res = LV_VER_MAX; /*Set the vertical resolution in pixels*/
/* Initialize the display */
lv_disp_drv_register(&disp_drv);
/*Initialize the (dummy) input device driver*/
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
// indev_drv.read_cb = my_touchpad_read;
lv_indev_drv_register(&indev_drv);
}
void my_flush_cb(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);
/*刷新显示区每个点的像素值*/
for (uint16_t y = area->y1; y <= area->y2; y++){
for (uint16_t x = area->x1; x <= area->x2; x++){
if(color_p->full != 0)display.getPixel(x, y);//由于我是用的OLED只有黑白,所以配置的2种颜色,当颜色值为1时设置该像素点
else display.getPixel(x, y);//由于我是用的OLED只有黑白,所以配置的2种颜色,当颜色值为0时设置清除像素点
color_p++;
}
}
display.display();//刷新OLED显示
lv_disp_flush_ready(disp);/* Indicate you are ready with the flushing 最后必须得调用,通知 lvgl 库你已经 flushing 拷贝完成了*/
}
7.lvgl跑起来之后,就是对36,A0口的一个数字采集,在DFROBOT DFR0034Gravity: 模拟声音传感器(Arduino兼容)产品资料库,使用教程中可以很清晰的看到如何使用。
8.进行一些界面的优化。
三、代码分析
因为这次使用的是老的OLED单色屏,且没有触摸功能,所以功能显示会比较粗糙简单,难点在于搭建lvgl的环境。
#include <Wire.h>
// 引入驱动OLED0.96所需的库
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//引入lvgl的库
#include "lvgl/lvgl.h"
#include "lvgl/examples/lv_examples.h"
#include "lvgl/demos/lv_demos.h"
在main.c中,首先对使用的一些库进行引用。
void Draw_Init_Interface(void) {
for (size_t i = 0; i < 46; i = i + 5)
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(25, 20);
display.println("Initialize...");
display.drawRect(38, 38, 51, 6, WHITE);
display.drawLine(40, 40, 40 + i, 40, WHITE);
display.drawLine(40, 41, 40 + i, 41, WHITE);
display.display();
delay(1000);
display.clearDisplay();
}
display.display();
}
绘制的首页就,进度条,自己定义延时时间。
void words_display() {
Serial.begin(115200);
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1.5);
display.setCursor(0, 0);
display.print("FunPack 2-3");
display.setCursor(0, 16);
display.print("time: ");
display.print(millis() / 1000);
display.print(" s");
display.setCursor(0, 32);
display.print("Author: ");
display.print("Yangwu");
int val;
display.setCursor(0, 48);
display.print("Voice: ");
val=analogRead(36);
display.print(val,DEC);
Serial.println(val,DEC);
}
第二界面的一个显示操作。
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
//设置LED_BUILTIN数字引脚初始状态为输出
lvgl_init();
//lvgl初始化
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
// 初始化OLED并设置其IIC地址为 0x3C
Draw_Init_Interface();
display.display();
}
这是setup函数的一个总的调用。
void loop()
{
words_display();
display.display();
delay(600);
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(60); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(60);
}
这是循环函数loop的定义,里面加了一个LED灯的闪烁。
前面已经说过了刷图lvgl的初始化定义,不再赘述。
四、任务完成情况
任务二的要求:用FireBeetle-E开发板作为控制单元,搭配显示屏移植lvgl图形库,动态显示任意一个及以上传感器采集到的数据,或者使用触摸屏对执行器进行控制。
硬件资源使用:FireBeetle ESP32-E板卡,HYLD9767 声音传感器,和128*64OLED屏幕。
实际演示:
顺序为:初始化界面,无声音,有声音。
五、一些项目后的感悟
不知不觉,已经参加了很多期硬禾举办的活动了,每一次都有很大的收获。本次对驱动一些硬件更了解了,在整个移植lvgl当中,个人能力有限,做的不是很好,尤其是在选择屏幕时,没有选择tft的触摸屏幕,而且是彩屏,这更适用于lvgl这个图形库的完成,效果也会更好。了解一些底层逻辑对嵌入式专业帮助很大,下面一步打算把自己手头上的stm32精英版跑起来,网上的资料也非常的充足,不让板子继续吃灰了。最后,希望自己一直坚持这份热爱,同时希望硬禾学堂越做越好,越来越强。
源码下载:
链接:https://pan.baidu.com/s/19oPcm88NQuiPupkaUeV2Mw
提取码:6789