Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.
Boot · ESP8266 deep sleep

Fix: ESP8266 deep sleep never wakes up (ESP.deepSleep)

ESP.deepSleep() needs GPIO16 (D0) wired to RST to wake. Add the wire (or close the D1 mini SLEEP jumper), and remove it while uploading if uploads fail.

NodeMCU ESP8266Wemos D1 miniESP-12E/FESP-01Updated 3 Nov 2026

Community draft — report a mistake

What you see

OutputOutput
Going to sleep for 60 seconds...
(nothing — the board stays asleep until RESET is pressed)

--- after wiring D0 to RST, at 74880 baud ---
 ets Jan  8 2013,rst cause:5, boot mode:(3,6)
...
Reset reason : 5 = Deep-Sleep Wake

ESP.deepSleep() switches off almost everything except a small timer. On the ESP8266 that timer can’t restart the CPU directly. It drives GPIO16 low, and only a wire from GPIO16 (D0) to the RST pin turns that into a reset that wakes the chip.

Without the wire the board sleeps until you press RESET. Add the D0-to-RST link and it wakes on schedule, with rst cause:5 in the boot log.

Quick fix — try in order

  1. 1

    Connect D0 (GPIO16) to RST

    During deep sleep only the RTC runs. When the timer expires it pulses GPIO16 low; that pulse must reach the RST pin to restart the chip. NodeMCU: a jumper wire D0 → RST. D1 mini: the same wire, or bridge the “SLEEP” solder jumper on boards that have one.

  2. 2

    Remove the wire while uploading if needed

    On some boards the D0–RST link interferes with auto-reset and uploads fail. Unplug it, upload, plug it back. A 470 Ω–1 kΩ resistor instead of a plain wire also helps.

  3. 3

    Stay under the maximum sleep time

    The timer overflows after roughly 3.5 hours. Use ESP.deepSleep(ESP.deepSleepMax()); as the longest; for longer periods wake, count and sleep again.

  4. 4

    Check the wake reason with the diagnostic sketch

    After a timed wake it reports “Deep-Sleep Wake”. If it says “External System” the wake came from a button on RST instead.

  5. 5

    ESP-01: no GPIO16 on the header

    GPIO16 isn't brought out on the ESP-01. It needs a fine wire soldered to the chip's pin 8 — or use a D1 mini instead.

Diagnostic sketch

Verified — core esp8266 3.1.2, 3 Nov 2026Compile-only
esp8266-reset-info.inoArduino C++Open in PlaygroundOpen in Playground
// FlashReady diagnostic: why did my ESP8266 reset?
// Prints the SDK reset reason (with the exception details after a crash), the real flash
// chip size versus the size chosen in Tools -> Flash Size, then a heartbeat every 5 s.
// Open Serial Monitor at 115200. The ROM's own boot line ("rst cause:..") is printed at 74880
// baud and shows up as a few garbage characters first - that is normal.
#include <user_interface.h>

void setup() {
  Serial.begin(115200);
  delay(200);
  Serial.println();
  Serial.println("=== FlashReady ESP8266 reset report ===");
  rst_info *info = ESP.getResetInfoPtr();
  // SDK numbering: 0 power-on, 1 hardware WDT, 2 exception, 3 soft WDT, 4 soft restart,
  // 5 deep-sleep wake, 6 external reset (RST pin). Not the same numbers as the ROM's "rst cause".
  Serial.printf("Reset reason : %u = %s\n", info->reason, ESP.getResetReason().c_str());
  Serial.printf("Reset info   : %s\n", ESP.getResetInfo().c_str());
  if (info->reason == REASON_EXCEPTION_RST) {
    Serial.printf("Exception    : (%u) at epc1=0x%08x - paste the stack into the Exception Decoder\n",
                  info->exccause, info->epc1);
  }

  uint32_t real = ESP.getFlashChipRealSize();
  uint32_t ide = ESP.getFlashChipSize();
  Serial.printf("Flash (chip) : %u KB (id 0x%06x)\n", real / 1024, ESP.getFlashChipId());
  Serial.printf("Flash (IDE)  : %u KB\n", ide / 1024);
  if (real != ide) {
    Serial.println("WARNING      : Tools -> Flash Size does not match the chip. Fix it and re-upload.");
  }
  Serial.printf("Core / SDK   : %s / %s\n", ESP.getCoreVersion().c_str(), ESP.getSdkVersion());
  Serial.printf("Free heap    : %u bytes\n", ESP.getFreeHeap());
  Serial.println("=======================================");
}

void loop() {
  static uint32_t last = 0;
  if (millis() - last >= 5000) {
    last = millis();
    Serial.printf("alive, uptime %lu s\n", millis() / 1000);
  }
}

Why it happens

Why doesn't the ESP8266 wake by itself?

Unlike the ESP32, the ESP8266 has no internal wake path from deep sleep. The RTC timer can only drive GPIO16, and only a reset restarts the CPU — hence the external D0-to-RST link.

It wakes but the battery still drains fast

NodeMCU boards keep the CH340 and AMS1117 regulator powered, drawing several mA. For battery projects use a bare ESP-12 or a D1 mini with a low-quiescent regulator.

Never put D0 on a button

With D0 wired to RST, using D0 as an input or output resets the board. Leave it for deep sleep only.

Board-specific notes

Wemos D1 mini: See the D1 mini page for where D0 and RST are on the header.

↑↓ to move · Enter to open