
简介面向ESP32开发者与智能小车入门者这份压缩包提供从零搭建智能小车的完整源码与配套文档解决硬件选型、电路设计、固件编程到无线控制的全流程问题。内容以构建指南为主线覆盖ESP32双核、Wi-Fi/蓝牙特性包含模块匹配、PCB布局、焊接组装及常见故障应对编程部分讲解Arduino IDE与ESP-IDF环境并提供Wi-Fi、蓝牙、TCP/IP通信及传感器数据处理的实现思路。压缩包仅11KB共4个文件以Markdown说明文档和网页版资源为主配合编辑器配置与Git忽略规则便于初学者直接阅读和后续代码管理。已有101人学习。通过该资源可掌握从电路搭建到高级应用的关键步骤并获得图像处理、电源管理、固件更新等进阶优化方向是快速上手ESP32智能小车项目的高性价比参考资料。 玩 ESP32 智能小车最痛苦的不是买零件也不是焊线而是资料东拼西凑代码到处抄最后编译报错一脸懵。我前前后后做了三版小车从最开始的 51 单片机到后来的 STM32最后稳定在 ESP32 方案原因很简单Wi-Fi 和蓝牙都在一颗芯片上省掉一堆外设而且用 Arduino 写起来特别顺手。这篇就把整个构建过程、踩过的坑、以及我最终在用的源码架构一次性讲清楚你照着做大概率能少走一两个月的弯路。这个项目最终完成的小车具备三种玩法手机蓝牙遥控、超声波自动避障、红外循迹行驶。整机成本控制在 150 元以内代码全部开源工程结构清晰拆解下来单个模块的代码量都不大非常适合嵌入式入门玩家、电子设计竞赛备赛学生以及想拿 ROS 2 做硬件底层的开发者当作起步平台。1. 项目整体设计与思路拆解1.1 为什么选 ESP32 而不是 STM32 或 51 单片机很多人一上来就问做智能小车不是应该用 STM32 吗竞赛里清一色都是它。这话没错但要看场景。STM32F103ZET6 这类芯片的优势在于外设资源丰富、生态成熟可如果你只是想快速把小车跑起来而不是深入研究寄存器操作那 ESP32 的性价比就体现出来了。先看芯片本身的差异。ESP32 集成了 2.4GHz Wi-Fi 和蓝牙双模这意味着遥控不再需要外接蓝牙模块或无线收发模块板载解决。而我早期用 STM32 做小车时光是一个 HC-05 蓝牙模块就要二十多块钱还得单独接稳压电路。ESP32 自带 320KB SRAM 和 4MB Flash跑一个 RTOS 系统加几个传感器完全够用主频 240MHz 双核处理四路编码器数据、超声波测距、PID 运算这些任务简直绰绰有余。再说开发门槛。Arduino 框架下的 ESP32 支持度已经非常完善官方维护的 esp32 库函数据我用了三年基本没遇到严重 Bug。相比之下STM32 如果不用 CubeMX 自动生成代码光配置时钟树和 GPIO 就能劝退一批新手。51 单片机就更不用提了做做课程设计还行性能上限摆在那里想扩展个摄像头或者跑个 Micro-ROS基本没戏。1.2 功能模块划分与整体架构我的习惯是先把整个系统按功能拆成独立模块再逐个实现最后组装联调。这个思维模式在做任何嵌入式项目时都适用。整辆小车的逻辑架构分四层感知层超声波传感器负责测距避障红外传感器负责循迹检测两者互不干扰通过 GPIO 读取数据决策层ESP32 主控芯片运行状态机逻辑根据传感器数据判断当前应该直行、转弯还是后退执行层TB6612FNG 电机驱动模块接收 ESP32 的 PWM 信号控制四个 TT 电机的转速和方向交互层手机 APP 通过蓝牙发送指令也可以在调试时通过串口监视器直接查看传感器数据这种分层设计的最大好处是哪一层出了问题直接隔离排查不用推翻重来。比如电机不转了先量执行层的 PWM 信号再查决策层代码逻辑两个小时的活压缩到二十分钟。2. 硬件选型与搭建细节2.1 核心硬件清单与选型理由硬件清单我在下面盘了一下都是实际用过验证过的型号不是纸上谈兵。硬件型号/规格数量参考价备注主控ESP32-DevKitC30引脚125别买 38 引脚的体积大且多数引脚用不上电机驱动TB6612FNG112比 L298N 体积小一半效率高发热低电机TT 减速电机带编码器4204个编码器版本方便后续做 PID 测速小车底盘四驱亚克力底盘130买带铜柱和螺丝包的套装省事超声波HC-SR0414便宜好用测距精度在 2cm-400cm循迹模块TCRT5000 红外传感器393个三路布局比两路更好覆盖黑线电池18650 电池两节 电池盒118电压 7.4V正好驱动电机和给 ESP32 供电稳压模块AMS1117-3.312给 ESP32 提供稳定 3.3V蓝牙ESP32 板载--不需要额外买这里特别要提一下电机驱动的选择。L298N 是很多教程的首选但我强烈建议你用 TB6612FNG。L298N 的压降高达 2-3V意味着 7.4V 的电池组到了电机端只剩 4-5V四驱小车根本跑不快。TB6612FNG 的 MOSFET 导通电阻只有 0.4Ω 左右几乎无压降同样电压下电机转速更高续航也更好。2.2 GPIO 引脚分配与电气接线ESP32 的引脚资源丰富但有些引脚有默认功能不能乱接。比如 GPIO 12 是 MTDI 引脚上电时如果拉高会导致 Flash 电压异常直接进不了下载模式。我踩过这个坑后来固定用下面的分配方案。ESP32 引脚功能连接对象GPIO 14PWM 通道 ATB6612FNG PWMAGPIO 27方向 AIN1TB6612FNG AIN1GPIO 26方向 AIN2TB6612FNG AIN2GPIO 25PWM 通道 BTB6612FNG PWMBGPIO 33方向 BIN1TB6612FNG BIN1GPIO 32方向 BIN2TB6612FNG BIN2GPIO 5超声波 TrigHC-SR04 TrigGPIO 18超声波 EchoHC-SR04 EchoGPIO 19/21/22循迹传感器TCRT5000 数字输出GPIO 16/17编码器 A/B左侧电机编码器后续扩展接线时需要注意TCRT5000 模块是 3.3V-5V 供电都支持但数字输出引脚电平与供电电压一致。如果你给传感器供 5V那输出高电平就是 5V直接接到 ESP32 的 GPIO 上会伤芯片。我的做法是传感器统一供 3.3V虽然红外 LED 的亮度略降但实测 2cm-3cm 的检测距离完全够用。2.3 供电方案双电源 vs 单电源供电是整个小车最容易出问题的地方。我第一版小车就翻车了四个电机一启动ESP32 直接重启后来查了半天是电源跌落导致的。问题根源在于电机启动瞬间的电流冲击。TT 电机堵转电流可以达到 1A 以上四个电机同时启动就是 4A 的瞬时电流别说 AMS1117 扛不住就是 18650 电池组也会有明显的电压跌落。解决方案是采用电源隔离设计电机电源两节 18650 电池7.4V直接给 TB6612FNG 的 VM 供电逻辑电源从电池组引线接 AMS1117-3.3 稳压后给 ESP32 供电共地把电池负极同时接到电机驱动和 ESP32 的 GND保证信号参考电平一致这个方案实测非常稳定即使四个电机急停急转ESP32 的供电电压也稳定在 3.3V 附近。要注意的是AMS1117 的输入输出压差需要至少 1V7.4V 输入降到 3.3V 完全没问题但会有一部分能量以热量形式消耗所以我在 AMS1117 上加了一个小铝散热片效果不错。3. 源码架构与核心代码实现3.1 开发环境搭建Arduino IDE 还是 ESP-IDF做 ESP32 开发主要有两条路Arduino IDE 和乐鑫官方的 ESP-IDF 框架。我的建议很明确如果是初学者或者追求开发效率用 Arduino IDE如果后续要做 Micro-ROS 2 或者需要精细控制硬件资源再切 ESP-IDF 不迟。Arduino 框架下的 ESP32 核心库封装得非常完善模拟输入输出、PWM、I2C、SPI、蓝牙、Wi-Fi 都有现成接口。一个简单的 GPIO 控制代码在 ESP-IDF 里要写几十行结构体配置在 Arduino 里就一行pinMode()。但 Arduino 也有缺点就是隐藏了太多底层细节出了问题不容易排查而且 float 运算效率不如 ESP-IDF 的原生驱动。我目前的习惯是功能验证阶段用 Arduino 快速搭原型产品化阶段再把关键模块迁移到 ESP-IDF。这个策略帮我节省了大量调试时间。安装 ESP32 开发支持时有几个细节容易踩坑。Arduino IDE 的“开发板管理器 URL”需要手动添加乐鑫的 JSON 链接国内网络环境下下载可能很慢建议使用乐鑫国内镜像地址。安装完成后在开发板列表里选择 “ESP32 Dev Module” 即可Flash Mode 一定要选择 “QIO”否则可能出现烧录成功但运行异常的情况。3.2 源码模块划分整个项目的源码我按功能模块拆成了五个文件结构非常清晰esp32_car/ ├── esp32_car.ino // 主逻辑状态机 ├── motor.h/cpp // 电机控制封装 ├── ultrasonic.h/cpp // 超声波测距封装 ├── tracking.h/cpp // 循迹传感器封装 └── bluetooth.h/cpp // 蓝牙指令解析这种分层的好处是每个文件只干一件事出了问题直接打开对应文件排查。比如小车循迹不灵敏你只需要看 tracking 相关的代码不用在动辄几百行的主逻辑里翻来找去。主控制逻辑采用一个简单的状态机方案。状态机是嵌入式开发里非常基础且高效的思想——把复杂的决策过程拆解为有限个状态每个状态下只处理对应的输入信号。我用枚举类型定义了小车的几个运行状态enum CarState { STATE_STOP, STATE_FORWARD, STATE_BACKWARD, STATE_LEFT, STATE_RIGHT, STATE_AVOID };然后设置mode变量来切换运行模式蓝牙遥控、避障、循迹。每种模式下状态机的跳转逻辑都不一样。避障模式下超声波检测到前方障碍物小于 20cm 就进入转弯状态循迹模式下根据三个红外传感器的组合值决定走直线还是修正方向。3.3 电机控制PWM 调速与方向控制电机控制核心就两个点速度用 PWM 调方向用电平组合切。TB6612FNG 的控制逻辑其实很简单每个通道有三个控制引脚PWMA 负责调速AIN1 和 AIN2 负责方向。电机方向控制真值表如下AIN1AIN2PWMA电机状态HIGHLOWPWM正转速度由 PWM 决定LOWHIGHPWM反转LOWLOW任意停止刹车HIGHHIGH任意停止惰性有了这个表写代码就非常容易了。下面是电机控制的封装函数void motor_left_set(int speed, bool forward) { digitalWrite(PIN_AIN1, forward ? HIGH : LOW); digitalWrite(PIN_AIN2, forward ? LOW : HIGH); ledcWrite(PWM_CHANNEL_LEFT, map(speed, 0, 100, 0, 255)); }这里用ledcWrite而不是 Arduino 原生的analogWrite是因为 ESP32 的 Arduino 核心并没有完整实现analogWrite用了也是基于ledc的封装而且指定的引脚通道不同。我在初始化里配置了 PWM 通道参数ledcSetup(PWM_CHANNEL_LEFT, 1000, 8); // 频率 1kHz分辨率 8 位 ledcAttachPin(PIN_PWMA, PWM_CHANNEL_LEFT);PWM 频率我选了 1kHz这个值对 TT 电机的刷式换向器来说是很合适的。频率太低比如 100Hz电机会有明显噪音和抖动频率太高比如 50kHz则会因为电机线圈电感的滤波作用导致实际电流很小扭矩不足。10kHz-20kHz 之间是听不见噪音的常见选择但 1kHz 在实际调试中已经够用且好观察。3.4 超声波避障与循迹实现超声波测距的原理很简单Trig 引脚拉高 10us模块自动发射 8 个 40kHz 的脉冲Echo 引脚输出高电平高电平的持续时间就是声波往返的时间。距离等于时间乘以声速340m/s再除以 2。float ultrasonic_read() { digitalWrite(PIN_TRIG, LOW); delayMicroseconds(2); digitalWrite(PIN_TRIG, HIGH); delayMicroseconds(10); digitalWrite(PIN_TRIG, LOW); long duration pulseIn(PIN_ECHO, HIGH, 30000); // 超时 30ms return duration * 0.034 / 2; }加超时参数很重要因为如果超声波前方没有遮挡物Echo 引脚会一直保持高电平pulseIn会阻塞程序执行。我设定 30ms 超时对应最大测距距离约为 5m超出就返回 0让上层逻辑当作无障碍处理这样就不会卡死。循迹部分就更直接了。TCRT5000 是一个红外反射传感器当它对准黑色跑道线时红外光被黑线吸收输出高电平当它偏离到白色地面时红外光被反射回来输出低电平。三个传感器并排安装在小车底盘前方形成一个简单的检测阵列就能判断小车相对黑线的位置状态。int tracking_read() { int s1 digitalRead(PIN_TRACK_LEFT); int s2 digitalRead(PIN_TRACK_MIDDLE); int s3 digitalRead(PIN_TRACK_RIGHT); return (s1 2) | (s2 1) | s3; }三个传感器返回的二进制组合对应不同的循迹动作传感器值组合中如果只有中间传感器检测到黑线说明小车正直前行如果左边或右边的传感器偏了就分别向左或向右修正。判断逻辑在状态机里统一处理这样代码就不零散。3.5 蓝牙遥控与手机 APP 对接蓝牙遥控这块ESP32 双模蓝牙支持经典蓝牙Bluetooth Classic和低功耗蓝牙BLE。APP 遥控我用的是经典蓝牙因为它支持 SPP 串口透传协议手机连接后虚拟出一个串口收发数据就像串口一样简单。在 Arduino 框架下使用经典蓝牙核心就几行代码#include BluetoothSerial.h BluetoothSerial SerialBT; void setup() { SerialBT.begin(ESP32_Car); // 蓝牙设备名称手机可搜索到 } void loop() { if (SerialBT.available()) { char cmd SerialBT.read(); handle_command(cmd); } }关键是设计一套简洁的指令协议。我自定义的协议是单字符指令简单高效指令含义F前进B后退L左转R右转S停止A切换避障模式T切换循迹模式H切换手动遥控模式为什么要用单字符因为嵌入式设备的内存和带宽都有限协议越简单越可靠。你当然可以用 JSON 格式传指令但解析 JSON 在 ESP32 上要额外引入库占用资源还容易出错。单字符协议在串口监视器里调试也直观一看就知道发的是什么。手机 APP 端我用一个开源的蓝牙串口调试工具也可以用 Arduino IDE 自带的串口监视器配合调试。APP 里设置一个方向按键面板四个方向键加一个停止键按下时发送对应字符松开时发送停止指令。这里有一个从实际调试中总结的经验按键按下立即发指令松开后不要马上发停止指令而是延迟 100ms 再发。否则电机会频繁启停电流冲击很大容易触发保护。4. 联调流程与功能验证4.1 先分模块测试再整机联调我犯过最蠢的错误就是所有模块焊接完之后直接上代码结果小车纹丝不动查了一下午才发现是电机驱动的两个接口线序接反了。从那以后我坚持一个基本原则模块先单独测试确认无误再整机联调。具体的测试顺序如下电源板测试焊好电源模块后先用万用表量输出是否稳定在 3.3V 和 5V。这一步非常关键如果这一步电压不对后续所有测试都是白搭甚至会烧毁传感器。电机测试单独写一个测试代码让四个电机依次正转、反转、停止确认每个电机的方向控制逻辑都正常。同时用记号笔在每个电机上做个方向标记方便后续组装的轮向判断。传感器测试超声波模块可以通过串口打印当前测距值用手在传感器前方移动观察数值是否线性变化。循迹模块则可以在白纸上放一段黑色胶带看串口输出是否在黑线上方产生跳变。蓝牙通信测试手机连接 ESP32 的蓝牙发送各指令字符观察串口输出是否收到正确的指令数据。整机联调所有模块单独确认无误后再合并到主代码里做整机测试。先地板擦干净放好黑线然后一个小功能一个小功能地验证。这个过程看起来繁琐但实际上是帮我节省了大量时间。每个模块单独出问题时排错范围很小基本看一眼串口输出就能定位。整机联调如果出问题哪哪都像嫌疑犯排查效率低到令人崩溃。4.2 四种模式的切换测试联调完成后我在不同场景下对四种模式做了验证测试这里把测试记录整理出来供你参考对照。手动遥控模式是最基本的测试时主要观察几个指标手机的连接是否稳定、指令响应是否及时、电机转向是否和按键方向一致。实测下来ESP32 蓝牙的连接稳定性不错在无障碍物的情况下直线距离 10 米内都能稳定控制。这里有个小坑如果你同时开了 Wi-Fi 和蓝牙两者共用 2.4GHz 频段会导致蓝牙响应变慢我通常测试时直接关掉 Wi-Fi。避障模式的测试场景是客厅我用纸箱摆了一个简单的障碍物布局。小车的逻辑是直行遇到障碍物停车测距判断是向左还是向右转避开然后继续直行。这里有一个需要调优的细节转弯角度如果固定小车在被障碍物围住的“死胡同”里可能会来回打转。我的做法是引入一个“连续转向”计数如果连续三次转向都在同一个方向就大幅增加转向角度让小车有更大的机动空间。循迹模式的测试在地上贴了两条黑线胶带一条直线和一条 S 弯。直线循迹基本没有悬念S 弯是对 PID 参数的考验。我一开始用固定速度直行结果在 S 弯的弯心处小车冲出去线了。后来把弯道的线速度降到了直道的 60%效果立竿见影。4.3 关键参数调优记录下面是几个我在调试过程中记录的关键参数供大家参考参数名初始值调优后说明直行 PWM 占空比50%40%四驱车空载时速度太快循迹易冲出线转弯 PWM 占空比50%35%转弯速度过高容易甩尾避障触发距离30cm20cm30cm 触发太早频繁转向行动效率低循迹传感器阈值无中值 800用模拟量读取判断阈值更可靠蓝牙响应延时无停止延迟 100ms防止电机瞬间刹车导致过流循迹传感器的阈值调优让我折腾了一晚上。TCRT5000 的数字输出在阈值附近会产生抖动导致传感器状态频繁跳变。我的解决方案是把传感器切到模拟量读取模式在串口监视器里观察黑线和白地的模拟值差异取两者的中间值作为判断阈值。这样比直接用数字输出稳定得多特别是环境光线变化的情况下。5. 常见问题与排查技巧实录5.1 烧录失败与驱动问题ESP32 烧录失败是新手遇到最多的问题表现是编译成功但上传时串口一直报 “Connecting...”然后超时失败。我遇到这个问题的排查路径是检查串口驱动ESP32 开发板用的串口芯片通常是 CP2102 或 CH340需要安装对应驱动。Windows 系统一般会自动安装但需要确认设备管理器里是否识别到 COM 口。按住 BOOT 键上传如果驱动没问题按住开发板上的 BOOT 键不放再点上传等出现 “Connecting” 时松手。这是因为 ESP32 的上电时序偶尔会异常进入不了下载模式手动按 BOOT 可以强制进入。检查数据线这个问题非常隐蔽。很多 USB 线只有充电功能没有数据线芯特别是那种细的白色安卓线。换一根短的、品牌靠谱的数据线能解决 80% 的烧录问题。烧录成功后还有一个经常被忽略的坑上传代码后没有任何反应。这时候在串口监视器里看输出如果卡在乱码或者没有任何输出尝试按下开发板的 EN 复位键大概率就能恢复。5.2 电机抖动与小车跑偏小车通电后电机抖动、转速不均匀甚至伴随异常电流声这个问题我排查过很多次最终归因到三个可能最普遍的原因是电池电压不足。刚买来的 18650 电池可能没有充满电四个电机同时启动时电压被拉低到电机驱动芯片的最小工作电压以下导致 PWM 信号不稳定。解决方法是先充满电再测试并且不要吝啬电池的放电能力参数建议买容量 2500mAh 以上的动力型 18650。其次是共地问题。驱动板和主控板之间如果没有连接 GND控制信号就会因为参考电位不一致而失效表现为电机动作异常、传感器数据漂移。我的接线规范是所有模块的 GND 全部拧到一起形成一个星型接地结构。最后是 PWM 频率不匹配。我之前用模拟输出口直接驱动电机TT 电机内部的减速齿轮结构在低转速段天然存在力矩波动如果 PWM 频率又正好落在机械共振区间抖动就会特别严重。可以试着把 PWM 频率调高或者调低一个量级比如从 1kHz 调到 500Hz看抖动是否改善。跑偏问题就更常见了尤其是四驱小车。四个电机的转速不可能完全一致即使给定相同的 PWM 占空比由于电机内部绕组、碳刷和机械齿轮的差异实际转速也会有 5%-10% 的偏差。早期方案里我直接用开环控制跑着跑着就歪了。解决办法有两个层级的简单方案在代码里给慢速的电机加上补偿值比如左侧电机 PWM 设为 40%右侧设为 36%反复调直到小车能走直线进阶方案利用编码器测速跑一个闭环 PID 调速算法把四个电机的实际转速都锁定到目标值附近如果要做竞赛项目或者对线的准确性有很高要求强烈建议直接上 PID 方案开环补偿只能保证当前电池电压下的直线度电池电量下降后参数又要重调。5.3 传感器误触发与数据漂移超声波传感器在电机同时工作时经常出现数据跳变原因有两个。第一是电源干扰。电机产生的电磁噪声会通过共地回路耦合到超声波模块的供电线上导致测距值偶尔跳变。我在模块供电输入端加了一个 10uF 电解电容和一个 0.1uF 陶瓷电容做滤波问题就改善了一大半。第二是壁面反射和斜射误差。超声波束是一个锥形区域如果探测目标是一个斜面或者墙角回波会被反射到其他地方导致测不出来或者数据偏大。处理办法是对测量数据做中值滤波——连续读五次取中间值作为有效数据可以有效消除单次大概率错数据。循迹传感器对环境光非常敏感。太阳光中的红外成分有一定概率直接触发传感器导致它在明亮环境下误判。我一般给传感器加上一个遮光罩黑色热缩管或者电工胶带把环境光线挡掉只让地面反射光进入传感器。5.4 蓝牙连接不稳定与串口调试技巧蓝牙连接不稳定容易出现连接后又断开、或者指令延迟严重的情况。我的排查结论是ESP32 的蓝牙和 Wi-Fi 同时启用时两者在 2.4GHz 频段互相干扰尤其是在 Wi-Fi 传输数据量大的时候蓝牙的时延会明显升高。如果你只做遥控不打算联网那就在代码里把 Wi-Fi 彻底停掉#include nvs_flash.h nvs_flash_erase(); nvs_flash_init(); esp_wifi_deinit();实测关闭 Wi-Fi 后蓝牙连接稳定性和响应速度都有明显提升。还有一个调试技巧在代码里大量使用Serial.println()输出调试信息然后通过 USB 串口监视器观察。但要注意一旦连接了手机蓝牙蓝牙和 USB 串口会共用同一个 UART两个都开的时候数据会在两个方向来回串导致串口监视器输出混乱。我的做法是调试蓝牙指令时断开 USB 连接直接通过手机 APP 发指令然后把 ESP32 的日志输出到另一个 GPIO 映射的串口上。6. 源码获取与后续扩展方向源码组织方式刚才说过了这里补充几个核心逻辑的细节。主循环里我用了一个简单的switch-case来处理不同模式下的状态机结构清晰方便扩展新的传感器和执行器。void loop() { switch (mode) { case MODE_REMOTE: handle_remote_command(); break; case MODE_AVOID: handle_avoid_mode(); break; case MODE_TRACK: handle_track_mode(); break; default: car_stop(); break; } }每个handle_xxx函数内部再根据传感器输入执行对应的状态跳转。这套代码的总量不大全部加起来也就三四百行很适合作为学习素材。在实现时我尽量保持了代码的可读性变量命名都是完整单词关键逻辑段有中文注释你拿到手之后直接烧录就能跑。6.1 从 Arduino 到 Micro-ROS走上机器人系统开发之路如果你在完成基础功能后想把小车接入 ROS 2 系统就可以进一步了解 micro-ROS 在 ESP32 上的移植和应用。这正好是近几年机器人开发的一个热点方向。Micro-ROS 是一个在 MCU 上运行的 ROS 2 客户端它通过串口或 Wi-Fi 与上位机比如树莓派或装有 ROS 2 Humble 的 PC通信。在 ESP32 上跑 Micro-ROS等于把你的小车变成了一个真正的分布式机器人节点传感器数据可以发到 ROS 2 的 Topic 里控制指令也可以从 ROS 2 的节点发下来。移植 micro-ROS 到 ESP32 需要用到乐鑫的micro_ros_espidf_component组件库。大致步骤是先安装 ESP-IDF 环境然后克隆 micro-ROS 的 ESP32 组件库到工程的 components 目录在 menuconfig 里根据你的板子性能选择合适的传输方式和内存配置编译烧录即可。Wi-Fi 通信模式下ESP32 作为 UDP 客户端连接上位机的 micro-ROS Agent串口模式下则通过物理串口连接稳定性和实时性更高是机器人竞赛中更常用的方式。6.2 项目扩展的四个方向项目跑通之后你会发现自己对 ESP32 和外设的控制方式都有了比较全面的理解。这时候可以往下面几个方向扩展视觉识别方向给小车加一个摄像头模块比如 ESP32-CAM 作为独立视觉节点通过 Wi-Fi 传输图像到上位机在 OpenCV 里做目标检测和巡线。这样一来就不只局限在红外循迹了。高精度定位方向给底盘加装霍尔编码器并融合 MPU6050 六轴陀螺仪配合 PID 闭环就能实现走直线不跑偏再往下做可以完成简单的轨迹规划这也是很多工业物流小车方案的简化版。语音交互方向在手机 APP 端集成语音识别把识别出的文本转成蓝牙指令比如“前进”“左转”这些指令车就能听懂人话。这也算是个比较讨巧的炫酷功能。多机协作方向用两块 ESP32 分别控制两台小车通过两个开发板上的 Wi-Fi 建立 TCP 通信实现一主一从的编队控制。这个方向的扩展比较有挑战性适合作为毕设或竞赛课题。顺便提一句如果你手边只有 STM32F103ZET6 或树莓派这套思路也可以直接平移。STM32 需要外接蓝牙和 Wi-Fi 模块代码上用 HAL 库重写一遍树莓派则可以直接用 Python 的gpiozero库或者 ROS 2 的驱动包逻辑一模一样区别主要在于底层 API 不同。6.3 最后分享三个实操心得从我做了三版小车、前后折腾了两个多月的经验来看有三件事对你可能最有帮助。第一第一次做小车一定要选择成熟的方案而不是追求配置堆料。我见过太多人一开始就想要机械臂、摄像头、激光雷达全加上结果项目进行到一半连轮子都转不起来。先把基础版跑通建立信心和手感再去逐项加功能这个节奏是最舒服的。第二把调试接口留足。我的每一版小车都保留了一个串口调试接口和一个状态 LED 灯。遇到问题时串口打日志、LED 看状态信息越丰富定位越快速。有人觉得这些冗余设计浪费时间等真正出问题的夜晚你才知道它们是你最忠实的朋友。第三选择一个由浅入深的项目路线。如果你的目标是参加竞赛直接参考近期工创赛智能物流小车的题目这类比赛大多数以视觉识别、色块抓取、物品搬运为主底层底盘和电机控制就是今天这套 ESP32 平台的变体。提前把底盘稳了比赛时就有了底牌。如果是课程设计加一路循迹加避障就足够拿高分剩余的精力用来把代码注释和报告写好反而更容易出彩。我这套小车源码已经在文末给出了完整工程包含了硬件的接线图、Arduino 版的全部源码以及规避的一堆坑。照着做一个周末的时间你就能看到自己的小车在地板上撒欢跑了。本文还有配套的精品资源点击获取