每个玩 ESP8266 的人,基本都撞过同一个画面:Arduino IDE 的进度条走到 99%,然后像被按了暂停键一样,一动不动。等十分钟、半小时,最后要么弹一个下载失败,要么干脆卡死在那里。我第一次装 ESP8266 时还以为是电脑配置不行,换了两台机器依旧卡在同一个地方。后来打开详细日志才看明白,IDE 卡住的并不是解压或者安装,而是在偷偷下载一个上百 MB 的编译工具链,这个下载只要中途断掉,整个安装就停在 99%,只能重新再来。
这篇文章就来解决这个 99% 魔咒。我会从 Arduino IDE 的下载逻辑讲起,然后给你两条不用死等的路:一条是更换下载源,让 IDE 尽量避开容易断的下载链路;另一条是直接把整套工具链离线放进 IDE 的目录里,绕开在线下载。跟着做一遍,从安装到能编译上传,熟练以后其实用不了 5 分钟。这篇内容适合刚接触 Arduino 的新手,也适合换电脑、重装系统后需要重新搭环境的老玩家——毕竟这问题从来不分新手和老手,谁都得面对。
1. 为什么每次都在 99% 卡住:从下载逻辑说起
1.1 这 99% 的时间 Arduino IDE 究竟在下载什么
正常情况下,你在开发板管理器里搜 esp8266,看到 “esp8266 by ESP8266 Community”,点 Install,界面上的绿色进度条看似只有一个任务,后台其实要连续做几件事。IDE 首先会去读取一个 JSON 索引文件,里面记录了这个开发板核心所有版本的下载地址、文件校验值、依赖的工具清单。接着 IDE 根据索引去下载核心压缩包,再下载 gcc 交叉编译器、esptool 烧录工具、mkspiffs 文件系统工具等依赖项。
这几个压缩包里,体积最大的通常不是主板描述文件,而是 xtensa-lx106-elf-gcc 这一套交叉编译器。它负责把你在 Arduino IDE 里写的 C++ 代码,翻译成 ESP8266 这颗芯片能跑的机器码,不同版本打包下来 100MB 到 200MB 很正常。Arduino IDE 的下载机制又不像浏览器那样支持良好的断点续传,哪怕文件已经拉了 90%,只要最后一部分数据没拿到,它就只能在进度条上干等着,表现出来就是你看到的 99% 卡死。
用一段白话解释,就是 IDE 从网上拉一个几百 MB 的文件,拉到最后一小块时网络断了,它既没有果断失败,也没有本事续传,于是卡在那边装死。很多人误以为是自己电脑性能不行,其实去任务管理器或者资源监视器里看就能发现,网络接收速率早就归零了,空等一点用都没有。
1.2 为什么同样的操作,有人一次成功,有人反复失败
同样是打开 IDE、装同一个版本,结果天差地别,原因可以拆成三个层面。
第一是下载地址的问题。如果你在“附加开发板管理器网址”里填的 JSON 地址不对,或者这个地址在你的网络环境下访问困难,那 IDE 连最基础的索引都拉不完整,后面所有下载全都会挂,表现往往就是进度条走到一半或者 99% 时告警。第二是网络链路的差异。你在宽带环境下下载官方工具链,和在某些公共网络环境下下载,走的路径完全不同,丢包率、连接建立速度差别很大。第三是本地缓存的干扰。之前某次装到一半留下的残包,如果还躺在 Arduino 的缓存目录里,有可能被 IDE 误判为有效文件,等它继续读后续数据时又发现不完整,最终造成进度条停滞。
理解了这三点,就能明白为什么单纯重试解决不了问题:网络路径没有变、缓存文件没有清、下载地址没有换,那重试一百次也只是把同样的问题再撞一百次。真正有效的方案,是让 IDE 换一条更顺畅的下载链路,或者干脆不去下载,直接把文件放到它规定的位置上。
2. 方案一:更换下载源,让 IDE 自己搞定
2.1 第一步:检查并填写开发板管理器地址
先做最基础的一件事:检查附加开发板管理器网址。打开 Arduino IDE,在菜单栏找到 文件 -> 首选项,中文版里叫“附加开发板管理器网址”,英文版叫 Additional Boards Manager URLs。如果你这里还是空的,或者填了一个不知道哪里抄来的地址,先把它改成 ESP8266 官方维护的标准地址:
https://arduino.esp8266.com/stable/package_esp8266com_index.json注意,这个地址必须以 http:// 或 https:// 开头,而且不要有多余空格。Arduino IDE 2.x 的入口位置稍微不一样,一般在 Preferences 的 Additional boards manager URLs 一栏,点那个图标会弹出一个输入框,把地址填进去保存。改完之后,回到开发板管理器,重新搜索 esp8266,这回出现在列表里的结果应该更完整,版本信息也能正确加载出来。
2.2 第二步:先验证地址能不能打开,再决定要不要继续
填完地址先不要急着点安装,我建议你先打开浏览器,把这串地址贴进去访问。如果你看到浏览器里出现一长串以{开头的 JSON 文本,说明这个地址能正常访问;如果浏览器直接超时,或者提示连接被重置、无法访问此网站,那么问题就明白了:IDE 卡住不是因为软件出 bug,而是它根本拿不到下载列表。
遇到这种访问不畅的情况,可以试试把 https 改成 http,也就是用非加密的旧地址重新访问一遍。有些网络环境下,加密连接反而更容易被掐断,用明文 http 反而能勉强拉一版数据下来。当然,从安全角度讲,这不是最好方案,但作为应急手段在社区里确实很常见。
如果你手边有学校实验室、开源社区或技术论坛提供的国内镜像地址,也可以填入同一栏位。镜像的好处是下载链路通常更直接,但要注意版本同步情况,镜像更新可能滞后。装好后看一下开发板管理器里的可用版本号,如果和你期望的不一致,再决定是继续用镜像还是回到官方源。
2.3 在线安装时还能顺手做的两个判断
在线安装的时候,我会顺手做两件事,能从侧面判断到底有没有在下载。
第一,把 IDE 的详细输出打开。在首选项里找到“显示详细输出”,把“编译”和“上载”都勾上。这样安装失败时,IDE 的日志窗口会显示具体卡在哪个 URL 上,信息量比干看进度条大得多。第二,开着任务管理器或者系统资源监视器,观察网络一栏。如果进度条停在 99% 而网络接收速率已经归零,说明下载进程实际已经断了,继续等没有意义;如果网络波动还在继续,那可能还有救,让 IDE 再跑一阵子。
这两个判断方法能帮你减少很多无谓等待。卡 99% 的时候,大多数人办了蠢事就是反复点安装、反复取消,把 staging 目录里的临时文件越搞越乱,后面反而更难排查。
3. 方案二:离线安装包,一劳永逸
3.1 离线安装的思路,其实很简单
如果换了下载源还是卡,或者你根本不想跟网络较劲,那我推荐离线安装。这个方法本质上是把 IDE 本来要自动下载的东西,预先放到它规定的目录里,让 IDE 在扫描时发现文件已经存在,从而跳过网络下载这一步。
整个过程的关键其实就两个:目录路径对不对,文件版本匹配不匹配。只要这两点对了,IDE 会认可这些本地文件,甚至不会再显示安装按钮,而是直接把这个版本标记为已安装。这个方法被很多人称作“绿色部署”,理解之后你会发现它不只对 ESP8266 有效,ESP32、AVR 这些核心也都能用同一套逻辑处理。
3.2 找对 Arduino15 目录,这是后面所有操作的基础
离线安装首先要找到 Arduino 的数据目录。不同操作系统位置不一样:
- Windows:
C:\Users\<你的用户名>\AppData\Local\Arduino15 - macOS:
~/Library/Arduino15 - Linux:
~/.arduino15
找不到的时候,可以直接在文件管理器里搜索 Arduino15 这个名字,或者打开 IDE 的首选项,看底部的磁盘位置信息。Arduino 的所有开发板核心、工具链、缓存安装包,都存放在这个目录里。
你打开 Arduino15 后,通常能看到 staging、packages 这些子目录。staging 是 IDE 的下载缓存区,它把下载好的压缩包临时放在这里,解压之后再挪到 packages 目录;packages 才是最终安装位置,里面按供应商名字分了一层又一层,比如 esp8266 就会出现在 packages\esp8266 下面。
3.3 怎么从 JSON 里找出真正的下载地址
如果你想自己做一个干净可靠的离线包,那就要学会读 package_esp8266com_index.json 这个文件。用浏览器打开 JSON 地址后,把内容保存成文本文件,然后用编辑器搜索你想装的版本号,比如 2.7.4。你会看到类似这样的结构:
{ "platforms": [ { "name": "esp8266", "version": "2.7.4", "url": "https://github.com/esp8266/Arduino/releases/download/2.7.4/esp8266-2.7.4.zip", "archiveFileName": "esp8266-2.7.4.zip", "toolsDependencies": [ { "packager": "esp8266", "name": "xtensa-lx106-elf-gcc", "version": "2.5.0-..." } ] } ] }这个 url 字段就是核心压缩包的下载地址。如果你浏览器能打开它,就把 zip 下载下来;如果打不开,就去网上找有没有人搬运到国内镜像站的同版本文件。注意 archiveFileName 是 IDE 期望的文件名,最好下载后保持原名,不要随手改。再用同样的方法,在 JSON 的 tools 区域找到 xtensa-lx106-elf-gcc、esptool、mkspiffs 这几个工具的下载地址,一并下载下来。
3.4 手动放置工具链的目录规范
下载完这些压缩包后,要做的事情就是解压并放到指定位置。我以 Windows 为例,最终目录结构应该是这样:
%LOCALAPPDATA%\Arduino15\packages\esp8266\ ├── hardware\esp8266\2.7.4\ │ ├── cores\ │ ├── libraries\ │ ├── tools\ │ ├── variants\ │ ├── boards.txt │ └── platform.txt └── tools\ ├── esptool\<版本号>\ ├── mkspiffs\<版本号>\ └── xtensa-lx106-elf-gcc\<版本号>\ └── xtensa-lx106-elf\看不懂目录为什么这么分也没关系,你只要记住一个核对标准:硬件描述包放在 hardware\esp8266<版本号> 下,工具链放在 tools<工具名><版本号> 下。如果你看到 IDE 在编译时报xtensa-lx106-elf-gcc: executable file not found in %PATH%,大概率就是工具链没放对位置,或者工具名、版本号目录对不上。重启 IDE,重新打开开发板管理器,这时候你会看到 esp8266 对应的版本已经显示为 Installed,整个安装环节就彻底绕过了在线下载。
4. 实操:从卡 99% 到成功烧录的全流程
4.1 安装前,先清理缓存和临时文件
不管用在线还是离线方案,我建议你先做一件容易被忽略的事:清理 Arduino15\staging 目录。这个目录是 IDE 的下载暂存区,之前安装失败留下的残包都堆在这里。有些残包文件大小和正常 zip 差不多,但校验值对不上,IDE 以为文件下载完了,结果一解压就出错,表现出来就是进度条反复卡在 99%,或者每次下载到同一个位置就失败。
清理的方式很简单:完全退出 Arduino IDE,打开 staging 目录,把 packages 和 cores 子目录里的旧文件删掉。如果你不想全删,优先删除文件名里带 .part 的、以及创建时间靠近最近一次安装失败的 .zip 文件。macOS 和 Linux 同理,在 ~/Library/Arduino15/staging 和 ~/.arduino15/staging 下操作。清完之后再装,问题通常会减去一半。
4.2 在线安装时,如何判断这次会不会成功
清完缓存,我们就正式开始安装。如果你选在线方式,点 Install 之后可以把注意力放在 IDE 左下角的输出区。Arduino IDE 1.8.x 会直接打印当前正在下载的文件名;Arduino IDE 2.x 的输出区藏得深一点,但也能看到类似 Downloading packages 的信息。如果日志卡在同一个 URL 超过几分钟,要么网络还没完全断开,要么这条链路已经废了,果断取消再来,别干等。
我可以给你的经验是:一次安装失败后,马上重试的成功率其实并不高。更有效的做法是取消这次安装,退出 IDE,清理 staging,重新打开 IDE,换一个更可靠的下载源或者直接走离线路,然后再试。这样看起来多花了几分钟,但整体成功率反而高很多。
4.3 选对开发板型号、端口和上传参数
核心装好之后,接下来就要处理上传到板子这个环节。先说开发板型号:如果你手里是 NodeMCU 开发板,通常在 工具 -> 开发板 里选择 NodeMCU 1.0 (ESP-12E) 就够用了;如果是 ESP-01 这类小模块,可以选 Generic ESP8266 Module,并且手动设置 Flash Size,常见的是 1MB (FS:64KB) 或者 512KB (FS:64KB),具体看模块标识。
端口这里最容易出问题。Windows 下,USB 转串口模块如果是 CH340 芯片,需要装 CH340 驱动;如果是 CP2102 芯片,需要装 CP210x 驱动。没有驱动时,设备管理器里会显示一个带感叹号的未知设备,Arduino IDE 的端口列表里也看不到任何串口。装好驱动后,把板子重新插拔一次,选择对应的 COM 口,再继续下一步。
上传参数方面,绝大多数 ESP8266 板子在 115200 波特率下都能正常烧录。如果你的板子走线比较长或者环境干扰大,上传时老超时,可以把 Upload Speed 降到 57600 甚至 9600,速度慢一点,但成功率会提升很多。Flash Size 一般看板载 Flash 芯片,常见 NodeMCU 基本都是 4M,选 4M (3M SPIFFS) 即可。
4.4 第一次点亮板载 LED,验证整条链路
配置好这些之后,先别写复杂代码,跑一个最小例程最稳妥。打开 文件 -> 示例 -> 01.Basics -> Blink,对 ESP8266 来说,这个例程默认控制的是开发板上的蓝色 LED 或者指定 GPIO。点上传,IDE 会先编译,然后进入烧录流程,你能看到 Connecting.... 的提示,接下来就是 Done uploading。
如果这时板载 LED 开始闪烁,说明从安装核心到编译上传整条链路已经完全跑通。这时候再用串口监视器输出一句 Hello,或者接个 DHT22 读温度湿度,才算真正进入 ESP8266 开发阶段。看到这里,99% 卡住这个坎就已经跨过去了。
5. 装完后的高频问题:编译报错和上传超时
5.1 编译时报 DHT 找不到,怎么处理
核心安装成功只是第一步,很多人第一次写温湿度程序,会碰到'DHT' does not name a type或fatal error: DHT.h: No such file or directory这类报错。这不是核心装错,而是缺少 DHT 库。在 工具 -> 管理库 里搜索 DHT sensor library,安装 Adafruit 维护的版本,然后在代码最前面加上#include <DHT.h>即可。
这里有个小细节:DHT 传感器接到 ESP8266 上时,数据引脚不要随意接,建议用 GPIO4 或 GPIO5,也就是 D2 和 D1 这两个丝印位置。代码里写清楚引脚编号,比如:
#include <DHT.h> #define DHTPIN 4 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE);编译前先检查这个库有没有真正安装到当前核心下面,如果库装了还是报错,多半是 Arduino IDE 版本和库版本兼容问题,升级 IDE 或者换一个旧版 DHT 库都能解决。
5.2 上传时一直 timed out 的排查顺序
ESP8266 最常见的上传失败提示是A fatal esptool.py error occurred: Failed to connect to ESP8266: Timed out waiting for packet header。遇到这个报错,按这个顺序排查,基本都能定位:
- 确认端口选中,且串口监视器没有占用同一个串口。
- 确认开发板型号,先换 NodeMCU 1.0 试试,再换 Generic ESP8266 试试。
- 降低上传波特率,从 115200 降到 57600,再尝试一次。
- 手动进入下载模式:按住板子上的 BOOT/FLASH 按钮不放,点上传,看到 Connecting.... 后松开按钮。
- 检查接线,特别是 IO0 是否被拉到低电平,有些板子需要把 IO0 接 GND 才能进入烧录模式。
绝大多数情况下,第 4 步能解决 ESP-01 这类没有自动下载电路的模块。如果你用的是 NodeMCU 板载方案,理论上自动下载电路可以处理,但偶尔会因为接触不良或者 USB 供电不足导致失败,这时候换一根短一点的 USB 线、插到主机后置 USB 口,也能提高成功率。
5.3 报错速查表
| 报错现象 | 常见原因 | 处理办法 |
|---|---|---|
| 进度条到 99% 后长时间不动,最终下载失败 | 下载中断,临时文件损坏或网络链路不稳定 | 清理 staging 缓存,换下载源,或直接用离线安装包 |
| 安装完成后开发板管理器里没有 ESP8266 选项 | 附加开发板管理器网址填写错误 | 填写官方 JSON 地址,并用浏览器先验证能否打开 |
| 编译时报 xtensa-lx106-elf-gcc not found | 编译器没有随核心完整安装 | 手动补齐 packages\esp8266\tools 下的工具链,或重装核心 |
| 上传时报 timed out waiting for packet header | 芯片没有进入烧录模式,或串口选错 | 按住 BOOT 键重试,降低波特率,检查 IO0 接 GND |
| 代码里 include DHT.h 报文件不存在 | 缺少 DHT 传感器库 | 在库管理器里安装 Adafruit 的 DHT sensor library |
6. 一些只有踩过坑才懂的经验
6.1 维护一套自己的离线安装包
如果你经常帮同学、同事装 Arduino 环境,或者需要给实验室的多台电脑统一配置,建议把常用版本的 esp8266 核心、ESP32 核心、CH340/CP2102 驱动打包放到一个移动硬盘里。这个习惯在我这里已经帮了大忙:每次拿到新电脑,先装驱动,再把 Arduino15 目录整个复制过去,IDE 打开之后直接识别所有核心,完全不用再去跑安装按钮。
要提醒的是,这套离线目录最好选在一台网络环境相对干净、之前安装没有报错的电脑上生成,复制过去之后路径合适就对。Windows 和 macOS 的目录结构差异比较大,不要跨系统拷贝,老老实实在同系统下维护。
6.2 杀毒软件和 IDE 缓存这两个隐形敌人
另一个容易忽略的因素是杀毒软件和系统防火墙。有些安全软件会锁定正在下载的临时文件,导致 IDE 无法正常读取和解压,进度条一直卡着不动。如果你把 Arduino15 放在默认位置,最好把Arduino15目录和 Arduino IDE 安装目录都加入白名单。
另外,卡 99% 时不要反复点安装按钮。反复点只会让多个下载任务在同一目录里互相争抢,甚至把 staging 里的临时文件弄乱。正确做法是取消本次安装,退出 IDE,清掉 staging 缓存,再重新装,或者直接离线安装。这个习惯能避免很多自己给自己挖的坑。
6.3 最后再分享一个我的习惯
如果让新手直接抄作业,我最推荐的组合是:Arduino IDE 1.8.19 搭配一个完整的离线安装包,再配好 CH340 驱动。这个组合我在不同电脑上装过很多次,几乎没再碰到 99% 卡死的问题。等你能够稳定编译和上传基础例程,再考虑要不要升级到 2.x,毕竟新版本的界面和缓存路径有些变化,没必要在入门阶段给自己增加变量。
我在实际使用中还有一个习惯:每次装好环境后,把板子连接、上传参数和测试用的 Blink 例程都存成一个文本文档放在桌面。等下次手忙脚乱的时候,照着文档十分钟之内就能服务好新机器,不给自己留任何“又要折腾一遍”的余地。