- 项目介绍
本项目通过使用RP2040通过ESP32获取完毕天气信息,通过LVGL进行天气信息的刷新,同时通过按键切换不同城市的天气信息。
为了简化开发流程,对ESP32 S2并未进行二次开发,而是使用乐鑫官方推出的AT固件。通过RP2040对ESP32进行AT配置,实现ESP32链接指定WiFI网络,并通过心知天气服务器获取天气信息,因为心知天气服务的免费版功能受限,因此本项目只显示了天气和温度信息,效果图如下
- 设计思路
- 硬件介绍
WIFI模块使用了乐鑫的ESP32-S2-MINI-1主控,气象台主机采用RP2040控制芯片,同时使用了240*240像素的ST7789屏幕作为显示屏幕,外加两颗按键作为上下翻页。
- 制作教程
4.1 ESP32烧录AT固件
4.1.1 固件和工具下载
[ESP32 S2 MINI 1固件]: https://www.espressif.com.cn/zh-hans/news/AT_Firmware_ESP32s2
我手中的ESP32 S2开发板的主控芯片为ESP32-S2-MINI-1,此型号的AT固件版本为V2.1.0.0,下载后即可得到固件文件如下,其中factory文件夹中factory_MINI.bin为合并文件,烧录到芯片0x00的位置。
烧写固件的工具为 Flash_download_tool_3.9.2_0,在首页选择ES32S2芯片烧录,如下图所示即可:
选中下载的ESP32固件,设置好烧录位置,使用USB转TTL模块连接ESP32的RXD0 TXD0两个引脚,按下板子上的BOOT按键,再按下松开RST按键,最后松开BOOT按键,ESP32即进入下载模式(也可通过串口查看TXD0的打印数据 看到download即可),点击Start即可开始对ESP32 S2进行固件下载。
下载完成后查看UART0的打印数据,看到最后打印出 ` 2.1.0 max tx power=78,ret=0`即可,如出现不停刷屏情况即烧录错误,需要检查固件是否正确。
4.1.2 AT测试
乐鑫官方手册中指出,ESP32-S2 AT 采用两个 UART 接口:UART0 用于下载固件和输出日志,UART1 用于发送 AT 命令和接收 AT 响应。我们将串口模块连接到 UART1 进行AT指令测试,收到如下字符即成功烧录AT固件。
发→◇AT
□
收←◆AT
OK
4.2 心知天气获取
注册心知天气账户,开通免费版天气获取。
使用USB转TTL连接ESP32模块,进行AT指令获取天气。
- 关闭回显
发→◇ATE0
□
收←◆ATE0
OK
- AT指令测试
发→◇AT
□
收←◆
OK
- 配置WIFI模式(1:作为客户端 2:作为服务器)
发→◇AT+CWMODE=1
□
收←◆
OK
- 复位ESP32
发→◇AT+RST
□
收←◆
OK
ready
- 连接网络(SSID替换为WIFI名,password为WIFI密码)
发→◇AT+CWJAP="SSID","password"
□
收←◆WIFI CONNECTED
收←◆WIFI GOT IP
OK
- 查询 IP 地址
发→◇AT+CIFSR
□
收←◆+CIFSR:STAIP,"192.168.180.116"
+CIFSR:STAMAC,"84:cc:a8:a0:c0:1c"
收←◆
OK
- 连接心知天气服务器(api.seniverse.com为心知天气服务ip,80为端口)
发→◇AT+CIPSTART="TCP","api.seniverse.com",80
□
收←◆CONNECT
OK
- 使能透传模式
发→◇AT+CIPMODE=1
□
收←◆
OK
- 天气获取(your_api_key替换为私钥,需注意GET ...指令后需加\r\n\r\n)
发→◇AT+CIPSEND
□
收←◆
OK
>
发→◇GET http://api.seniverse.com/v3/weather/now.json?key=your_api_key&location=beijing&language=en&unit=c
收←◆{"results":[{"location":{"id":"WX4FBXXFKE4F","name":"Beijing","country":"CN","path":"Beijing,Beijing,China","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"now":{"text":"Sunny","code":"0","temperature":"33"},"last_update":"2022-07-18T12:34:14+08:00"}]}
- 退出透传(*“+++“ 退出透传发送数据,回到正常 AT 指令模式。此时, TCP 连接仍然是保持的,可以再发 AT+CIPSEND指令,重新开始透传)
发→◇+++
- 退出透传模式
发→◇AT+CIPMODE=0
□
收←◆
OK
- 断开服务器连接
发→◇AT+CIPCLOSE
□
收←◆
CLOSED
OK
通过以上流程便完成了一次天气信息获取,但是自己手写此部分代码较为繁琐,因此我们通常使用专用库 ESP_AT_Lib,ESP-AT 库命令解析器是一个通用的、独立于平台的库,用于使用 AT 命令与 ESP8266 Wi-Fi 模块进行通信。
4.3 RP2040开发
4.2.1 LVGL显示
LVGL的作者是来自匈牙利的Gabor Kiss-Vamosikisvegabor,LVGL用C语言编写,以实现最大的兼容性(与C ++兼容),模拟器可在没有嵌入式硬件的PC上启动嵌入式GUI设计,同时LVGL作为一个图形库,它自带着接近三十多种小工具可以供开发者使用。这些强大的构建块按钮搭配上带有非常丝滑的动画以及可以做到平滑滚动的高级图形,同时兼具着不高的配置要求以及开源属性,显著的优势使得LVGL蔚然成风,成为广大开发者在选择GUI时的第一选择。
使用LVGL首先需要对TFT进行初始化:
void Display_Init(void)
{
tft.begin(); /* TFT init */
tft.setRotation(0); /* Landscape orientation */
tft.fillScreen(0xFFFF);
}
本项目的天气显示部分通过LVGL进行显示,以下代码创建了一个天气台的显示屏布局,可将心知天气获取的信息填充并显示:
void WeatherView::Create(lv_obj_t *root)
{
lv_obj_remove_style_all(root);
lv_obj_set_size(root, LV_HOR_RES, LV_VER_RES);
lv_obj_set_scrollbar_mode(root, LV_SCROLLBAR_MODE_OFF); // 关闭滑动条
// 城市信息创建
lv_obj_t* city_label = lv_label_create(root);
lv_obj_set_style_text_font(city_label, Resource.GetFont("city_cn_10"), 0);
lv_obj_set_style_text_color(city_label, lv_color_hex(0x000000), 0);
lv_label_set_text(city_label, "石家庄");
lv_obj_set_pos(city_label, 15, 25);
ui.city_label = city_label;
// 城市位置创建
lv_obj_t *distantion = lv_img_create(root);
lv_img_set_src(distantion, Resource.GetImage("distantion"));
lv_obj_set_pos(distantion, 120, 20);
// 创建风格
static lv_style_t style_shadow;
lv_style_init(&style_shadow);
lv_style_set_bg_color( &style_shadow, lv_color_hex(0x97bff2) );
lv_style_set_bg_grad_color( &style_shadow, lv_color_hex(0x6998f2) );
lv_style_set_bg_grad_dir( &style_shadow, LV_GRAD_DIR_VER ); // 创建过渡颜色
// 创建天气背板
lv_obj_t *weatherback = lv_obj_create(root);
lv_obj_set_size(weatherback, 220, 120);
lv_obj_set_pos(weatherback, 10, 115);
lv_obj_add_style(weatherback, &style_shadow, LV_PART_MAIN);
// 天气图片创建
lv_obj_t *weather = lv_img_create(root);
lv_img_set_src(weather, Resource.GetImage("Cloud_angled_rain_zap"));
lv_obj_set_pos(weather, 23, 95);
ui.weather = weather;
// 天气温度创建
lv_obj_t* label_tem = lv_label_create(root);
lv_obj_set_style_text_font(label_tem, Resource.GetFont("num_56"), 0);
lv_obj_set_style_text_color(label_tem, lv_color_hex(0xBAD8FE), 0);
lv_label_set_text(label_tem, "27");
lv_obj_set_pos(label_tem, 115, 115);
ui.label_tem = label_tem;
lv_obj_t* label = lv_label_create(root);
lv_obj_set_style_text_font(label, Resource.GetFont("tem"), 0);
lv_obj_set_style_text_color(label, lv_color_hex(0xBAD8FE), 0);
lv_label_set_text(label, "℃");
lv_obj_set_pos(label, 190, 160);
// 天气状态
lv_obj_t* text_label = lv_label_create(root);
lv_obj_set_style_text_font(text_label, Resource.GetFont("en_18"), 0);
lv_obj_set_style_text_color(text_label, lv_color_hex(0xf3f7ff), 0);
lv_label_set_text(text_label, "Rain");
lv_obj_set_pos(text_label, 35, 180);
ui.text_label = text_label;
// 更新时间
lv_obj_t* updata_label = lv_label_create(root);
lv_obj_set_style_text_font(updata_label, Resource.GetFont("time_10"), 0);
lv_obj_set_style_text_color(updata_label, lv_color_hex(0xf3f7ff), 0);
lv_label_set_text(updata_label, "2022-08-31T21:07");
lv_obj_set_pos(updata_label, 35, 210);
ui.updata_label = updata_label;
}
4.2.2 ESP32 AT通信
ESP32 S2与RP2040进行的交互主要依赖于乐鑫官方的AT指令集,因此此部分引入了ESP_AT_Lib库,能够更方便的进行芯片管理。
在系统初始化时刻就通过AT指令对ESP32 S2进行了WIFI配置,同时在WIFI连接完成后进行5个城市的天气信息获取,获取完毕后通过LVGL调用显示,具体代码如下:
bool wifi_init(void)
{
EspSerial.begin(ESP_AT_BAUD);
WiFiDebug.print("FW Version:");
WiFiDebug.println(wifi.getVersion().c_str());
WiFiDebug.print("Set AP/STA Mode ");
if (wifi.setOprToStationSoftAP())
{
WiFiDebug.println("OK");
return 1;
}
else
{
WiFiDebug.println("failed");
return 0;
}
return 0;
}
bool wifi_connecting(void)
{
WiFiDebug.print("Join WiFi ");
if (wifi.joinAP(SSID, PASSWORD))
{
WiFiDebug.println("Connect to WiFi OK");
WiFiDebug.print("IP: ");
WiFiDebug.println(wifi.getLocalIP().c_str());
return 1;
}
else
{
WiFiDebug.println("Connect to WiFi failed");
return 0;
}
return 0;
}
- 项目不足
因为本次采用的气象平台为心知天气,心知天气的免费版本能够获取的天气信息较少,无法更详尽的预报天气,并且天气采用英文显示,没有采用中文,也是需要改进的一个部分。
- 代码链接
链接:https://pan.baidu.com/s/1zLvxPEOnIlql0vAT2xQVlw?pwd=wwuh
提取码:wwuh