开始之前
第 2 课:环境配置(Arduino CLI + AI 辅助路线)
用 AI 带着你自动装好 Arduino CLI 和 ESP32 开发环境,避开 C3 的串口坑,最后用 Blink 点亮板载 LED。
环境配置:Arduino CLI + AI 辅助路线
这节课有点长,但值得
我是吴老师。上一条路我们用积木把灯点亮了,这一条路,我们把灯点亮的同时,还要把"为什么"搞明白。
先说清楚一件事:这节课比图形化那节长,中间可能会卡。我提前把话说在这儿——卡住是正常的,不是你笨,也不是你电脑有问题。装嵌入式环境这事儿,全世界的人都卡。区别只在于:有人卡住了就放弃了,有人卡住了知道该查哪一步。这节课我主要教你的,就是"该查哪一步"。
好消息是,你现在有 AI 帮忙。以前装环境是纯手工活,报错了只能去论坛翻帖子;现在 AI 能直接读你的报错、直接敲命令、直接帮你定位。 这就是为什么我不用 Arduino IDE,而是用 Arduino CLI——下面第一节就讲这个。
一、为什么用 Arduino CLI,不用 Arduino IDE
我知道你听过 Arduino IDE。图形界面,点两下就能烧程序,看着挺友好。那为什么不推荐?
因为IDE 是一扇关着的门,CLI 是一扇开着的门。
| Arduino IDE | Arduino CLI | |
|---|---|---|
| 交互方式 | 鼠标点按钮 | 敲命令 |
| AI 能不能帮你操作 | 不能。AI 看不见你的窗口,也点不了你的按钮 | 能。AI 可以直接执行命令、读输出、判断结果 |
| 出错时的信息 | 弹窗、红字,你还得自己描述给 AI 听 | 全是文本,AI 能直接读懂并定位 |
| 能不能重复 | 每次都要手动点一遍 | 一条命令,写一次跑一百次 |
| 能不能写成脚本 | 基本不能 | 天生就是干这个的 |
| 装环境 | 手动在菜单里翻,一层套一层 | 三条命令装完 |
关键就在第一行对比。AI 没法帮你点鼠标,但 AI 能帮你敲命令。 你选 IDE,就等于把 AI 这个最强助手关在门外了;你选 CLI,AI 就能全程陪着你,从装环境一路陪到烧录排错。
另外三个理由,说给你听:
- 可脚本化。 你要给 30 个学生装同样的环境?CLI 写个脚本,一次搞定;IDE 就一个一个点吧。
- 可复现。 命令是白纸黑字写下来的,我发的命令你照着敲,结果一模一样。IDE 里"点哪个菜单"这种描述,换个版本就失效了。
- 输出是文本。 编译报错、烧录日志、串口输出,全是纯文本。文本 AI 读起来毫无障碍——这意味着你遇到问题不用费劲描述,直接把输出丢给 AI 就行。
一句话:IDE 是给人操作的,CLI 是给人和 AI 一起操作的。 我们这套课有 AI,所以选 CLI。
二、动手之前,先认你的板子和线
别急着敲命令。环境配置失败的原因,一半不在软件,在硬件。先花三分钟把这三件事确认了,能省你一个下午。
1. 那根线,是不是数据线
你套件里那根 Type-C 线,我在材料清单里特意标了**"需支持数据传输"**,不是凑字数的。
市面上大量的 Type-C 线是纯充电线——里面只有供电的两根芯(VBUS 和 GND),根本没有传数据的那两根(D+ 和 D-)。
插上这种线会发生什么?板子上的电源灯亮得好好的,电脑却怎么都找不到串口。 你会以为是驱动问题、是板子坏了、是软件装错了,折腾一下午,其实就换根线的事。
这个坑太经典了,我专门教你怎么用万用表验它:
- 万用表打到通断档(就是那个会"嘀"的档位,图标像个声波)。
- 先短接两支表笔,确认表响了。这一步不能省——表笔断了或者档位打错了,测什么都是不通,你会得出错误结论。
- 一支表笔点线的一头,另一支点另一头对应的触点,测 GND 是否导通(应该响)。
- 再测 D+ 和 D- 是否导通。
第 4 步就是分水岭:GND 响、D+ 或 D- 不响 → 这就是一根纯充电线,换掉它。 别犹豫,也别可惜,它对你没有任何用处。
图省事的话还有个土办法:拿一根你平时给手机传文件用的线,那种线一定是数据线。
2. 板子上那两个小按键
拿到板子,翻到正面,你会看到一到两个小小的贴片按键。它们大概率是这两个:
- BOOT 键:管"进入下载模式"的。烧录不进去的时候,就得靠它。
- EN / RESET 键:管"复位重启"的。
有些小板子(尤其是那种很小的 C3)只有一个 BOOT 键,没有复位键。 没关系,后面的操作照样能做,我会写两种手法。
现在你只需要做一件事:用手摸一遍,记住它们在哪、哪个是哪个。 一会儿卡住了你会感谢现在的自己。
3. 板子上有没有那颗"转接芯片"
这一步是给后面那个最大的坑做铺垫。
把板子翻到背面,看看 Type-C 口旁边,有没有一颗小小的黑色方形芯片(比指甲盖还小)。有两种情况:
- 有这颗芯片:说明板子用了一颗"USB 转串口"芯片(常见型号 CH340、CH343、CP2102)。这颗芯片负责把电脑的 USB 信号翻译成主控能懂的串口信号。
- 没有这颗芯片:说明这块板子是 Type-C 直连主控的,靠 ESP32-C3 芯片自己内置的 USB 功能来跟电脑通信(这块 C3 内置了 USB Serial/JTAG)。
记住你是哪一种,第三节讲坑的时候要用。 判断不出来也没关系——插上电脑看设备管理器,后面会讲怎么分辨。
三、装 Arduino CLI
下面是正式操作。我按 Windows 11 给你写。
方式 A:winget(我推荐这个)
Windows 11 自带 winget。打开PowerShell或者终端,敲:
winget install --id ArduinoSA.CLI --exact装完之后,把终端窗口关掉,重新开一个——这一步很多人漏掉,导致敲 arduino-cli 提示"找不到命令",然后以为装失败了。其实只是当前窗口还没读到新的 PATH。
重新开窗口后验证:
arduino-cli version看到类似 arduino-cli Version: 1.x.x ... 就成功了。
方式 B:MSI 安装包
不想用 winget,就去下载官方 MSI:
https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Windows_64bit.msi下载完双击装,一路下一步。装完同样重开终端,再验证。
方式 C:手动解压 ZIP(需要自己配 PATH)
下载这个 ZIP:
https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Windows_64bit.zip解压到哪儿?别乱放。 我给你两条硬规矩:
- 路径必须是纯英文、不能有空格。 别放在"桌面"、别放在"我的文档"、别放在带中文的文件夹里。中文路径会让后面的编译和烧录出各种莫名其妙的错,而且报错信息完全看不出是路径的锅——这是最恶心的一类问题。
- 建议路径:
C:\arduino-cli\(全局,所有用户可用),或者C:\Users\你的用户名\arduino-cli\(只给当前用户,不需要管理员权限)。
解压完,C:\arduino-cli\arduino-cli.exe 应该存在。
配 PATH
用 PowerShell 永久添加(注意别用 setx,它会在 1024 字符处截断,还有可能把你的 PATH 整个覆盖掉,是个坑爹命令):
$old = [Environment]::GetEnvironmentVariable('Path', 'User')
[Environment]::SetEnvironmentVariable('Path', $old + ';C:\arduino-cli', 'User')改完必须重开终端才生效。
如果只想在当前 Git Bash 窗口临时用一下,可以这样:
export PATH="$PATH:/c/arduino-cli"Git Bash 和 PowerShell 的差异,我说清楚
你用的是 Git Bash,这里有几个地方跟 PowerShell 不一样,不知道的话会踩坑:
| 事情 | Git Bash | PowerShell |
|---|---|---|
| 路径写法 | /c/arduino-cli |
C:\arduino-cli |
| 临时加 PATH | export PATH="$PATH:/c/arduino-cli" |
$env:Path += ';C:\arduino-cli' |
| 永久加 PATH | 改 ~/.bashrc |
[Environment]::SetEnvironmentVariable(...) |
| 下载文件 | curl -L -o x.zip URL |
curl.exe(PowerShell 里的 curl 是 Invoke-WebRequest 的别名,参数完全不一样,直接写 curl 会报错) |
| 搜索输出 | arduino-cli board listall | grep -i c3 |
arduino-cli board listall | Select-String c3 |
| 串口名 | COM3 直接写就行 |
COM3 |
关于串口名:在 Git Bash 里有时候需要用 /dev/ttyS3 这种写法来指代 COM3。大多数情况下直接写 COM3 就行,如果报"端口不存在",换成 /dev/ttyS2 这种写法试一下(COM3 对应 ttyS2,也就是串口号减一)。这是 Git Bash 的历史遗留问题,不是你操作错了。
数据目录在哪
arduino-cli 下载的开发板支持包、编译工具链,默认都放在:
C:\Users\你的用户名\AppData\Local\Arduino15\这个目录会涨到 1~2 GB。 C 盘紧张的同学心里有个数,回头清理或者装之前先留出空间。
四、装 ESP32 支持包(两条路,选一条)
Arduino CLI 本身只是个空壳,它不知道 ESP32 是什么。我们要告诉它:去哪儿找 ESP32 的开发板支持。
这一步是整节课最容易卡住的地方,因为要下载几百 MB。我给你两条路:
| 方式一:在线装 | 方式二:离线包 | |
|---|---|---|
| 适合 | 网速还行 | 装不动、反复失败、要离线教学 |
| 体积 | 下载约 400MB | 下载约 1.8GB |
| 时间 | 看网速,可能很久 | 下载慢,但装是一次性的 |
| 从哪拿 | 直接命令行装 | 百度网盘 |
先试方式一。 卡住了、反复失败,再上方式二。方式二虽然文件大,但一次到位,不用管网络。
方式一:在线装(用国内镜像)
第 1 步:生成配置文件
arduino-cli config init这会在 Arduino15 目录下生成 arduino-cli.yaml。看看它长什么样:
arduino-cli config dump第 2 步:加开发板索引地址
这一步是关键,加错了后面会慢到你想砸电脑。
arduino-cli config add board_manager.additional_urls https://jihulab.com/esp-mirror/espressif/arduino-esp32/-/raw/gh-pages/package_esp32_index_cn.json注意我加的是国内镜像,不是官方地址。 这里必须解释一下为什么,因为它直接决定你后面的体验:
官方索引
espressif.github.io只是个"目录",它本身能访问。但它里面记的每一条下载地址都指向github.com——而 GitHub 在国内是出了名的不稳定。国内镜像索引
package_esp32_index_cn.json不一样:它里面 1000 多条下载地址全部指向dl.espressif.cn(乐鑫自己的国内 CDN)。同样的包,走国内 CDN 可能几分钟就下完,走 GitHub 可能一个下午都下不动。我实测过这个镜像,本机这套环境就是用它装的。
两个地址二选一,千万别同时加。 它们指的是同一个 esp32:esp32 平台,同时加会让 arduino-cli 犯迷糊,出现"平台已安装但版本对不上"这类怪问题。
如果你之前手滑加过官方地址,先删掉:
arduino-cli config remove board_manager.additional_urls https://espressif.github.io/arduino-esp32/package_esp32_index.json第 3 步:更新索引
arduino-cli core update-index把"有哪些开发板、哪些版本"的清单拉下来。要联网,等一两分钟。
第 4 步:安装 ESP32 核心
arduino-cli core install esp32:esp32这一步最慢,要下整套编译工具链(交叉编译器,几百 MB)。泡杯茶。
中途看着不动了别急着 Ctrl+C——它在下大文件,进度条经常卡着不动。Ctrl+C 打断会留下不完整的文件,下次装还得重来。
装完确认:
arduino-cli core list列表里能看到 esp32:esp32 这一行就成了。
方式二:离线包(装不动就用这个)
这条路我不推荐你一开始就走,但它是最后的保障。
什么时候用
- 方式一试了好几次,每次都下到一半失败
- 你要在没有网的地方教学(机房、比赛现场)
- 你不想每次都等下载
要下什么
一个约 1.8GB 的离线开发包,在百度网盘上:
https://pan.baidu.com/share/init?surl=BlzEhW6F85fYG9sU3Cd0Xg
提取码:8888为什么单独放网盘? 因为 1.8GB 太大了,没法塞在课程里直接给你。
另外:百度网盘不开会员下载会很慢,这是它的商业模式,不是文件有问题。如果你有别的网盘,也可以问问吴老师有没有备用地址。
里面是什么
这个包不是只有 ESP32 核心,而是一整个配置好的编译环境:
| 内容 | 干什么的 |
|---|---|
ESP32 核心(3.3.10-cn) |
开发板支持包本体 |
| 全套工具链 | RISC-V 编译器、C3 专用库、烧录工具 |
| 库索引 | 装第三方库时的目录,省得再联网拉 |
关键是"工具链"那几项。 没有它,你只能写代码不能编译——而它就是在线安装时最慢、最容易失败的那几百 MB。装上它,编译就完全不需要网了。
怎么装
一句话:把包里那个 Arduino15 文件夹,整个放到指定位置。
- 解压下载好的包,你会看到一个叫
Arduino15的文件夹 - 找到你的目标位置(在资源管理器地址栏敲这个,回车):
一般是纯文本 %LOCALAPPDATA%C:\Users\你的用户名\AppData\Local\ - 把
Arduino15整个放进去,和已有内容合并
如果那个位置已经有
Arduino15了怎么办?先重命名成
Arduino15_备份(别直接删,万一要退回去)。然后再把新的放进去。因为离线包里的版本是
3.3.10-cn,如果你之前装过别的版本,混在一起会出现"平台已安装但版本对不上"的问题。
- 验证:
看到Shell arduino-cli core listesp32:esp32 3.3.10-cn就成了。
本机现在用的就是这个版本。 所以课里后面所有命令,跟我这里的结果能对上。
五、找到 ESP32-C3 的"身份证"
不管走哪条路装好的,到这一步都一样。
在 arduino-cli 里,每块板子都有一个编号,叫 FQBN(Fully Qualified Board Name)。后面编译烧录都要用它。
arduino-cli board listall | grep -i esp32c3PowerShell 里用 Select-String:
arduino-cli board listall | Select-String esp32c3我们要的是这个:
esp32:esp32:esp32c3把它抄下来,贴在你笔记里。 记不住没关系,但别记错——写成 esp32:esp32:esp32(那是通用 ESP32,不是 C3)就等着看板子装死吧。
六、装几个常用库
库就是别人写好的功能包。我们要用的:
arduino-cli lib install "Adafruit GFX Library"
arduino-cli lib install "Adafruit SSD1306"
arduino-cli lib install "DHT sensor library"
arduino-cli lib install "Adafruit Unified Sensor"说明一下这几个是干嘛的:
| 库 | 干什么用 |
|---|---|
| Adafruit GFX Library | 图形显示的地基,画点、画线、画字 |
| Adafruit SSD1306 | OLED 屏的驱动,配合上面那个用 |
| DHT sensor library | 读温湿度传感器的 |
| Adafruit Unified Sensor | 上面那个 DHT 库的依赖,不装会编译报错 |
为什么现在就把这些装上? 因为这些库的下载和安装,也是要联网、也可能出错的。与其等到上 OLED 那一节课手忙脚乱,不如现在一次性把地基打平。
装完检查:
arduino-cli lib list再说个小技巧:不确定库的准确名字时,先搜:
arduino-cli lib search SSD1306搜出来的名字要原样用引号包着装进去,名字差一个字母都装不上。
七、ESP32-C3 的坑(这一节最重要)
好,环境装完了。但装完不等于能用。ESP32-C3 有几处特别的坑,不知道的话你会以为环境装错了,然后从头再装一遍——白折腾。
我把这些年被这些坑坑过的经验,一条一条交给你。
坑 1:串口一片空白——USB CDC On Boot
这是 C3 上最常见、最气人的一个问题。 症状是:程序烧录显示成功,板子也在跑,但你打开串口监视器,一片空白,一个字都没有。
我先讲讲为什么会这样。
ESP32-C3 芯片上有两套能往外"说话"的通道:
- UART0:一根传统的串口,走
GPIO20(RX)和GPIO21(TX)。 - USB Serial/JTAG:芯片内置的 USB 功能,直接走
GPIO18(D-)和GPIO19(D+),也就是你那个 Type-C 口。
现在问题来了:你写的代码里 Serial 这个词,到底走哪条通道?
这是编译时决定的,由一个叫 CDCOnBoot 的选项控制:
CDCOnBoot=default(默认,关闭)→Serial走 UART0(GPIO20/GPIO21)。CDCOnBoot=cdc(打开)→Serial走 USB(GPIO18/GPIO19,即 Type-C 口)。
于是两种板子会出现两种完全相反的症状:
情况 A:你的板子是 Type-C 直连主控(没有转接芯片)。
Type-C 口连的是芯片的 USB 引脚。如果你保持默认(CDCOnBoot=default),Serial 就往 UART0 发数据——而 UART0 那两根脚根本没接到 Type-C 口上,悬空着呢。数据发到空气里去了。所以你看到的就是:烧录成功,串口空白。
→ 解法:给 FQBN 加上 :CDCOnBoot=cdc。
情况 B:你的板子上有转接芯片(CH340 / CP2102)。
电脑看到的那个串口,是通过转接芯片连到 UART0 的。这时候你如果设了 CDCOnBoot=cdc,Serial 就改往 USB 发了,而 USB 那两根脚可能压根没接到 Type-C 口。于是又是空白。
→ 解法:保持默认,别加 CDCOnBoot=cdc。
看出来了吧?这个选项没有"对"和"错",只有"跟你的板子配不配"。 判断方法就是我们在第二节让你看的那颗芯片:
| 板子上有没有转接芯片 | CDCOnBoot 该怎么设 |
串口走哪 |
|---|---|---|
| 没有(Type-C 直连) | 加上 :CDCOnBoot=cdc |
USB(GPIO18/GPIO19) |
| 有(CH340 / CP2102 等) | 保持默认,不加 | UART0(GPIO20/GPIO21) |
加上之后的完整命令长这样:
arduino-cli compile --fqbn esp32:esp32:esp32c3:CDCOnBoot=cdc D:/dev/esp32-projects/blink两个必须记住的点:
CDCOnBoot是编译期选项,不是运行期。 改完必须重新编译再重新烧录,光烧一遍旧的编译产物没用。- 编译和烧录的 FQBN 要写成一样的。 别编译时带了
:CDCOnBoot=cdc,烧录时忘了带。养成习惯:同一个 FQBN 字符串,复制粘贴两遍。
还有个小提醒:在 CDCOnBoot=cdc 模式下,板子复位的时候 USB 会重新枚举一次,串口可能会短暂消失再出现。如果你看到串口在列表里一闪一闪的,那是正常的,不是坏了。
坑 2:驱动没装,电脑认不出板子
如果板子上有转接芯片,那就要装对应的驱动。Windows 11 不一定会自动给你装。
| 芯片型号 | 装什么驱动 |
|---|---|
| CH340 / CH343 | WCH 官方的 CH341SER 驱动 |
| CP2102 / CP2104 | Silicon Labs 的 CP210x VCP 驱动 |
| 无转接芯片(原生 USB) | 一般免驱,Windows 自带的 USB CDC 驱动就够 |
怎么查? 打开设备管理器(按 Win + R,输入 devmgmt.msc,回车),重点看两个地方:
- "端口 (COM 和 LPT)" 这一项下面,有没有出现一个
COM开头的设备。 - 有没有带黄色感叹号的未知设备。
一个百试百灵的判断手法:
- 先拔掉板子的 USB 线,看设备管理器,记住现在有什么。
- 再插上板子,看多出来了什么。
多出来的那个,就是你的板子。它出现在"端口"下面 → 驱动正常;它出现在"其他设备"下面还带个黄色感叹号 → 驱动没装,去装上面表格里对应的驱动。
装驱动这事儿,让 AI 帮你找官方下载页,别去那些乱七八糟的下载站,捆绑软件能给你装一箩筐。
坑 3:一直卡在 Connecting...,烧不进去
症状是这样——命令敲下去,屏幕上开始打点:
Connecting........_____....._____....._____然后一直卡着,最后超时报错。这不是环境坏了,是板子没进入"下载模式"。
正常情况下,arduino-cli 会自动通过串口的控制信号让板子复位进下载模式。但有些板子的自动复位电路没做全,或者被占用了,就得你手动来。
手动进下载模式的两种手法,按你的板子选:
手法一:板子上有 BOOT 键 + EN/RESET 键(两个键)
- 按住 BOOT 键不放。
- 点一下 EN/RESET 键(按一下松开)。
- 再松开 BOOT 键。
顺序别错。核心是:BOOT 要在复位的那一刻是按住的状态。
手法二:板子上只有一个 BOOT 键(很多小 C3 板是这样)
- 按住 BOOT 键不放。
- 保持按住,把 USB 线拔下来再插回去(或者如果有个电源开关就开关一次)。
- 再松开 BOOT 键。
进对了是什么表现? 通常会看到串口消失一下又回来(Windows 会"叮咚"一声),或者你盯着的那个"Connecting"突然就开始往下跑了。
最后强调:这个操作只在烧录失败的时候才需要。平时烧录,直接敲命令就行,不用每次都按。按 BOOT 是排错手段,不是标准流程——我见过学生每次烧录都按一遍,还以为是必须的,白白多了一道手续。
坑 4:GPIO 编号和板子丝印对不上
这个坑最隐蔽,因为它不报错。程序烧进去了,编译也没问题,就是不干活——因为你接错引脚了。
先说清楚概念:
- GPIO 编号:芯片自己认的编号,是唯一的、权威的。代码里写的就是它。
- 丝印:板子上、拓展板上印的字。是厂商自己起的名字,跟芯片没关系。
拓展板上经常看到 A0、A1、D2、D3 这种丝印。这个 D2 极有可能不是 GPIO2,可能是 GPIO10、可能是 GPIO4,各家做得不一样。
唯一的准则是:以 GPIO 编号为准。 拿到任何一块板子,第一件事是找到它的引脚图(Pinout),把丝印和 GPIO 号的对应关系搞明白,写下来。别猜。猜错了不报错,只让你干瞪眼。
下面是 ESP32-C3 的引脚真相表。这张表你贴在桌上都不为过:
| 引脚 | 能不能接东西 | 说明 |
|---|---|---|
| GPIO0 ~ GPIO4 | 可以,优先用 | 走 ADC1,做模拟输入的首选 |
| GPIO5 | 慎用 | 是 ADC2 的唯一一路,和 WiFi 冲突,开 WiFi 时读数会失败 |
| GPIO6 / GPIO7 | 可以,推荐 | 没特殊用途,推荐拿来做 I2C 的 SDA/SCL |
| GPIO8 | 谨慎 | 接了板载 RGB 灯,而且是启动模式相关引脚 |
| GPIO9 | 别接东西 | 是 BOOT 按键,也是启动模式相关引脚 |
| GPIO2 | 谨慎 | 启动模式相关引脚,别接按键或下拉电阻 |
| GPIO10 | 可以 | 但跟 JTAG 调试口的选择有关,教学中建议避开 |
| GPIO11 ~ GPIO17 | 别用 | 连着板载 flash,动了它就起不来了 |
| GPIO18 / GPIO19 | 别用 | 是 USB 的 D- / D+,占用了 USB 口就废了 |
| GPIO20 / GPIO21 | 慎用 | 是 UART0 的 RX / TX,串口通信用着 |
几条重点展开讲讲:
关于 GPIO5 和 WiFi 冲突: ESP32-C3 只有两路 ADC,ADC1 占了 GPIO0 到 GPIO4 五路,ADC2 只有一路,就是 GPIO5。而 ADC2 是跟 WiFi 模块共用的——一旦你开了 WiFi,GPIO5 上的模拟读数就会失败或者给你乱数。所以做光敏、热敏、电位器、麦克风这些模拟实验时,一律用 GPIO0 到 GPIO4。反正五路也够你用了。
关于 GPIO8 和 GPIO9: 这两个都是"启动模式"相关的引脚,芯片上电那一瞬间会去读它们的电平,决定是正常运行还是进下载模式。这里有个硬约束:GPIO8 和 GPIO9 同时为低电平是非法状态,芯片会做出你预料不到的事。所以:
- 别在
GPIO8上接按键(按下就是接地)。 GPIO9上已经焊了 BOOT 按键了,你就别往上接别的了。
关于 I2C 接 OLED 的坑(这个特别实用): ESP32-C3 的默认 I2C 引脚是 SDA = GPIO8、SCL = GPIO9。看出来问题没有?GPIO9 上焊着 BOOT 键,GPIO8 又是启动脚——俩都不是省油的灯。
所以接 OLED 的时候,别用默认引脚,在代码里手动指定。我推荐 GPIO6 和 GPIO7:
Wire.begin(6, 7); // SDA = GPIO6, SCL = GPIO7这一行在你上 OLED 那节课的时候会救你的命。现在先记下这个结论:默认 I2C 引脚不能用,改用 GPIO6 / GPIO7。
关于 GPIO18 / GPIO19: 这两个是 USB 的口子。你把它们当普通 IO 用了,轻则 USB 口失效(得手动按 BOOT 才能再烧录),重则电脑再也认不出板子。总之——别碰。
坑 5:能供电,但电脑就是找不到串口
这个我在第二节提过,这里正式收尾。
板子上的电源灯亮,只说明一件事:USB 的供电通了(VBUS 和 GND 通了)。它完全不说明数据线通了。
这两件事是分开的:
- 电源灯亮 = VBUS、GND 这两根芯是通的 → 板子能上电。
- 找得到串口 = D+、D- 这两根芯也是通的 → 电脑能和板子说话。
纯充电线只有前两根,没有后两根。 所以症状就是本文开头描述的:灯亮着,口找不到。
排查顺序,我按性价比排好:
- 换一根线——优先换你确定能传数据的(手机传文件那根)。这一条能解决八成的情况,而且只要十秒钟。
- 换一个 USB 口——特别是台式机,插机箱后面的口,别插前面板。
- 别用 USB 扩展坞 / Hub,直连。有些 Hub 供电不足或者芯片兼容性有问题。
- 万用表验 D+ / D-(做法见第二节)。到这一步还没解决,就是线的问题实锤了。
- 看设备管理器(见坑 2)。多出来个带感叹号的设备,那就是驱动问题,不是线的问题。
为什么要用万用表? 因为你光看外表分不出充电线和数据线,它们长得一模一样。万用表是唯一能一眼看穿的家伙。 这也是为什么材料清单里给你配了它——它不只是量电压用的,"通断"这个功能在排查这种问题时比什么都好使。
八、Blink:亲手验证环境通了
环境装好了,坑也讲完了。现在来真的——跑通 Blink,让板载 LED 闪起来。 这是我们这节课的成功标志。
第 1 步:建工程目录
先说一件重要的事:路径必须纯英文。
虽然我们这个课程项目本身的目录里带中文,但你自己写代码的工程目录,一定要用纯英文、无空格的路径。中文路径会让编译工具链出各种诡异的错,而且报错信息完全指向不到真正的原因。
所以我建议你在 D 盘建一个专门的目录:
D:\dev\esp32-projects\再强调一遍 Arduino 的一个死规矩:文件夹名必须和 .ino 文件名一模一样。 这条规矩无数人栽过,编译报错 main file missing from sketch 就是这个原因。
所以我们要建的是:
D:\dev\esp32-projects\blink\blink.ino文件夹叫 blink,文件也必须叫 blink.ino。 一个字母都不能差。
在 Git Bash 里建:
mkdir -p /d/dev/esp32-projects/blink在 PowerShell 里建:
New-Item -ItemType Directory -Force D:\dev\esp32-projects\blink第 2 步:先接上 LED 模块
在写代码之前,先把灯接上。
我们套件里的 LED 是个独立的模块,不是焊在板子上的。所以你得先把它连起来:
| LED 模块 | 接到 |
|---|---|
| VCC | 3.3V |
| GND | GND |
Signal |
GPIO3 |
接之前先断电(把板子从电脑上拔下来)。接好了再插回去。
为什么要用
GPIO3?因为它是这块板子上最安全的通用引脚之一——不是启动脚、不是 USB 脚、不是 flash 脚。后面几节课我们都尽量用它。
第 3 步:写代码
新建 blink.ino,就写这么点:
void setup() {
pinMode(3, OUTPUT); // 把 GPIO3 设为"输出"
}
void loop() {
digitalWrite(3, HIGH); // 点亮
delay(500); // 等 500 毫秒
digitalWrite(3, LOW); // 熄灭
delay(500); // 等 500 毫秒
}先别急着问为什么,先烧进去看现象。 原理我们后面几节课讲——这是这门课的规矩:先看到,再理解。
为什么这里写
3而不是别的?因为你的
Signal线就接在GPIO3上。代码里的引脚号,必须跟你实际接线的那根脚对上。 接的是哪根、代码里就写哪根——这两件事不一致,灯就不会亮,而且从外观上完全看不出来。这也是后面你排查故障时要留意的:第一件事就是核对"代码里写的脚"和"线插的脚"是不是同一个。
第 3 步:编译
arduino-cli compile --fqbn esp32:esp32:esp32c3 /d/dev/esp32-projects/blink如果你的板子是 Type-C 直连的(第二节让你看过的那颗芯片,没有),加上 CDC 选项:
arduino-cli compile --fqbn esp32:esp32:esp32c3:CDCOnBoot=cdc /d/dev/esp32-projects/blink编译成功的话,你会看到类似这样的输出:
Sketch uses 288341 bytes (22%) of program storage space. Maximum is 1310720 bytes.
Global variables use 21876 bytes (6%) of dynamic memory, leaving 305804 bytes for local variables. Maximum is 327680 bytes.看到这两行,就说明编译过了。 中间那些 #pragma message 之类的警告,忽略它们,不影响运行。新手最容易在这儿自己吓自己。
第 4 步:烧录
先确认板子插着,看看电脑认到哪个口了:
arduino-cli board list你会看到类似这样的一行:
Port Protocol Type Board Name FQBN Core
COM3 serial Serial Port (USB) UnknownBoard Name 显示 Unknown 是完全正常的,不用管它——那只是 arduino-cli 没法自动认出具体型号而已。我们关心的是 COM3 这个端口号。
注意:你要用你自己电脑上显示的那个端口号,别照抄我的 COM3。 每台电脑都不一样。
然后烧录:
arduino-cli upload -p COM3 --fqbn esp32:esp32:esp32c3 /d/dev/esp32-projects/blink带 CDC 的版本:
arduino-cli upload -p COM3 --fqbn esp32:esp32:esp32c3:CDCOnBoot=cdc /d/dev/esp32-projects/blinkFQBN 跟编译时保持一致,这是我前面强调过的。
烧录过程中会打出芯片信息:
Chip type: ESP32-C3 (QFN32) (revision v0.4)
Features: Wi-Fi, BT, Single Core, 160MHz
Crystal frequency: 40MHz看到 ESP32-C3 这行字,说明电脑确确实实跟芯片握上手了。 这一步的成功率是最高的,如果卡在 Connecting,回坑 3 按 BOOT。
如果卡住了,按一下 BOOT 键,或者按坑 3 的手法进下载模式,然后重新执行 upload 命令。
第 5 步:看现象
烧录完成,眼睛离开屏幕,看你接的那个 LED 模块。
它开始一闪一闪,间隔半秒——恭喜,环境通了。 这节课最硬的一块骨头,你啃下来了。
没闪的话,按这个顺序倒查(顺序别乱):
- 接线:
VCC真的是3.3V吗?GND真的接地了吗?Signal真的在GPIO3上吗? - 代码里的引脚号:你接的是
GPIO3,代码里写的也是3吗?这两件事必须对上。 - 板子上的电源灯亮不亮?(不亮 → 坑 5,线的问题)
- 烧录命令真的成功了吗,还是中途报错了?(回去看输出)
- 前面那个"让板子说话"的程序还在跑吗?重新烧一次。
注意第 1、2 条排在最前面。九成的"灯不亮"都是接线或者引脚号的问题,而不是代码写错了。这就是下一课要学的"排查顺序"——先查硬件,最后才怀疑代码。
第 6 步:让它开口说话
灯闪了,再往前一步,让板子通过串口跟你说句话。把 blink.ino 改成这样:
void setup() {
Serial.begin(115200); // 打开串口,速度设为 115200
pinMode(3, OUTPUT);
Serial.println("吴老师,我上线了!");
}
void loop() {
Serial.println("灯亮");
digitalWrite(3, HIGH);
delay(500);
Serial.println("灯灭");
digitalWrite(3, LOW);
delay(500);
}波特率 115200 必须和后面读串口时用的一致,不一致就是一堆乱码。这是仅次于接错线的第二大新手坑。
重新编译、烧录(记得带上你那个 CDC 选项),然后读串口:
arduino-cli monitor -p COM3 --config baudrate=115200按 Ctrl+C 退出。
给 AI 的一个实操建议:如果你是 AI 在代跑,别用
arduino-cli monitor——它是交互式终端,会一直占着不返回,不适合自动执行。改用 Python + pyserial 读固定行数:Shell pip install pyserialShell python -c " import serial, time ser = serial.Serial('COM3', 115200, timeout=1) time.sleep(2) # 等板子启动,这两秒不能省 for i in range(10): line = ser.readline() if line: print(line.decode('utf-8', errors='replace').strip()) ser.close() "
time.sleep(2)那行很关键——板子复位后要一两秒才启动完,起太早读到的全是空的,然后你会误判成"串口没输出"。
看到串口里滚动着"灯亮""灯灭",这节课就彻底通关了。 你现在有了一个完整可用的 ESP32-C3 开发环境。
九、AI 该按什么顺序帮你排查
这一节是写给 AI 看的,学习者也应该照着这个顺序自查。核心原则只有一条:从最底层往上一层层查,一步不通,绝不往下跳。
跳过前面的步骤直接查后面,是所有排查里最浪费时间的行为。 比如串口读不到,你上来就去改代码,而真正的原因可能是 arduino-cli 压根没装成功。
| 顺序 | 命令 | 要确认什么 | 这一步失败说明 |
|---|---|---|---|
| 1 | arduino-cli version |
能不能打印出版本号 | 没装成功,或者 PATH 没配好/没重开终端 |
| 2 | arduino-cli config dump |
输出里有没有 board_manager.additional_urls |
索引地址没加上,或者配置写在别的地方了 |
| 3 | arduino-cli core list |
列表里有没有 esp32:esp32 |
核心没装成功,或者上一步索引没更新 |
| 4 | arduino-cli board list |
能不能列出 COM 端口 |
硬件层问题:线、驱动、USB 口。这一步不过,下面全是白费 |
| 5 | arduino-cli board listall esp32c3 |
确认 FQBN 是 esp32:esp32:esp32c3 |
核心装好了但板型找不到,索引有问题 |
| 6 | arduino-cli compile --fqbn ... |
编译有没有通过 | 代码问题、库没装、路径问题 |
| 7 | arduino-cli upload -p ... --fqbn ... |
有没有打出 Chip type: ESP32-C3 |
板子没进下载模式(按 BOOT)、端口被占用 |
| 8 | 读串口(Python 或 monitor) | 有没有正常文字输出 | 波特率不对、或 CDC 选项跟板子不匹配(回坑 1) |
第 4 步是整个流程的分水岭。 端口列不出来,就不要再去动代码、动库、重装核心——那些跟这个问题一点关系都没有。老老实实回到坑 2 和坑 5:查驱动、换线、换 USB 口。
再给 AI 两条操作纪律:
- 一次只改一个变量。 别一边换线一边重装核心一边改代码。改多了,成了你不知道为什么成,败了你也不知道是哪儿的错。
- 每一步都把原始输出亮给学习者看。 别只说"好了"或者"失败了"。学习者看的就是这个排查过程,这才是这节课真正的教学内容。
十、故障速查表
| 症状 | 最可能的原因 | 怎么办 |
|---|---|---|
arduino-cli: command not found |
装完没重开终端 / PATH 没配 | 关掉终端重新开一个;还不行就查 PATH |
电源灯亮,但 board list 里没端口 |
纯充电线,D+ / D- 不通 | 换数据线(十秒钟解决八成情况);万用表验线;换 USB 口 |
| 设备管理器里有带感叹号的设备 | 驱动没装 | 按芯片型号装 CH340 或 CP210x 驱动 |
core install 卡住不动 / 超时 |
网络问题,在下几百 MB 工具链 | 耐心等;或换国内镜像索引重来 |
编译报 main file missing from sketch |
文件夹名和 .ino 文件名不一致 | 改成同名,比如 blink/blink.ino |
| 编译报找不到某个库 | 库没装,或库名打错了 | arduino-cli lib search 关键词 搜准确名字,加引号重装 |
| 编译报中文路径相关的怪错 | 工程路径里有中文或空格 | 把工程挪到纯英文路径 |
烧录卡在 Connecting........_____ |
板子没进下载模式 | 按住 BOOT → 点一下 EN → 松开 BOOT;只有一个键就按住 BOOT 插拔 USB |
| 烧录成功,但串口一个字都没有 | CDCOnBoot 跟板子不匹配(坑 1) |
有转接芯片 → 用默认;Type-C 直连 → 加 :CDCOnBoot=cdc。改完重新编译再烧 |
| 串口全是乱码 | 波特率不匹配 | Serial.begin() 和读串口时的 baudrate 都必须是 115200 |
| 串口读出来是空的 | 板子还没启动完 | 读之前先 time.sleep(2) 等它启动 |
| 程序烧进去了但不干活 | 引脚接错了(坑 4) | 查板子的引脚图,以 GPIO 编号为准,别信丝印 |
| 烧录后 USB 口认不出来了 | 程序占用了 GPIO18 / GPIO19 | 按住 BOOT 进下载模式重新烧一个不占用 USB 的程序 |
| 灯不亮,但烧录成功 | 接线错了,或代码里的引脚号跟实际接的不一致 | 核对 Signal 接的是哪根、代码里写的是几 |
十一、自测
答案与解析
重点在于:官方索引本身能访问,它只是个"目录"。但它记的每一条下载地址都指向 GitHub——而 GitHub 在国内不稳定。镜像索引里 1000 多条地址全部指向 dl.espressif.cn,这才是速度差别的真正原因。
答案与解析
离线包里包含了完整的编译工具链(RISC-V 编译器、C3 专用库、烧录工具)——它们正是在线安装时最慢、最容易失败的那几百 MB。装好之后,编译和烧录都完全在本地完成。
arduino-cli 提示"找不到命令",但你确定刚才装成功了。最可能是什么原因?答案与解析
装完 CLI 之后 PATH 变了,但已经开着的终端窗口用的还是旧的 PATH。关掉重开就好。这是装环境最常见的"假失败",很多人在这里以为装错了、反复重装。
arduino-cli board list 里一个端口都没有。列出你的排查顺序,并说明每一步在排除什么可能。答题要点
答题要点应该包含:① 先换线——排除充电线(内部没有 D+/D-,板子会亮但电脑认不出),这是最高频原因;② 换 USB 口,台式机优先插机箱后面板,排除供电不足;③ 看设备管理器有没有带感叹号的设备,判断是不是驱动没装(CH340/CP2102 视板子而定);④ 确认板子类型——Type-C 直连的板子可能需要 CDCOnBoot=cdc 才能出现串口;⑤ 最后才怀疑板子坏。顺序原则是:先排除最简单的、最常见的,再往复杂走。
拓展为什么"官方索引能打开,但装包很慢"?这两件事为什么不是一回事?
这个问题课上不讲,留给你自己找答案——**问 AI 是最好的办法**。
提示:搜"索引文件 与 实际下载地址 的关系"。想一想:一张菜单能看,不代表上面写的每一家店都好找。
拓展编译工具链(交叉编译器)是什么?为什么嵌入式开发需要它?
这个问题课上不讲,留给你自己找答案——**问 AI 是最好的办法**。
提示:搜"交叉编译 为什么需要"、"RISC-V 工具链"。想一想:你的电脑是 x86 的,而 ESP32-C3 是 RISC-V 的,编译出来的程序能直接在电脑上跑吗?
十二、本节你要动手做的事
别看完就关掉,动手做完这七件事,这节课才算真的过。
- 确认你的线。 用万用表通断档测那根 Type-C 线的 GND、D+、D-。测出来是充电线就换掉。 顺手记下结论:我用的线,是/不是数据线。
- 确认你的板子类型。 看背面有没有转接芯片,插上电脑看设备管理器的变化,结论记下来:我的板子是"Type-C 直连"还是"带转接芯片"。这个结论决定了你要不要加
CDCOnBoot=cdc。 - 装好 arduino-cli 并验证。 敲
arduino-cli version能看到版本号;arduino-cli config dump里能看到你加的那个索引地址;arduino-cli core list里能看到esp32:esp32。- 如果在线装反复失败,别硬耗,直接用第四节的离线包(百度网盘,1.8GB)。这条路慢在下载,但装是一次性的,装完再也不用管网络。
- 记下两个关键信息:你的 ESP32-C3 的 FQBN(应该是
esp32:esp32:esp32c3),和你的板子出现在哪个COM口。 - 跑通 Blink。 在
D:\dev\esp32-projects\blink\blink.ino写那四行,编译、烧录,亲眼看到 LED 模块闪起来。 - 让板子说话。 把
Serial那版代码烧进去,读串口,看到"灯亮""灯灭"一路滚出来。 - 把 AI 的排查顺序走一遍。 就算一切顺利,也照着第八节那张表,从第 1 步到第 8 步把命令敲一遍,看看每步的输出长什么样。因为等你哪天真的卡住了,你需要的是"知道正常长什么样"——只有见过正常的,才能一眼认出不正常的。
说句掏心窝子的话
这节课你熬下来了,我得跟你说几句。
装环境是这门课里最没意思的一节——没有灯闪,没有舵机转,全程对着黑乎乎的命令行。它枯燥、容易报错、而且一点都不好玩。
但恰恰是它,劝退了大部分人。我教过的学生里,倒在"装环境"这一步的,比倒在后面所有技术难题上的加起来还多。不是因为它难,是因为它没有即时反馈——你在前面熬两个小时,什么都看不见,很容易就想"算了吧"。
你熬过来了。
顺便说件事:这一节里我讲的那几个坑(串口不显示、驱动、BOOT 键、CDC 模式),不是你这次躲过去了就永远没事了。你以后换板子、换电脑、帮同学装,还会再撞上它们。但那时候你已经见过正常的输出了——这就是今天第七件事的价值。
下一节开始,我们就有东西看了。真的。