PAYATHON 2026

ESP8266 Deep Sleep 唤醒后只有启动日志,程序不执行,如何排查?

数据阿明

结论:复位日志不能证明程序已正常启动

rst cause:2 和 boot mode:(3,6) 分别表示芯片发生了外部复位、选择从 Flash 启动。仅凭这两行日志,无法确认程序是否执行到 setup(),也无法断定复位由 Deep Sleep 定时器触发。GPIO16 触发 RST、复位按钮或其他复位电路都可能产生外部复位。启动模式与复位原因说明

目前还不能确定唯一原因。建议先统一串口波特率、移除 LED 操作,再对比手动复位和定时唤醒,最后检查复位波形与供电。

先让启动日志和应用日志使用相同波特率

ESP8266 ROM 启动日志通常使用 74880 baud,原代码则使用 Serial.begin(115200)。因此,能读到启动日志,并不代表当前串口设置也能正确显示应用输出。Espressif 串口启动日志说明

排查时,把代码和串口监视器的波特率都设为 74880,并持续记录整个唤醒过程。你已经观察到 LED 也不再闪烁,因此检查波特率只能先排除日志显示的问题,还不能解释全部现象。

移除 LED 操作,检查 LED_BUILTIN 的实际引脚

D0 已连接 RST,测试代码不应再将 GPIO16 配置为普通输出并拉低,以免影响复位线路。

检查当前开发板配置中 LED_BUILTIN 的值。如果它等于 16,原来的闪灯代码就会操作连接 RST 的引脚。ESP8266 Arduino Core 当前的 NodeMCU 引脚定义默认将 LED_BUILTIN 设为 GPIO2,同时将辅助 LED 定义在 GPIO16。实际取值仍需以你安装的 Core 和所选开发板配置为准。NodeMCU 引脚定义

原代码在操作 LED 之前输出 BOOT OK。即使发现 LED 引脚冲突,仍需查明为什么没有看到这条输出,暂时不能把引脚冲突认定为全部原因。

使用不操作 GPIO 的最小程序做对照

下面的程序只保留串口和 Deep Sleep。测试时将串口监视器设为 74880,D0(GPIO16)连接 RST,不连接其他外设。

#include <Arduino.h>

constexpr bool USE_DEEP_SLEEP = true;

void setup()
{
  Serial.begin(74880);
  delay(2000);

  Serial.println();
  Serial.println("ENTER setup()");
  Serial.print("LED_BUILTIN GPIO = ");
  Serial.println(static_cast<unsigned int>(LED_BUILTIN));
  Serial.flush();

  if (!USE_DEEP_SLEEP) {
    return;
  }

  delay(2000);
  Serial.println("Going to sleep for 5 seconds...");
  Serial.flush();

  ESP.deepSleep(5000000ULL);
}

void loop()
{
  Serial.println("loop() is running");
  Serial.flush();
  delay(1000);
}

正常的定时唤醒需要 GPIO16 与 RST 连接,唤醒时通过复位重新启动程序。ESP8266 Arduino Core Deep Sleep 示例说明

这里将 5e6 写成 5000000ULL,是为了明确使用整数微秒值,并不能据此判定原来的 5e6 是故障原因。

分两轮测试:

  1. 将 USE_DEEP_SLEEP 改为 false,确认程序能持续输出。分别测试完全断电后上电和按 RST,观察两种启动方式是否都能进入 setup()。
  2. 改回 true,观察定时唤醒后是否重新打印 ENTER setup()。如果失败,再按一次 RST,记录手动复位能否恢复。

如果手动复位也失败,应先排查一般启动问题。如果手动复位正常,只有定时唤醒失败,则重点检查 GPIO16 到 RST 的唤醒路径及相关电路。

定时唤醒失败时,检查实际电平和完整日志

检查 RST、EN 和 3.3V

有示波器时,比较正常手动复位与失败唤醒时的波形,重点观察:

  • RST 是否出现复位脉冲,之后能否恢复并保持高电平。
  • EN 是否稳定,是否受到其他电路影响。
  • 3.3V 在唤醒和启动期间是否明显下跌。

更换 USB 线和端口只能排除部分供电因素,不能证明板载稳压器及芯片端电压始终稳定。万用表也可能漏掉短暂的电压跌落。

你已经试过加入和移除电阻。继续修改前,先确认电阻是串联在 GPIO16 与 RST 之间,还是作为 RST 上拉使用,并核对板上已有电路。两种接法的作用不同,不能仅凭“加了 1k 电阻”判断是否合适。

检查启动引脚与串口自动复位电路

正常从 Flash 启动时,启动采样要求 GPIO0、GPIO2 为高,GPIO15 为低。现有日志的第一个启动模式参数为 3,说明这次采样选择了 Flash 启动,但不能排除后续的供电或复位异常。ESP8266 启动引脚说明

CH340 的存在不能直接证明 USB 转串口芯片有故障。需要检查板上的 DTR/RTS 自动复位连接,以及串口软件是否改变了这些控制线。Espressif 文档说明,部分串口程序打开端口时会改变 DTR/RTS 状态,从而影响复位。自动复位电路说明

测试期间尽量保持串口监视器打开,关闭硬件流控,避免反复打开端口引入额外复位。

保存两行日志之后的内容

分别保存冷启动、手动复位和失败唤醒的完整日志,特别留意是否出现 load、校验相关输出、异常堆栈或重复启动信息。只有最前面的两行日志,无法区分 Flash 加载失败、启动中异常和复位循环。

硬件检查后仍无法定位怎么办?

记录准确的开发板型号、ESP8266 Arduino Core 版本、Flash 配置和完整启动日志,再在另一块已知正常的板上运行同一最小程序。

如果只有某块板失败,可以进一步核对其复位电路、供电和模块差异;如果多块板都失败,则继续检查共同的软件配置与测试方式。必要时,可在核实 Flash 容量和模式后重新烧录最小程序,但现有材料不足以指定某个 Core 版本、Flash 模式或电阻值作为确定的修复方案。

备注:内容仅供参考。