功能

  1. mq2 模块测试
  2. esp32s3 获取 mq2 模块数据,并且使用 LVGL显示。

代码

使用最基础的 digitalRead() 以及 analogRead() 就可以读取数据。

变量定义

1
2
3
4
5
6
7
#define smokePin 5
#define analogPin 12
typedef struct _lv_mq2
{
lv_obj_t *digitalNum; // 时间标签
lv_obj_t *analogNum; // 日期标签
} lv_mq2_t;

UI设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
void demo12()
{
static lv_style_t date_time_clock_style; // 最外层对象的样式
lv_style_reset(&date_time_clock_style); // 重置样式
lv_style_init(&date_time_clock_style); // 初始化样式
lv_style_set_radius(&date_time_clock_style, 5); // 设置样式圆角
lv_style_set_bg_opa(&date_time_clock_style, LV_OPA_20); // 设置样式背景透明度
lv_style_set_border_width(&date_time_clock_style, 0); // 设置样式边框宽度
lv_style_set_bg_color(&date_time_clock_style, lv_color_white()); // 设置样式背景颜色,白色
lv_style_set_pad_left(&date_time_clock_style, 1); // 设置样式左边padding填充宽度
lv_style_set_pad_right(&date_time_clock_style, 1); // 设置样式右边padding填充宽度
lv_style_set_pad_top(&date_time_clock_style, 0); // 设置样式顶部padding填充宽度
lv_style_set_pad_bottom(&date_time_clock_style, 0); // 设置样式底部padding填充宽度

static lv_style_t time_style; // 时间对象样式
lv_style_reset(&time_style);
lv_style_init(&time_style);
lv_style_set_bg_opa(&time_style, LV_OPA_COVER);
lv_style_set_border_width(&time_style, 0);
lv_style_set_radius(&time_style, 5);
lv_style_set_bg_color(&time_style, lv_palette_main(LV_PALETTE_BLUE));
lv_style_set_pad_left(&time_style, 0);
lv_style_set_pad_right(&time_style, 0);
lv_style_set_pad_top(&time_style, 0);
lv_style_set_pad_bottom(&time_style, 0);

static lv_style_t time_label_style; // 时间标签样式
lv_style_reset(&time_label_style); // 重置样式
lv_style_init(&time_label_style); // 初始化样式
lv_style_set_text_color(&time_label_style, lv_color_white()); // 设置标签样式文本颜色
lv_style_set_text_font(&time_label_style, &lv_font_montserrat_32); // 设置字体风格
lv_style_set_text_opa(&time_label_style, LV_OPA_COVER); // 设置字体透明度
lv_style_set_bg_opa(&time_label_style, LV_OPA_0); // 设置样式背景透明度

lv_obj_t *src = lv_obj_create(lv_scr_act()); // 基于屏幕创建时间日期对象
lv_obj_set_size(src, 320, 150);
lv_obj_center(src);
lv_obj_add_style(src, &time_style, LV_STATE_DEFAULT);

static lv_obj_t *lv_mq2_label = lv_label_create(src);
lv_obj_add_style(lv_mq2_label, &time_label_style, LV_STATE_DEFAULT); // 给date_obj对象添加样式

lv_obj_align_to(lv_mq2_label, lv_obj_get_parent(lv_mq2_label), LV_ALIGN_CENTER, 0, 0);

lv_timer_t *task_timer = lv_timer_create(demo12_my_timer, 2000, (void *)&lv_mq2_label);
}

定时更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void demo12_my_timer(lv_timer_t *timer)
{
int mq2Value = digitalRead(smokePin);
int anaValue = analogRead(analogPin);
Serial.println("D0");
Serial.println(mq2Value);
Serial.println("ANA");
Serial.println(anaValue);

if (timer != NULL && timer->user_data != NULL)
{

lv_obj_t *mq2_label = (lv_obj_t *)(timer->user_data);
if (mq2_label != NULL)
{
lv_label_set_text_fmt(mq2_label, "digitalRead: %01d", mq2Value);
lv_obj_align_to(mq2_label, lv_obj_get_parent(mq2_label), LV_ALIGN_CENTER, 0, 0);
}
}
}

修bug

1.主控不断重启

设计 UI 时发现屏幕闪烁,查看串口输出发现是触发看门狗不断重启。

此种错误基本上都是指针使用错误

以下为错误示例❌❌❌,lv_mq2_label 已经是一个 obj 基本对象的指针,传递时不需要再取地址。

1
2
static lv_obj_t *lv_mq2_label = lv_label_create(src);
lv_timer_t *task_timer = lv_timer_create(demo12_my_timer, 2000, &lv_mq2_label);

去掉取地址即可正确运行。

1
2
static lv_obj_t *lv_mq2_label = lv_label_create(src);
lv_timer_t *task_timer = lv_timer_create(demo12_my_timer, 2000, lv_mq2_label);

对比

此处取地址是因为 lv_dht11 在定义的时候就是一个结构体,为了方便定时器修改数据,避免占用过多内存,因此传递用户数据时应该传递指针 (void *)&lv_dht11 。

1
2
static lv_dht11_t lv_dht11 = {0};
lv_timer_t *task_timer = lv_timer_create(demo11_my_timer, 2000, (void *)&lv_dht11);

最终效果

image-20230531005443438

image-20230531005453640