元器件 · 控制器
ESP32
ESP32 是一颗内置 Wi-Fi 和蓝牙的高速双核单片机,相当于一块能无线对话的 Arduino。本文讲它能做什么,以及什么时候该选它。
它是什么
ESP32 就像一台装上了无线模块、同时拆掉了刹车的 Arduino。它有一枚双核 32 位处理器,速度比 Uno 快好几个数量级,内存也大得多——而最抢眼的功能是内置 Wi-Fi 和蓝牙。正是这个组合让它统治了入门机器人和物联网:一台机器人可以自己托管一个网页来控制自己,把传感器数据推送到你的手机,或者通过蓝牙接收指令,而这些全靠一颗便宜的芯片完成。
关键在于,你用来编程的仍然是你可能已经熟悉的同一套 Arduino IDE 和同一种语言。你在 Uno 上学到的东西可以直接迁移,你只是额外获得了联网能力和性能余量。
工作原理
核心是两枚 Xtensa CPU,频率最高 240 MHz。拥有双核对机器人很重要:一个核可以以稳定的时序运行你的控制循环,另一个处理 Wi-Fi,于是网络永远不会拖住轮子。CPU 周围是常规的单片机外设——GPIO、PWM 通道、多个 ADC、I²C、SPI、UART——再加上那颗射频芯片。
最要紧的实践事实是电压:ESP32 用的是 3.3 V 逻辑,而不是 Uno 的 5 V。它的引脚不耐 5 V。像 HC-SR04 的 Echo 脚这类 5 V 传感器输出,在接到 ESP32 引脚之前必须降到 3.3 V,否则就有损坏风险。从 Uno 转过来的人几乎都在这里栽过跟头。
什么时候用它
当你的机器人需要无线——遥控、遥测、浏览器控制台——或者需要 8 位板子搞不定的算力,比如处理更多传感器、或者在设备上跑一些轻量逻辑时,就用 ESP32。ESP32-CAM 变体还加了相机,为简单的视觉项目打开了大门。
以下情况请留在 Arduino Uno:你在学基础知识,5 V 容差让接线更安全,或者项目本身简单且不需要联网——让两台电机沿着一条线跑,并不需要 Wi-Fi。
接线与坑
- **3.3 V,不耐 5 V。**5 V 信号进 GPIO 前电平转换。新手烧 ESP32 头号方式。
- **Wi-Fi 加电机板子欠压。**射频电流尖峰陡;弱电源和电机共用复位。电机经电机驱动独立供电,ESP32 稳 3.3 V 轨。
- **不是每个引脚都空闲。**有几个 GPIO 只能输入、与启动行为绑定,或者连着内部 flash。分配引脚前先查引脚图,否则板子根本开不了机。
- **ADC 有怪癖。**两个 ADC 中有一个在 Wi-Fi 激活时不可用,而且读数的线性度不如 Uno——需要精度的话要做标定。
绝不能用的脚
ESP32 大约有 34 个 GPIO,而这个数字确实具有误导性,因为其中相当一部分要么无法使用,要么有条件才能使用,要么一旦占用就会让板子无法启动。下面这张表是接线前唯一值得读的东西。
| 引脚 | 状态 | 原因 |
|---|---|---|
| GPIO 6–11 | 绝不用 | 连内部 SPI flash,用了不开机 |
| GPIO 0 | 启动模式 | 复位 HIGH,不然进烧录模式 |
| GPIO 2 | 启动模式 | 复位悬空或 LOW |
| GPIO 12 | 启动模式 | 复位 LOW——这里上拉板子不开机 |
| GPIO 15 | 启动模式 | 复位时为 HIGH 会让启动日志静默 |
| GPIO 34–39 | 只输入 | 无输出驱动,也无内部上拉 |
| GPIO 1、3 | 串口(TX0/RX0) | USB 烧录器占 |
在标准的 30 针开发板上,最安全的通用引脚是 GPIO 4、5、13、14、16、17、18、19、21、22、23、25、26、27、32、33。从这些开始,就能避开上面所有的坑。
启动模式引脚是最让人困惑的一类故障,因为板子在你接上任何东西之前都工作得好好的。GPIO 12 上的一个上拉电阻——对一个按键来说完全合理——就能让板子根本启动不起来,既没有报错,也没有串口输出。
只输入脚另坑:GPIO 34–39 无内部上下拉,上面按键浮空随机读。要外部电阻。
3.3 V,代价是什么
ESP32 脚不耐 5 V,人们烧它头号方式。5 V 信号都要处理:
| 情况 | 解 |
|---|---|
| 5 V 传感器输出 → ESP32 输入 | 电阻分压(1 kΩ / 2 kΩ)或电平转换 |
| ESP32 输出 → 5 V 设备输入 | 一般没问题——多数 5 V 逻辑把 3.3 V 认作 HIGH |
| 5 V 与 3.3 V 双向 I²C | 正规的双向电平转换芯片(基于 BSS138) |
| 自带 3.3 V 上拉的 5 V I²C 设备 | 常常直连就能用——查清上拉接在哪 |
这种不对称值得牢牢记住:**输出通常是安全的,输入通常不是。**HC-SR04 的 Echo 脚就是典型例子——它把满 5 V 灌进一个绝对最大额定值只有 3.6 V 的引脚。
ADC 问题
ESP32 ADC 芯片最弱环,嘴硬浪费小时。
**Wi-Fi 激活时 ADC2 无法工作。**射频要用它。在 ADC2 引脚上做 analogRead,在 Wi-Fi 连接的瞬间就会返回乱码或者直接阻塞——而无线机器人正是你用 ESP32 的全部理由,所以这几乎把 ADC2 完全排除在外。只用 ADC1:GPIO 32–39。
**响应是非线性的。**12 位 ADC 在两端都明显非线性,低于约 0.1 V 和高于约 3.1 V 的读数会被压缩。芯片里存有出厂标定数据,ESP-IDF 的 esp_adc_cal 函数会替你套用;而 Arduino 的 analogRead 默认并不使用它。
| 衰减 | 可用输入范围 |
|---|---|
ADC_0db |
0–1.1 V |
ADC_2_5db |
0–1.5 V |
ADC_6db |
0–2.2 V |
ADC_11db(默认) |
0–3.3 V,最不线性 |
如果你需要从模拟传感器上得到真正的精度,务实的答案是一块外置 I²C ADC,比如 ADS1115。它要几美元,而且把整个问题一并消除。
不欠压供电
这是 ESP32 机器人项目最常翻车的地方,而原因并不明显。
射频消耗的电流并不平稳——它是以突发方式消耗的。一次发射突发可以在几百微秒内达到 500 mA,而平均值只有 40–80 mA。用万用表量起来没问题的电源,在这些尖峰上照样会发生电压下垂,而 ESP32 的反应是复位并报出 Brownout detector was triggered。
| 规则 | 为什么 |
|---|---|
| 至少供 500 mA,理想是 1 A | 要紧的是峰值而不是平均值 |
| 板子 3.3 V 引脚旁放 100 µF 或更大 | 用本地储能顶住那次突发 |
| 绝不与电机共用一路电源 | 电机启动冲击加上射频突发,保证会复位 |
| 用一根好的 USB 线 | 细线的电阻会把一次突发变成一次欠压 |
| 优先用 5 V 引脚而不是 3.3 V 引脚 | 板载稳压器能处理这些瞬态 |
最后一点要说清楚:**把 5 V 喂到 VIN/5V 引脚,让板上的稳压器生成 3.3 V。**直接灌 3.3 V 会绕过稳压器及其滤波,而这恰恰正是稳压器该做的事。
双核,真用法
双核才是 ESP32 对机器人的真正优势,而 Arduino 框架把它藏了起来——你的 loop() 跑在核 1 上,Wi-Fi 协议栈跑在核 0 上。
任务显式钉核:
void controlLoop(void *param) {
const TickType_t period = pdMS_TO_TICKS(10); // exactly 100 Hz
TickType_t last = xTaskGetTickCount();
for (;;) {
readSensors();
updatePid();
driveMotors();
vTaskDelayUntil(&last, period); // no drift, unlike delay()
}
}
void setup() {
xTaskCreatePinnedToCore(
controlLoop, "control", 4096, nullptr,
2, // priority above the default
nullptr,
1); // core 1 — leave core 0 for Wi-Fi
}
正是这个模式让 ESP32 对机器人而言真的好用,而不只是能联网:一个核跑硬实时的控制循环,另一个核跑网页服务器,却拖不住它。vTaskDelayUntil 是其中的关键细节——它不像 delay(),会补偿循环体实际花掉的时间,因此周期能精确保持 10 ms。
故障排查
| 现象 | 可能原因 | 解决 |
|---|---|---|
Brownout detector was triggered |
射频突发时电源下垂 | 更硬的电源,本地加 100 µF,喂 5 V 而不是 3.3 V |
| 板子完全不开机 | GPIO 0、2 或 12 有东西拽 | 释放启动模式脚 |
Wi-Fi 下 analogRead 返回乱码 |
用到了 ADC2 引脚 | 换到 ADC1:GPIO 32–39 |
| 脚永远不高 | GPIO 34–39 只输入 | 换脚 |
| GPIO 35 按键随机读 | 34–39 无内部上拉 | 加外部电阻 |
| 上传失败要按 BOOT | 山寨自动复位电路缺 | 上传开始按住 BOOT,或 EN 加 10 µF 电容 |
| 带载随机复位 | 共电源轨 | 独立供电,共地 |
| 接线后传感器损坏 | 5 V 进了 3.3 V 引脚 | 做电平转换——并检查引脚是否还正常 |
| 电机一转 Wi-Fi 就掉 | 射频干扰或电源下垂 | 让天线远离电机线;做好去耦 |
ESP32 还是 Arduino Uno?
| Uno | ESP32 | |
|---|---|---|
| 速度 | 16 MHz,8 位 | 最高 240 MHz,双核 32 位 |
| SRAM | 2 KB | 520 KB |
| 逻辑 | 5 V,宽容 | 3.3 V,不宽容 |
| 无线 | 无 | Wi-Fi 和蓝牙 |
| 引脚坑 | 几乎无 | 好几个不开机 |
| 学习曲线 | 上面的一切第一次就能跑通 | 接线前先读引脚图 |
两者用同一种语言和同一套 IDE,这正是重点——这次过渡在代码上几乎不花什么代价,在接线的严谨性上却要付出不少。
诚实的建议是:**在 Uno 上学习,在 ESP32 上造机器。**Uno 的 5 V 容差和完全没有引脚陷阱,意味着你早期的错误都是可以挽回的。等你明白了控制循环是什么、为什么各地必须共地之后,ESP32 就能用差不多的钱,给你十五倍的时钟频率、两百六十倍的内存,外加一颗射频芯片。
ESP32-CAM 变体值得单独了解:它加上了相机和 SD 卡槽,售价只贵几美元,而且以明显的优势成为进入机器人视觉最便宜的路径——代价是几乎不剩什么空闲 GPIO。
探索关联图谱
用到它的搭建
包含 ESP32 的项目、学习路线和模拟器。
对比
替代方案
问题
ESP32 常见问题
ESP32 是什么?
ESP32 是一款低成本的单片机,拥有双核处理器,并内置 Wi-Fi 和蓝牙。你可以把它看作一台快得多、还能通过无线与网络和手机通信的 Arduino,这也是大多数联网机器人和物联网项目都用它的原因。
ESP32 用来做什么?
凡是项目需要无线连接,或者需要 8 位板子给不了的算力,都会用到它:Wi-Fi 遥控机器人、网页控制台、蓝牙遥控、向云端上报数据的传感器节点,以及使用 ESP32-CAM 变体的相机项目。
ESP32 比 Arduino Uno 更好吗?
单看参数,是的——它快得多,内存更大,还带有 Uno 所没有的无线功能。但 Uno 是 5 V 的,对接线错误更宽容;而 ESP32 是 3.3 V 的,容错性更差。学习基础知识时 Uno 更友好;做联网或计算量大的机器人,ESP32 胜出。
Arduino 和 ESP32 有什么区别?
Arduino 通常指一块 8 位、5 V、单核、不带无线电的板子。ESP32 则是一块 32 位、3.3 V、双核的板子,内置 Wi-Fi 和蓝牙。容易混淆的是,两者都用 Arduino IDE 编程,所以“Arduino”既可以指这套语言和工具,也可以指那些经典的开发板。
ESP32 用 C 还是 C++?
ESP32 用 C++(其中也有大量 C 代码)编程,可以使用 Arduino 框架,也可以使用乐鑫(Espressif)自己的 ESP-IDF。如果你写过 Arduino 程序,语言和结构都能直接沿用——你基本上只是多了 Wi-Fi、蓝牙和更多可用的引脚。
能用 Arduino IDE 给 ESP32 编程吗?
可以。在 Arduino IDE 的开发板管理器中添加 ESP32 开发板支持包之后,你就可以像给 Uno 编程一样编写和上传程序,现有的库大多也能直接使用。这是最容易的入门方式,之后再转向 ESP-IDF 来使用高级功能。
延伸阅读