项目概述和主要工作内容,以下是对项目的详细分析:
针对您提出的项目,以下是对软件规划部分的详细阐述,包括LVGL用户交互界面的实现等关键内容:
一、硬件连接示意图:
二、软件架构概述
软件部分将基于ESP32-S3和rp2040双核心进行开发,其中ESP32-S3作为主核心负责LVGL用户交互界面的运行和显示,而rp2040作为副核心则负责温湿度数据的采集、处理以及与主核心的通信。
界面设计:
利用LVGL(Light and Versatile Graphics Library)库,设计直观、易用的用户交互界面,界面应包含温湿度数据显示区域、数据刷新按钮。
数据更新与显示:
编写程序,使ESP32-S3主核心能够实时接收来自rp2040副核心的温湿度数据。
利用LVGL库中的图表或标签等控件,将接收到的数据动态显示在界面上。
实现数据刷新功能,用户点击刷新按钮时,界面将更新显示最新的温湿度数据。
LVGL用户交互界面实现:
static lv_disp_t *display_init(ESP_PanelLcd *lcd)
{
ESP_PANEL_CHECK_FALSE_RET(lcd != nullptr, nullptr, "Invalid LCD device");
ESP_PANEL_CHECK_FALSE_RET(lcd->getHandle() != nullptr, nullptr, "LCD device is not initialized");
static lv_disp_draw_buf_t disp_buf;
static lv_disp_drv_t disp_drv;
// Alloc draw buffers used by LVGL
void *buf[LVGL_PORT_BUFFER_NUM_MAX] = { nullptr };
int buffer_size = 0;
ESP_LOGD(TAG, "Malloc memory for LVGL buffer");
#if !LVGL_PORT_AVOID_TEAR
// Avoid tearing function is disabled
buffer_size = LVGL_PORT_BUFFER_SIZE;
for (int i = 0; (i < LVGL_PORT_BUFFER_NUM) && (i < LVGL_PORT_BUFFER_NUM_MAX); i++) {
buf[i] = heap_caps_malloc(buffer_size * sizeof(lv_color_t), LVGL_PORT_BUFFER_MALLOC_CAPS);
assert(buf[i]);
ESP_LOGD(TAG, "Buffer[%d] address: %p, size: %d", i, buf[i], buffer_size * sizeof(lv_color_t));
}
三、温湿度数据采集与处理
传感器初始化与配置:
在rp2040副核心上编写代码,初始化BME280传感器,并配置其采集模式和采样率等参数。
数据采集与传输:
编写数据采集循环,使rp2040能够定期从BME280传感器读取温湿度数据。
实现数据通信协议,将采集到的数据通过UART、SPI等通信接口发送给ESP32-S3主核心。
Serial.begin(115200);
while(!Serial); // time to get serial running
Serial.println(F("BME280 test"));
unsigned status;
status = bme.begin();
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n");
Serial.print(" ID of 0x60 represents a BME 280.\n");
Serial.print(" ID of 0x61 represents a BME 680.\n");
while (1) delay(10);
if (isnan(temperature) || isnan(humidity)) {
// 如果读取失败,则通过串口输出错误信息
Serial.println("Failed to read from BME280 sensor!");
} else {
// 如果温度和湿度数据读取成功,则执行以下操作
// 创建一个静态JSON文档对象,分配200字节的内存空间
// 用于存储JSON格式的数据
StaticJsonDocument<200> doc;
// 向JSON文档中添加温度数据
doc["temperature"] = temperature;
// 向JSON文档中添加湿度数据
doc["humidity"] = humidity;
// 假设pressure和altitude变量已经通过某种方式获取(例如从BME280传感器)
// 向JSON文档中添加气压数据
doc["pressure"] = pressure;
// 向JSON文档中添加海拔数据(注意:BME280传感器本身不提供海拔数据,
// 这里可能是通过其他方式计算或获取的)
doc["altitude"] = altitude;
// 创建一个字符串对象,用于存储序列化后的JSON数据
String jsonString;
// 使用serializeJson函数将JSON文档序列化为字符串
// 并存储在jsonString变量中
serializeJson(doc, jsonString);
// 通过串口输出序列化后的JSON字符串(通常用于调试)
Serial.println(jsonString);
// 通过Serial1串口输出序列化后的JSON字符串
// 这可能用于将数据发送到其他设备或系统
Serial1.println(jsonString);
}
实际输出 结果:
显示地理位置代码:
String cityCode = "66666&"; // 查看你的 城市代码
String userKey = "66666666666"; // 要去注册一个高德地图的开发用户
文字代码:
/* 佛 */
20,20,18,0,3,0, //dsc : unicode = 0x4f5b
0x00,0x00,0x00,0x00,0xcc,0x7f,0x00,0x00,0x00,0xb8,0xb8,0x00,0x00,0xdc,0x87,0x00,0x00,0x00,0x00,0x00, //....@*...%%..@%.....
0x00,0x00,0x00,0x33,0xff,0x5d,0x00,0x00,0x00,0xb8,0xb8,0x00,0x00,0xe4,0x8c,0x00,0x00,0x00,0x00,0x00, //...+@*...%%..@%.....
0x00,0x00,0x00,0x8f,0xf2,0x53,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x48,0x00, //...%@*@@@@@@@@@@@@*.
0x00,0x00,0x0c,0xf0,0x91,0x17,0x54,0x54,0x54,0xcf,0xcf,0x54,0x54,0xed,0xb2,0x54,0x6e,0xff,0x48,0x00, //..+@%+***@@**@%**@*.
0x00,0x00,0x6e,0xff,0x28,0x00,0x00,0x00,0x00,0xb8,0xb8,0x00,0x00,0xe4,0x8c,0x00,0x28,0xff,0x48,0x00, //..*@+....%%..@%.+@*.
0x00,0x0c,0xe8,0xff,0x10,0x00,0x00,0x00,0x00,0xb8,0xb8,0x00,0x00,0xe4,0x8c,0x00,0x28,0xff,0x48,0x00, //.+@@+....%%..@%.+@*.
0x00,0x82,0xff,0xff,0x10,0x21,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x48,0x00, //.%@@++@@@@@@@@@@@@*.
0x2e,0xfa,0xd5,0xff,0x10,0x44,0xff,0x79,0x54,0xd4,0xcd,0x54,0x54,0xed,0xb2,0x54,0x6e,0xff,0x48,0x00, //+@@@+*@**@@**@%**@*.
0xa1,0xd5,0x5b,0xff,0x10,0x67,0xff,0x1c,0x00,0xc6,0xab,0x00,0x00,0xe4,0x8c,0x00,0x00,0x00,0x00,0x00, //%@*@+*@+.@%..@%.....
0x50,0x35,0x54,0xff,0x10,0x8a,0xf9,0x02,0x00,0xd9,0x9a,0x00,0x00,0xe4,0x8c,0x00,0x00,0x00,0x00,0x00, //*+*@+%@+.@%..@%.....
0x00,0x00,0x54,0xff,0x10,0x9c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2a, //..*@+%@@@@@@@@@@@@@+
0x00,0x00,0x54,0xff,0x10,0x33,0x54,0x54,0x6f,0xff,0x8c,0x54,0x54,0xed,0xb2,0x54,0x54,0x96,0xff,0x20, //..*@++***@%**@%**%@+
0x00,0x00,0x54,0xff,0x10,0x00,0x00,0x00,0x5e,0xff,0x24,0x00,0x00,0xe4,0x8c,0x00,0x00,0x6e,0xff,0x12, //..*@+...*@+..@%..*@+
0x00,0x00,0x54,0xff,0x10,0x00,0x00,0x00,0xc5,0xda,0x00,0x00,0x00,0xe4,0x8c,0x0f,0x07,0xae,0xf5,0x02, //..*@+...@@...@%++%@+
0x00,0x00,0x54,0xff,0x10,0x00,0x00,0x54,0xff,0x67,0x00,0x00,0x00,0xe4,0x8c,0xdf,0xff,0xff,0xa3,0x00, //..*@+..*@*...@%@@@%.
0x00,0x00,0x54,0xff,0x10,0x00,0x28,0xf1,0xc9,0x05,0x00,0x00,0x00,0xe4,0x8c,0x51,0x73,0x57,0x05,0x00, //..*@+.+@@+...@%***+.
0x00,0x00,0x54,0xff,0x10,0x30,0xe9,0xe8,0x20,0x00,0x00,0x00,0x00,0xe4,0x8c,0x00,0x00,0x00,0x00,0x00, //..*@++@@+....@%.....
0x00,0x00,0x54,0xff,0x10,0x37,0xc6,0x23,0x00,0x00,0x00,0x00,0x00,0xe4,0x8c,0x00,0x00,0x00,0x00,0x00, //..*@++@+.....@%.....
/* 山 */
19,17,18,2,3,0, //dsc : unicode = 0x5c71
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //.......@@........
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //.......@@........
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //.......@@........
0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+
0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+
0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+
0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+
0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+
0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+
0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+
0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+
0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+
0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+
0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+
0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+
0xff,0xd2,0x7c,0x7c,0x7c,0x7c,0x7c,0xed,0xeb,0x7c,0x7c,0x7c,0x7c,0x7c,0xce,0xff,0x0c, //@@*****@@*****@@+
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0c, //@@@@@@@@@@@@@@@@+
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //..............%@+
/* 市 */
20,20,20,0,2,0, //dsc : unicode = 0x5e02
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4e,0xd1,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //........*@+.........
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3b,0xfe,0xbe,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //........+@%+........
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9b,0xc8,0x1a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //.........%@+........
0x68,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80, //*@@@@@@@@@@@@@@@@@@%
0x32,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0xe3,0xe3,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x3e, //+********@@********+
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //.........@@.........
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //.........@@.........
0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00, //..@@@@@@@@@@@@@@@@..
0x00,0x00,0xc0,0xdf,0x74,0x74,0x74,0x74,0x74,0xe1,0xe1,0x74,0x74,0x74,0x74,0x74,0xcf,0xe0,0x00,0x00, //..@@*****@@*****@@..
0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0xa8,0xe0,0x00,0x00, //..@@.....@@.....%@..
0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0xa8,0xe0,0x00,0x00, //..@@.....@@.....%@..
0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0xa8,0xe0,0x00,0x00, //..@@.....@@.....%@..
0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0xa8,0xe0,0x00,0x00, //..@@.....@@.....%@..
0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0xa8,0xe0,0x00,0x00, //..@@.....@@.....%@..
0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0xab,0xdf,0x00,0x00, //..@@.....@@.....%@..
0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x1a,0xe1,0xca,0x00,0x00, //..@@.....@@....+@@..
0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x6c,0xff,0xff,0xff,0xff,0x75,0x00,0x00, //..@@.....@@.*@@@@*..
0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x28,0x8b,0x83,0x7c,0x4c,0x00,0x00,0x00, //..@@.....@@.+%%**...
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //.........@@.........
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //.........@@.........
显示结果:
LVGL
初始化液晶屏和 LVGL 接口的函数,直接调用 esp_lvgl语句实现的,函数就是在 esp32_s3_szp.c 文件中实现的及函数的定义。
esp-bsp 库,使用 VSCode 打开 esp-bsp 文件夹, bsp/esp32_s3_eye/esp32_s3_eye.c 文件, bsp_display_lcd_init()函数,下代码所示:
static lv_display_t *bsp_display_lcd_init(const bsp_display_cfg_t *cfg)
{
assert(cfg != NULL);
esp_lcd_panel_io_handle_t io_handle = NULL;
esp_lcd_panel_handle_t panel_handle = NULL;
const bsp_display_config_t bsp_disp_cfg = {
.max_transfer_sz = BSP_LCD_DRAW_BUFF_SIZE * sizeof(uint16_t),
};
BSP_ERROR_CHECK_RETURN_NULL(bsp_display_new(&bsp_disp_cfg, &panel_handle, &io_handle));
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
esp_lcd_panel_disp_off(panel_handle, false);
#else
esp_lcd_panel_disp_on_off(panel_handle, true);
#endif
/* Add LCD screen */
ESP_LOGD(TAG, "Add LCD screen");
const lvgl_port_display_cfg_t disp_cfg = {
.io_handle = io_handle,
.panel_handle = panel_handle,
.buffer_size = cfg->buffer_size,
.double_buffer = cfg->double_buffer,
.hres = BSP_LCD_H_RES,
.vres = BSP_LCD_V_RES,
.monochrome = false,
/* Rotation values must be same as used in esp_lcd for initial settings of the screen */
.rotation = {
.swap_xy = false,
.mirror_x = false,
.mirror_y = false,
},
.flags = {
.buff_dma = cfg->flags.buff_dma,
.buff_spiram = cfg->flags.buff_spiram,
#if LVGL_VERSION_MAJOR >= 9
.swap_bytes = (BSP_LCD_BIGENDIAN ? true : false),
#endif
}
};
return lvgl_port_add_disp(&disp_cfg);
}
四、实际效果:
总结:
一个基于ESP32-S3和rp2040双核心的智能温湿度显示系统。硬件部分通过连接BME280传感器实现数据采集,软件部分则利用LVGL库设计用户交互界面,并实时显示温湿度数据。ESP32-S3作为主核心负责界面运行与数据显示,而rp2040则负责数据采集与传输。项目关键工作包括界面设计、数据更新与显示、LVGL用户交互界面实现以及温湿度数据采集与处理。通过此系统,用户可直观获取当前环境的温湿度信息。
本帖最后由 meiyao 于 2024-11-5 23:20 编辑