ESP32-S3智能小车
ESP32-S3智能小车
前言
智能小车是嵌入式开发的经典项目,它融合了硬件控制、传感器应用、网络通信等多个技术领域。本文将详细介绍如何基于ESP32-S3开发板,从零开始构建一个功能完整的WiFi遥控智能小车,包括硬件设计、软件架构、算法优化等各个方面。
项目概述
本项目实现了一个基于ESP32-S3-MINI-1的智能小车,具备以下核心功能:
- WiFi遥控: 通过Web界面实时控制小车运动
- 多种运行模式: 手动控制、跟随模式、循迹模式、自由运行(避障)
- 传感器融合: 5路循迹传感器 + 超声波传感器
- 模块化设计: 清晰的代码架构,易于扩展和维护
硬件设计
核心组件详解
1. ESP32-S3-MINI-1开发板
ESP32-S3-MINI-1是乐鑫科技推出的高性能WiFi+蓝牙双模芯片开发板,是本项目的核心控制器。
技术规格:
- 处理器: Xtensa双核32位LX7,主频240MHz
- 内存: 512KB SRAM,支持外部PSRAM扩展
- 存储: 内置Flash,支持外部Flash扩展
- 无线通信:
- WiFi 802.11 b/g/n,支持2.4GHz频段
- 蓝牙5.0 (BLE)
- GPIO: 45个可编程GPIO,支持多种外设接口
- 工作电压: 3.0V - 3.6V
- 工作温度: -40°C ~ 85°C
选择理由:
- 强大的处理能力,支持复杂的控制算法
- 内置WiFi,无需额外模块即可实现网络通信
- 丰富的GPIO接口,满足多传感器需求
- 完善的ESP-IDF开发框架,开发效率高
2. TB6612FNG电机驱动模块
TB6612FNG是东芝公司生产的双通道H桥电机驱动芯片,用于驱动两个直流电机。
技术规格:
- 驱动方式: 双H桥驱动
- 工作电压: 2.5V - 15V(逻辑),4.5V - 13.5V(电机)
- 最大驱动电流: 1.2A(连续),3.2A(峰值)
- PWM频率: 1kHz - 100kHz(本项目使用1kHz)
- 控制方式:
- 方向控制:AIN1/AIN2(电机A),BIN1/BIN2(电机B)
- 速度控制:PWMA/PWMB(PWM信号)
- 使能控制:STBY(高电平使能)
工作原理:
前进:AIN1=HIGH, AIN2=LOW, PWMA=PWM信号
后退:AIN1=LOW, AIN2=HIGH, PWMA=PWM信号
停止:AIN1=LOW, AIN2=LOW 或 STBY=LOW
GPIO连接:
- AIN1: GPIO1(左轮方向控制1)
- AIN2: GPIO2(左轮方向控制2)
- PWMA: GPIO3(左轮PWM控制)
- BIN1: GPIO4(右轮方向控制1)
- BIN2: GPIO5(右轮方向控制2)
- PWMB: GPIO6(右轮PWM控制)
- STBY: GPIO7(使能控制)
3. 5路循迹传感器模块
5路循迹传感器采用红外反射原理,通过检测地面反射光强度来判断是否检测到黑线。
技术规格:
- 检测原理: 红外反射式
- 传感器数量: 5路独立传感器
- 传感器间距: 2cm - 2.5cm - 2.5cm - 2cm(从左到右)
- 检测宽度: 约9cm(传感器阵列总宽度)
- 检测距离: 0.5cm - 3cm(可调)
- 响应时间: < 1ms
- 工作电压: 3.3V - 5V
传感器布局:
传感器位置示意图:
s1(-4.5cm) s2(-2.5cm) s3(0cm) s4(2.5cm) s5(4.5cm)
| | | | |
2cm 2.5cm 2.5cm 2cm
工作原理:
- 传感器发射红外光,接收地面反射光
- 白色地面反射强,传感器输出LOW(未检测到黑线)
- 黑色布条吸收光,反射弱,传感器输出HIGH(检测到黑线)
GPIO连接:
- OUT1: GPIO8(最左侧传感器)
- OUT2: GPIO9(左侧传感器)
- OUT3: GPIO10(中间传感器)
- OUT4: GPIO11(右侧传感器)
- OUT5: GPIO12(最右侧传感器)
4. HC-SR04超声波传感器
HC-SR04是常用的超声波测距模块,通过测量超声波往返时间计算距离。
技术规格:
- 工作电压: 5V
- 工作电流: < 15mA
- 测量范围: 2cm - 400cm
- 测量精度: 3mm
- 测量角度: 15度
- 响应频率: 40kHz
- 工作温度: -15°C ~ 70°C
工作原理:
- 向Trig引脚发送10μs高电平触发信号
- 模块自动发送8个40kHz超声波脉冲
- 模块检测回波,Echo引脚输出高电平
- 高电平持续时间与距离成正比:距离 = (高电平时间 × 声速) / 2
GPIO连接:
- Trig: GPIO13(触发引脚)
- Echo: GPIO14(回响引脚)
硬件连接总览
完整的硬件连接表:
| 模块 | 引脚 | ESP32-S3 GPIO | 说明 |
|---|---|---|---|
| TB6612 | AIN1 | GPIO1 | 左轮方向控制1 |
| TB6612 | AIN2 | GPIO2 | 左轮方向控制2 |
| TB6612 | PWMA | GPIO3 | 左轮PWM控制 |
| TB6612 | BIN1 | GPIO4 | 右轮方向控制1 |
| TB6612 | BIN2 | GPIO5 | 右轮方向控制2 |
| TB6612 | PWMB | GPIO6 | 右轮PWM控制 |
| TB6612 | STBY | GPIO7 | 使能控制 |
| 循迹传感器 | OUT1 | GPIO8 | 最左侧传感器 |
| 循迹传感器 | OUT2 | GPIO9 | 左侧传感器 |
| 循迹传感器 | OUT3 | GPIO10 | 中间传感器 |
| 循迹传感器 | OUT4 | GPIO11 | 右侧传感器 |
| 循迹传感器 | OUT5 | GPIO12 | 最右侧传感器 |
| 超声波 | Trig | GPIO13 | 触发引脚 |
| 超声波 | Echo | GPIO14 | 回响引脚 |
电源设计
- 电机电源: 7.4V锂电池(2节18650串联),直接连接到TB6612的VM引脚
- 逻辑电源: ESP32-S3使用3.3V,通过板载LDO从USB或外部电源转换
- 传感器电源: 循迹传感器使用3.3V,超声波传感器使用5V(需电平转换或独立供电)
注意事项:
- 电机电源和逻辑电源需要共地
- 建议使用独立电源为电机供电,避免影响ESP32稳定性
- 确保电源容量足够,建议使用2000mAh以上的锂电池
软件架构设计
分层架构
项目采用经典的分层架构设计,实现了硬件抽象、业务逻辑和用户接口的清晰分离:
┌─────────────────────────────────┐
│ 应用层 (main.c) │
│ - 系统初始化 │
│ - 任务调度 │
│ - 组件协调 │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ 中间件层 (middle/) │
│ - Web服务 (web/) │
│ * HTTP服务器 │
│ * RESTful API │
│ * Web界面 │
│ - WiFi管理 (wifi_manage/) │
│ * AP/STA模式切换 │
│ * NVS配置存储 │
│ - 小车控制 (car_control/) │
│ * 模式管理 (car_mode) │
│ * 跟随模式 (car_follow) │
│ * 循迹模式 (car_track) │
│ * 自由运行 (car_free) │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ 硬件抽象层 (bsp/) │
│ - TB6612驱动 │
│ * PWM控制 │
│ * 方向控制 │
│ - 循迹传感器 (line_tracker) │
│ * 多路传感器读取 │
│ - 超声波传感器 (ultrasonic) │
│ * 距离测量 │
└─────────────────────────────────┘
软件模块详解
1. 硬件抽象层 (BSP)
TB6612驱动模块 (bsp/tb6612/)
- 功能: 封装电机控制接口,提供高级API
- 核心接口:
esp_err_t tb6612_init(void); // 初始化 esp_err_t tb6612_car_forward(uint8_t speed); // 前进 esp_err_t tb6612_car_backward(uint8_t speed); // 后退 esp_err_t tb6612_car_turn_left(uint8_t speed); // 左转 esp_err_t tb6612_car_turn_right(uint8_t speed); // 右转 esp_err_t tb6612_set_car(int16_t left, int16_t right); // 自定义速度 - 技术细节:
- 使用LEDC(LED PWM控制器)生成PWM信号
- PWM频率:1kHz,分辨率:8位(0-255)
- 支持正反转和速度控制
循迹传感器模块 (bsp/line_tracker/)
- 功能: 读取5路循迹传感器状态
- 核心接口:
esp_err_t line_tracker_init(void); esp_err_t line_tracker_read_all(line_tracker_state_t *state); bool line_tracker_read_sensor(uint8_t sensor_num); - 技术细节:
- 使用GPIO输入模式,上拉电阻
- 支持单路和批量读取
- 提供状态结构体,便于算法处理
超声波传感器模块 (bsp/ultrasonic/)
- 功能: 测量前方障碍物距离
- 核心接口:
esp_err_t ultrasonic_init(void); esp_err_t ultrasonic_measure_cm(float *distance_cm); - 技术细节:
- 使用GPIO和定时器测量Echo高电平时间
- 自动计算距离(考虑声速和温度)
- 支持超时检测和错误处理
2. 中间件层
WiFi管理模块 (middle/wifi_manage/)
- 功能: WiFi连接管理和配置存储
- 核心特性:
- 支持AP模式(配网模式)和STA模式(连接WiFi)
- 使用NVS(非易失性存储)保存WiFi配置
- 自动重连机制
- 配置缓存优化
- 工作流程:
- 启动时检查NVS中是否有保存的WiFi配置
- 如果有,自动连接;如果没有,启动AP模式
- 通过Web界面配置WiFi后,保存到NVS并重启
小车控制模块 (middle/car_control/)
这是项目的核心模块,采用模块化设计,每个功能模式都是独立的模块:
模式管理模块 (car_mode.c/h)
- 功能: 统一管理小车运行模式
- 模式类型:
CAR_MODE_MANUAL: 手动控制模式CAR_MODE_FOLLOW: 跟随模式CAR_MODE_FREE: 自由运行模式(避障)CAR_MODE_TRACK: 循迹模式
- 核心接口:
car_mode_t car_mode_get(void); esp_err_t car_mode_set(car_mode_t mode); const char* car_mode_get_name(car_mode_t mode);
跟随模式模块 (car_follow.c/h)
- 功能: 使用超声波传感器保持跟随距离
- 算法特点:
- PID式距离控制
- 可配置跟随距离和速度
- 平滑的速度调整
- 配置参数:
typedef struct { uint8_t base_speed; // 基础速度 float follow_distance; // 跟随距离(cm) float max_distance; // 最大检测距离 uint32_t check_interval_ms; // 检测间隔 } car_follow_config_t;
循迹模式模块 (car_track.c/h)
- 功能: 沿黑线自动行驶
- 算法特点:
- 加权偏差计算(考虑传感器实际位置)
- 智能速度控制(根据偏差和急转弯调整)
- 丢失黑线容错机制
- 优化参数:
- 基础速度:180(针对3cm布条优化)
- 最大速度:240
- 检测间隔:20ms(快速响应)
自由运行模块 (car_free.c/h)
- 功能: 自动避障探索
- 算法特点:
- 障碍物检测和后退
- 随机转向选择
- 可配置避障距离
Web服务模块 (middle/web/)
- 功能: HTTP服务器和Web界面
- 技术栈:
- ESP-IDF HTTP服务器组件
- 嵌入式HTML/CSS/JavaScript
- RESTful API设计
- API接口:
POST /api/car/control- 手动控制GET/POST /api/car/mode- 模式管理GET /api/sensors- 传感器数据GET /api/info- 系统信息GET/POST /api/wifi/config- WiFi配置
模块解耦设计
一个重要的设计决策是将Web服务与功能模块完全解耦:
解耦前的问题:
- Web服务代码包含大量业务逻辑(循迹算法、跟随算法等)
- 难以测试和维护
- 添加新功能需要修改Web服务代码
- 代码耦合度高,修改影响面大
解耦后的优势:
- Web服务只负责HTTP请求处理和响应
- 功能模块独立,易于单元测试
- 新增功能只需添加新模块,无需修改Web服务
- 代码结构清晰,职责分明
实现方式:
// car_mode.h - 模式管理接口
typedef enum {
CAR_MODE_MANUAL = 0,
CAR_MODE_FOLLOW = 1,
CAR_MODE_FREE = 2,
CAR_MODE_TRACK = 3
} car_mode_t;
car_mode_t car_mode_get(void);
esp_err_t car_mode_set(car_mode_t mode);
// car_follow.h - 跟随模式接口
TaskHandle_t car_follow_start(const car_follow_config_t *config);
void car_follow_stop(TaskHandle_t task_handle);
// car_track.h - 循迹模式接口
TaskHandle_t car_track_start(const car_track_config_t *config);
void car_track_stop(TaskHandle_t task_handle);
// car_free.h - 自由运行模式接口
TaskHandle_t car_free_start(const car_free_config_t *config);
void car_free_stop(TaskHandle_t task_handle);
Web服务中的使用:
// web_server.c - 只负责HTTP处理,调用功能模块
if (new_mode == CAR_MODE_FOLLOW) {
task_handle = car_follow_start(NULL);
car_mode_set_task_handle(task_handle);
} else if (new_mode == CAR_MODE_TRACK) {
task_handle = car_track_start(NULL);
car_mode_set_task_handle(task_handle);
}
// ... 其他模式
任务管理
项目使用FreeRTOS进行任务管理:
- 主任务: 系统初始化和组件启动
- Web服务任务: HTTP服务器(ESP-IDF内部管理)
- 自动模式任务: 跟随/循迹/自由运行模式(独立任务)
- WiFi任务: WiFi连接管理(ESP-IDF内部管理)
任务优先级:
- 自动模式任务:优先级5(较高,保证实时响应)
- Web服务:默认优先级
- 系统任务:低优先级
核心算法实现
循迹算法优化
循迹算法是项目的核心难点。针对3cm宽黑线和特定的传感器间距,我们实现了优化的循迹算法。
1. 偏差计算算法
传统算法使用简单的加权平均,我们考虑了传感器的实际物理位置:
// 传感器位置权重(考虑实际间距:2-2.5-2.5-2 cm)
// 传感器位置:s1(-2.0), s2(-0.75), s3(0), s4(0.75), s5(2.0)
float weighted_pos = 0.0f;
int weight_sum = 0;
if (s1) {
weighted_pos += -2.0f * 3; // 最左侧,权重3
weight_sum += 3;
}
if (s2) {
weighted_pos += -0.75f * 2; // 左侧,权重2
weight_sum += 2;
}
if (s3) {
weighted_pos += 0.0f * 4; // 中间,权重4(最重要)
weight_sum += 4;
}
// ... 其他传感器
2. 速度控制策略
优化后的速度控制策略:
- 居中时: 略微加速(+10),充分利用直道
- 正常转向: 减少速度差(35/30),保持较高速度
- 急转弯: 优化速度差(50/50),快速转向但保持速度
- 微调: 增加修正力度(20/25),快速回到中间
if (deviation == 0) {
// 居中,直行(可以稍微加速)
left_speed = track_speed + 10;
right_speed = track_speed + 10;
} else if (sharp_turn) {
// 急转弯:快速转向,但保持较高速度
left_speed = track_speed - (abs_dev * 50);
right_speed = track_speed + (abs_dev * 50);
} else {
// 正常转向:减少速度差,保持较高速度
left_speed = track_speed - (abs_dev * 35);
right_speed = track_speed + (abs_dev * 30);
}
3. 参数优化
针对3cm布条优化的参数:
#define DEFAULT_TRACK_SPEED 180 // 提高基础速度(原120)
#define DEFAULT_TRACK_MAX_SPEED 240 // 提高最大速度(原160)
#define DEFAULT_TRACK_MIN_SPEED 80 // 提高最小速度(原50)
#define DEFAULT_CHECK_INTERVAL_MS 20 // 减少检测间隔(原30ms)
跟随模式算法
跟随模式使用超声波传感器保持安全距离:
if (distance_cm > follow_distance + 5) {
// 距离太远,前进
tb6612_car_forward(base_speed);
} else if (distance_cm < follow_distance - 5) {
// 距离太近,后退
tb6612_car_backward(base_speed);
} else {
// 距离合适,停止
tb6612_car_stop();
}
自由运行模式(避障)
避障算法结合了距离检测和随机转向:
if (distance_cm < obstacle_distance) {
// 检测到障碍物,后退并转向
tb6612_car_backward(base_speed);
vTaskDelay(300 / portTICK_PERIOD_MS);
// 随机选择左转或右转
if (esp_random() % 2 == 0) {
tb6612_car_turn_left(base_speed);
} else {
tb6612_car_turn_right(base_speed);
}
vTaskDelay(500 / portTICK_PERIOD_MS);
} else {
// 无障碍物,继续前进
tb6612_car_forward(base_speed);
}
Web服务实现
HTTP服务器
使用ESP-IDF的HTTP服务器组件实现RESTful API:
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.max_uri_handlers = 15;
config.lru_purge_enable = true;
if (httpd_start(&server, &config) == ESP_OK) {
httpd_register_uri_handler(server, &uri_api_car_control);
httpd_register_uri_handler(server, &uri_api_car_mode);
// ... 其他URI处理器
}
API设计
RESTful风格的API设计:
POST /api/car/control- 手动控制小车GET /api/car/mode- 获取当前模式POST /api/car/mode- 切换模式GET /api/sensors- 获取传感器数据GET /api/info- 获取系统信息
Web界面
使用嵌入式HTML/CSS/JavaScript实现控制界面,支持:
- 实时控制按钮
- 传感器数据可视化
- 模式切换
- WiFi配置
开发经验总结
1. 模块化设计的重要性
通过模块解耦,我们实现了:
- 代码可维护性大幅提升
- 功能模块可独立测试
- 新功能添加变得简单
2. 算法优化需要结合实际硬件
循迹算法的优化必须考虑:
- 传感器实际间距
- 布条宽度
- 小车物理特性
- 实际测试反馈
3. 实时性考虑
- 使用FreeRTOS任务管理
- 合理的任务优先级
- 适当的延迟时间
- 避免阻塞操作
4. 调试技巧
- 使用ESP_LOG进行分级日志
- 串口监控实时数据
- Web界面显示传感器状态
- 分模块测试
性能优化
速度提升
通过算法优化,循迹速度提升了50%:
- 基础速度:120 → 180
- 最大速度:160 → 240
- 响应时间:30ms → 20ms
稳定性提升
- 优化偏差计算算法
- 改进丢失黑线处理
- 增强容错机制
未来扩展方向
- 地图记忆功能: 记录路径并支持回放
- PID控制: 更精确的速度和位置控制
- 图像识别: 添加摄像头实现视觉导航
- 多车协同: 支持多车通信和协同
- 机器学习: 使用TensorFlow Lite实现智能决策
总结
本项目展示了从硬件设计到软件实现的完整开发流程,重点突出了:
- 架构设计: 分层架构和模块解耦
- 算法优化: 针对实际硬件的算法调优
- 工程实践: 代码组织和可维护性
通过这个项目,我们不仅实现了一个功能完整的智能小车,更重要的是掌握了嵌入式系统开发的核心技能和工程实践方法。
项目仓库
本项目已开源,代码仓库地址:
Gitee仓库: https://gitee.com/myliujiuri/esp32-car
仓库包含完整的源代码、文档和示例,欢迎Star和Fork!
快速开始
# 克隆仓库
git clone https://gitee.com/myliujiuri/esp32-car.git
cd esp32-car
# 配置ESP-IDF环境
. $HOME/esp/esp-idf/export.sh
# 编译项目
idf.py build
# 烧录到开发板
idf.py -p /dev/ttyUSB0 flash monitor
项目结构
esp32-car/
├── main/
│ ├── main.c # 主程序入口
│ ├── bsp/ # 硬件抽象层
│ │ ├── tb6612/ # 电机驱动
│ │ ├── line_tracker/ # 循迹传感器
│ │ └── ultrasonic/ # 超声波传感器
│ └── middle/ # 中间件层
│ ├── web/ # Web服务
│ ├── wifi_manage/ # WiFi管理
│ └── car_control/ # 小车控制
├── README.md # 项目说明文档
├── README_CN.md # 中文说明文档
├── BLOG.md # 技术博文
└── CMakeLists.txt # 构建配置
参考资料
关于作者
本项目由嵌入式开发爱好者开发,旨在分享ESP32-S3智能小车的完整开发经验。
项目特点:
- ✅ 完整的硬件设计文档
- ✅ 清晰的软件架构
- ✅ 优化的算法实现
- ✅ 详细的代码注释
- ✅ 完善的开发文档
适用人群:
- 嵌入式开发初学者
- ESP32开发爱好者
- 智能小车项目开发者
- 物联网项目开发者
许可协议: 本项目仅供学习和研究使用。
项目地址: https://gitee.com/myliujiuri/esp32-car
如有问题或建议,欢迎在仓库中提交Issue或Pull Request!
更多推荐




所有评论(0)