YOLO11 目标检测在 ESP32-S3 上的实现 —— 开发全流程记录
一、项目概述
本项目基于 ESP-DL 库的 yolo11_detect 示例,在 ESP32-S3(N16R8,16MB Flash + 8MB PSRAM)上实现了从网络获取 JPEG 图片、进行 YOLO11n 目标检测、并通过串口交互式输入 URL 输出中文检测结果的功能。
二、开发环境与工具
-
硬件:ESP32-S3-WROOM-1-N16R8(16MB Flash)
-
软件框架:ESP-IDF v6.0.1
-
AI 推理库:ESP-DL v3.3.2(组件化安装)
-
模型:YOLO11n INT8 量化模型(
coco_detect_yolo11n_s8_v1.espdl),存放于 Flash 的coco_det分区 -
编程语言:C++(
app_main.cpp)
三、项目创建与初始化
1. 从官方示例创建项目
bash
idf.py create-project-from-example "espressif/esp-dl=3.3.2:yolo11_detect"
该命令会自动下载示例代码并生成项目骨架。
2. 设置目标芯片
bash
idf.py set-target esp32s3
四、关键配置步骤
4.1 分区表配置(partitions2.csv)
原始示例默认使用 8MB Flash,但模型 + 应用超过 8MB,需调整为适配 16MB Flash:
csv
nvs, data, nvs, 0x9000, 24K, phy_init, data, phy, 0xf000, 4K, factory, app, factory, 0x010000, 8M, # 应用分区 8MB coco_det, data, spiffs, , 4M, # 模型分区 4MB(实际模型 2.8MB)
-
若模型嵌入固件(
EMBED_FILES),则无需coco_det分区,但此处采用独立分区烧录模型。
4.2 组件依赖(idf_component.yml)
项目需要 esp_new_jpeg(但最终使用 dl_image_jpeg 软件解码,故未实际添加)。网络功能所需组件已在 main/CMakeLists.txt 中通过 REQUIRES 声明。
4.3 主组件构建文件(main/CMakeLists.txt)
-
移除
EMBED_FILES(防止模型嵌入 App,导致体积过大) -
添加网络组件依赖:
cmake
set(requires coco_detect
esp_wifi
esp_http_client
nvs_flash
esp_event
esp_netif)
-
保留条件编译(
esp32_s3_eye_noglib等)
4.4 Menuconfig 设置
-
Flash Size:
Serial flasher config→Flash size→16 MB -
优化选项:
Compiler options→Optimization Level→-Os(减小 App 体积) -
看门狗:
Component config→ESP System Settings→Enable Task Watchdog Timer→ 取消勾选(或延长超时,我们在代码中调用esp_task_wdt_deinit()禁用)
五、代码开发与功能实现
5.1 核心功能模块
-
Wi-Fi 连接:
wifi_init_sta()使用事件组等待 IP 分配,返回连接状态。 -
HTTP 图片下载:采用
esp_http_client_open()+esp_http_client_fetch_headers()+ 循环esp_http_client_read()的流式方式,避免一次性读取失败(关键)。 -
JPEG 解码:使用 ESP-DL 的
dl::image::sw_decode_jpeg()将 JPEG 转为 RGB888。 -
YOLO 推理:
COCODetect类自动从coco_det分区加载模型,调用run()得到检测结果列表。 -
串口交互:自定义
read_line()函数,基于getchar实现命令行输入,支持退格、忽略非打印字符。 -
结果输出:使用预定义的中文类别名称数组,将类别 ID 映射为中文显示。
5.2 关键代码片段
下载函数(解决读取 0 字节问题)
cpp
esp_http_client_config_t config = {};
config.url = url;
config.method = HTTP_METHOD_GET;
config.timeout_ms = 30000;
config.user_agent = "Mozilla/5.0";
config.keep_alive_enable = false;
esp_http_client_handle_t client = esp_http_client_init(&config);
esp_http_client_set_header(client, "Accept-Encoding", "identity");
esp_http_client_open(client, 0);
int content_length = esp_http_client_fetch_headers(client);
// 循环读取直到 content_length 或连接关闭
串口输入函数(避免 fgets 阻塞问题)
cpp
static int read_line(char *buf, int max_len) {
int idx = 0;
while (1) {
int c = getchar();
if (c == EOF) continue;
if (c == '\r' || c == '\n') { buf[idx] = '\0'; return idx; }
// 处理退格、可打印字符...
}
}
六、编译、烧录与运行
6.1 编译
bash
idf.py build
常见编译错误及解决:
-
missing-field-initializers:改用
wifi_config_t wifi_config = {};然后逐个字段赋值,或使用strcpy。 -
类型不匹配:
esp_http_client_read_response要求char*,传入uint8_t*需强制转换(char*)。 -
未使用变量警告:移除
TAG,在事件处理函数中添加(void)event_data;。
6.2 烧录模型到 Flash 分区
使用 esptool.py 单独烧录模型(或通过 idf.py flash 自动执行,如果已在 CMake 中添加 esptool_py_flash_to_partition):
bash
复制
下载
esptool.py --chip esp32s3 --port COMx write_flash 0x810000 coco_detect_yolo11n_s8_v1.espdl
0x810000 根据分区表计算(
coco_det的偏移量)。若使用partitions2.csv自动分配,偏移量可通过idf.py partition-table查看。
6.3 烧录应用
bash
idf.py -p COM22 flash
6.4 运行监视
bash
idf.py -p COM22 monitor
程序启动后自动连接 Wi-Fi,然后进入交互模式等待用户输入图片 URL。

七、问题与解决方案汇总
| 问题现象 | 原因分析 | 解决方法 |
|---|---|---|
App 分区溢出(factory 太小) |
模型被嵌入固件(EMBED_FILES)或 App 本身过大 |
移除 EMBED_FILES;使用 16MB Flash 并扩大 factory 分区;启用 -Os 优化 |
HTTP 下载 esp_http_client_read_response 返回 0 |
一次性读取方式不适合 chunked 或 keep-alive 连接 | 改用 esp_http_client_open + 循环 esp_http_client_read |
串口输入 fgets 不等待,直接退出 |
stdin 缓冲问题,EOF 提前到来 |
改用 getchar 循环手动读取,忽略 EOF |
| 看门狗超时复位 | YOLO 推理耗时较长(约 5~8秒) | 禁用看门狗 esp_task_wdt_deinit() 或延长超时 |
| 编译警告 missing-field-initializers | 结构体指定初始化顺序与声明不一致 | 使用全零初始化 + 逐字段赋值 |
| 模型加载失败(未找到分区) | 分区名 coco_det 与代码中加载名不一致 |
确认分区表名称与 COCODetect() 默认查找名称一致(示例默认 coco_det) |
| 图片下载失败(域名解析) | DNS 未配置或网络不通 | 使用 IP 直连测试,确保 Wi-Fi 连接正常 |
八、最终程序特点
-
中文交互:所有提示、错误信息、检测结果类别均为中文。
-
简洁界面:仅显示必要的状态和结果,无大量调试日志。
-
灵活输入:支持通过串口动态输入任意图片 URL,重复识别。
-
稳定下载:流式 HTTP 读取,支持 chunked 和固定长度响应。
-
资源释放:每次循环后释放图片数据和模型对象,防止内存泄漏。
九、后续可扩展方向
-
支持从 SD 卡加载模型,释放 Flash 空间。
-
支持从本地文件系统读取图片(如 SPIFFS)。
-
增加 JSON 格式输出,方便上位机解析。
-
接入摄像头实时视频流,实现连续检测。
十、参考资源
更多推荐


所有评论(0)