目录

一、系统接线部分

1.1 硬件清单

1.2 接线方案表

1.3 具体接线图

1.4 接线实物图

二、安装与使用部分

三、代码讲解部分

3.1 状态栏及各标签排列

3.2 处理 64位 表情文件

3.3 外部设备的初始化及注册

3.4 处理事件

四、项目结果演示

视频演示

五、常见问题解答

Q1:发送语音后器件无反应?

Q2:语音唤醒不灵敏或自动进入待机状态?

Q3:如何使用自定义表情?


    ✔零知开源(零知IDE)是一个专为电子初学者/电子兴趣爱好者设计的开源软硬件平台,在硬件上提供超高性价比STM32系列开发板、物联网控制板。取消了Bootloader程序烧录,让开发重心从 “配置环境” 转移到 “创意实现”,极大降低了技术门槛。零知IDE编程软件,内置上千个覆盖多场景的示例代码,支持项目源码一键下载,项目文章在线浏览。零知开源(零知IDE)平台通过软硬件协同创新,让你的创意快速转化为实物,来动手试试吧!

✔访问零知实验室,获取更多实战项目和教程资源吧!

www.lingzhilab.com

项目概述

       项目基于零知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口

GPIO_NUM_8

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

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐