零知IDE——零知ESP32-S3部署 AI小智 2.0版发布!调整界面UI,新增LED、舵机和风扇外部设备和控制
A:可以用PS将表情像素调整到 32*32,保存后通过官方工具转换成 .c文件,注意格式选择RGB565A8。
目录
✔零知开源(零知IDE)是一个专为电子初学者/电子兴趣爱好者设计的开源软硬件平台,在硬件上提供超高性价比STM32系列开发板、物联网控制板。取消了Bootloader程序烧录,让开发重心从 “配置环境” 转移到 “创意实现”,极大降低了技术门槛。零知IDE编程软件,内置上千个覆盖多场景的示例代码,支持项目源码一键下载,项目文章在线浏览。零知开源(零知IDE)平台通过软硬件协同创新,让你的创意快速转化为实物,来动手试试吧!
✔访问零知实验室,获取更多实战项目和教程资源吧!
项目概述
项目基于零知ESP32-S3部署 AI小智 1.0版本,调整了界面的布局,同时添加了对LED灯、L9110风扇传感器模块的开关,还有舵机SG90的开关以及控制舵机转动角度的功能
项目难点及解决方案
问题描述:状态栏布局调整和表情图片转成LVGL9能识别的文件
解决方案:
将状态栏status_bar_排列方式改成 LV_FLEX_FLOW_COLUMN 垂直排列,可调整标签labe间距到合适的距离;表情文件可自定义并通过官网转换 .c 文件,要注意对应的LVGL版本。
一、系统接线部分
1.1 硬件清单
| 组件名称 | 型号规格 | 数量 | 备注 |
|---|---|---|---|
| 主控板 | 零知ESP32-S3 | 1 | 主控制器 |
| 底板 | 小智扩展底板 | 1 | 零知ESP32-S3扩展板 |
| 扬声器 | 腔体喇叭扬声器3.2W | 1 | 音频输出 |
| LCD显示屏 | 2.0寸SPI ST7789 | 1 | 数据显示 |
| LED | F3 3MM七彩快闪LED | 1 | 灯光控制 |
| 舵机 | SG90舵机模块 | 1 | 舵机控制 |
| 风扇 | L9110风扇传感器模块 | 1 | 风扇控制 |
| 杜邦线 | 母对母、公对母 | 若干 | 系统连接 |
1.2 接线方案表
AI 小智1.0版本中有介绍扩展板、喇叭和显示屏的连接方式,包括代码下载和验证,不清楚的可以跳转查看,这里只提及新添加功能,根据代码中的引脚定义,硬件接线方案如下:
| ESP32-S3引脚 | 连接模块 | 功能描述 | 代码定义 |
|---|---|---|---|
| IO2 | LED正极(长脚) | 控制LED开关 | GPIO_NUM_2 |
| IO8 | L9110模块INA | 风扇模块INA口 |
|
| IO19 | L9110模块INB | 风扇模块INB口 | GPIO_NUM_19 |
| IO20 | SG90舵机PMW引脚 | 输入舵机角度 | GPIO_NUM_20 |
1.3 具体接线图
请注意:SG90 舵机模块和L9110风扇模块都需要 5V 供电,这里先将风扇模块接到3.3V,也可以将5V电压接到洞洞板上;
1.4 接线实物图
二、安装与使用部分
2.1 开源平台-输入 小智 并搜索-代码下载自动打开
2.2 连接-验证-上传
三、代码讲解部分
3.1 状态栏及各标签排列
/* Status bar */
lv_obj_set_flex_flow(status_bar_, LV_FLEX_FLOW_COLUMN);
lv_obj_set_style_border_width(status_bar_, 0, 0);
lv_obj_set_style_pad_column(status_bar_, 0, 0);
lv_obj_set_style_pad_all(status_bar_, 0, 0);
lv_obj_set_style_pad_row(status_bar_, 0, 0);
lv_obj_set_style_pad_top(status_bar_, 5, 0);
lv_obj_set_scrollbar_mode(status_bar_, LV_SCROLLBAR_MODE_OFF);
// 设置状态栏的内容垂直居中
lv_obj_set_flex_align(status_bar_, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
//状态标签 status_label_
status_label_ = lv_label_create(status_bar_);
lv_obj_set_flex_grow(status_label_, 0); // 不拉伸
lv_label_set_long_mode(status_label_, LV_LABEL_LONG_SCROLL_CIRCULAR);
lv_obj_set_style_text_color(status_label_, current_theme_.text, 0);
lv_label_set_text(status_label_, "初始化");
lv_obj_set_style_text_align(status_label_, LV_TEXT_ALIGN_LEFT, 0);
// 表情标签 emotion_label_
lv_obj_t* center_container = lv_obj_create(status_bar_);
lv_obj_set_flex_grow(center_container, 1); // 占据剩余空间
lv_obj_set_style_bg_opa(center_container, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(center_container, 0, 0);
lv_obj_set_style_pad_all(center_container, 0, 0);
lv_obj_set_width(center_container, LV_SIZE_CONTENT);
lv_obj_set_height(center_container, LV_SIZE_CONTENT);
emotion_label_ = lv_label_create(center_container);
lv_obj_set_style_text_font(emotion_label_, &font_awesome_30_4, 0);
lv_obj_set_style_text_color(emotion_label_, current_theme_.text, 0);
// lv_label_set_text(emotion_label_, FONT_AWESOME_AI_CHIP);
lv_obj_center(emotion_label_); // 水平垂直居中
LV_FLEX_FLOW_COLUMN 会让状态栏中的标签垂直排列,调整间距让外观看起来更舒适
3.2 处理 64位 表情文件
//读取64位的表情文件并返回
const lv_font_t *font_emoji_64_init(void)
{
static lv_font_t *font = NULL;
if (font == NULL) {
font = lv_imgfont_create(64, get_imgfont_path, NULL);
if (font == NULL) {
LV_LOG_ERROR("Failed to allocate memory for emoji font");
return NULL;
}
font->base_line = 0;
font->fallback = NULL;
}
return font;
}
返回的数据可以直接给emotion_label_展示
lv_obj_set_style_text_font(emotion_label_, font_emoji_64_init(), 0); //调用处
3.3 外部设备的初始化及注册
// 1.定义了LED的属性
std::vector<ai_vox::iot::Property> led_properties({
{
"state", // 属性名
"LED灯开关状态", // 属性描述
ai_vox::iot::ValueType::kBool // 属性类型
},
// 添加更多属性
});
// 2.定义LED功能
std::vector<ai_vox::iot::Function> led_functions({
{"TurnOn", // 功能名
"打开LED灯", // 功能描述
{
// no parameters
}},
{"TurnOff", // 功能名
"关闭LED灯", // 功能描述
{
// 无参数
}},
// 添加更多功能
});
// 3.创建LED实体
g_led_iot_entity = std::make_shared<ai_vox::iot::Entity>("Led", // name
"LED灯", // description
std::move(led_properties), // properties
std::move(led_functions) // functions
);
// 4.初始化LED实体的默认值
g_led_iot_entity->UpdateState("state", false);
// 5.注册LED实体到 AI Vox 引擎
ai_vox_engine.RegisterIotEntity(g_led_iot_entity);
如果一些文字识别不清晰或者出错,可以更改功能描述,例如“舵机”可更换成“马达”等容易识别的词
3.4 处理事件
//从g_observer观察者对象中取出所有待处理的事件
const auto events = g_observer->PopEvents();
for (auto& event : events) {
//IoT 消息事件
if (auto iot_message_event = std::get_if<ai_vox::Observer::IotMessageEvent>(&event)) {
//处理 LED 设备指令
if (iot_message_event->name == "Led") {
if (iot_message_event->function == "TurnOn") {
printf("turn on led\n");
digitalWrite(kLedPin, HIGH); // 硬件操作:点亮 LED
g_led_iot_entity->UpdateState("state", true); // 更新 LED 状态实体(关键:硬件状态同步)
} else if (iot_message_event->function == "TurnOff") {
printf("turn off led\n");
digitalWrite(kLedPin, LOW); // 硬件操作:关闭 LED
g_led_iot_entity->UpdateState("state", false); // 同步状态到实体
}
}
}
}
处理消息后注意同步状态,但随着设备重启,状态也会重置
四、项目结果演示
视频演示
零知ESP32-S3部署 AI小智 2.0版发布!
音乐播放器系统物理按键操作/多控制方式状态同步+Web界面和远程控制演示+LVGL GUI图形界面
五、常见问题解答
Q1:发送语音后器件无反应?
A:在处理 IOT 事件中,执行对应操作后要同步更新实体状态
g_xxx_iot_entity->UpdateState();
Q2:语音唤醒不灵敏或自动进入待机状态?
A:WiFi信号不稳定或者查看是否短路,比如屏幕后面的器件跟模块外壳接触容易导致短路,可以在屏幕后面贴上绝缘
Q3:如何使用自定义表情?
A:可以用PS将表情像素调整到 32*32,保存后通过官方工具转换成 .c文件,注意格式选择RGB565A8
更多推荐


所有评论(0)