Whilst looking for something I could do with an ESP-01 and sleeping/batteries, I found this, which itself was inspired by this (which I couldn’t get to work!)

Essentially you power on the ESP-01 by pressing a button. Now whilst that sounds lame, the clever part is that once its on, you can do whatever you like e.g. post to a website, and then turn the unit back off (by setting GPIO2 and CH_PD low) until the button is pressed again.

This is actually better than the sleep routines as it essentially cuts power to the chip, rather than just putting it into a low power sleep. You could replace the button with a reed switch or PIR, any sensor that can make a high signal.

The only issue I found is that you need to keep the signal high for a second or so, a quick button press doesn’t work, so I added a 10uF capacitor between the diode and GND to slowly discharge the signal sent to the microcontroller, and now I can press the button as fast as I like.

When asleep the entire circuit uses 370uA (most of which is probably the power LED) and when wifi is on it uses 70mA, which seems unlikely as I’ve seen wifi spike to 300mA on an ESP-12, but maybe that’s only in client mode not server? I’ve removed the two LED’s and their series resistors with a screwdriver and now sleep current is down to 18uA, wake current is about the same oddly enough, but my bench supply and multimeter say the same for wake, so it must be about right.


I used Arduino style C++ instead of Lua, my version serves up a web page when the button is pressed, and you can power it off by submitting the form:

// include libraries
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

// configure server
ESP8266WebServer server(80);

void handle_form()
    if (server.arg("stop") == "stop")
        // set ch_pd and gpio2 low
        server.send(200, "text/html", "Shutting down");
        digitalWrite(2, LOW);
        // send the form
        server.send(200, "text/html", "<form action='/'><input type='submit' value='stop' name='stop'></form>");

void setup()
    // set gpio2 high to keep chip on even if CH_PD goes low
    pinMode(2, OUTPUT);
    digitalWrite(2, HIGH);

    // ssid, password, ip, gateway, netmask
    WiFi.begin("essid", "password");
    WiFi.config(IPAddress(192,168,1,111), IPAddress(192,168,1,1), IPAddress(255,255,255,0));

    // connect
    while (WiFi.status() != WL_CONNECTED)

    // setup callback
    server.on("/", handle_form);

    // start the webserver

void loop()

I also made a Makefile so I could use arduino-builder instead of the IDE:

ARDUINO_PATH = $(HOME)/arduino-1.6.6
SKETCHBOOK = $(HOME)/sketchbook
ESPTOOL = $(SKETCHBOOK)/hardware/esp8266com/esp8266/tools/esptool/esptool
SKETCH = $(notdir $(CURDIR)).ino
TARGET_DIR = $(CURDIR)/build-esp8266

	@ mkdir -p $(TARGET_DIR)

	$(ARDUINO_PATH)/arduino-builder -compile -logger=machine \
	-hardware "$(ARDUINO_PATH)/hardware" \
	-hardware "$(SKETCHBOOK)/hardware" \
	-tools "$(ARDUINO_PATH)/tools-builder" \
	-tools "$(ARDUINO_PATH)/hardware/tools/avr" \
	-built-in-libraries "$(ARDUINO_PATH)/libraries" \
	-libraries "$(SKETCHBOOK)/libraries" \
	-fqbn=esp8266com:esp8266:generic:UploadTool=esptool,CpuFrequency=80,FlashFreq=40,FlashMode=dio, \
         UploadSpeed=115200,FlashSize=512K64 \
	-ide-version=10606 \
	-build-path "$(TARGET_DIR)" \
	-warnings=none \
	-prefs=build.warn_data_percentage=75 \
	-verbose "$(SKETCH)"

	$(ESPTOOL) -v -cd ck -cb 115200 -cp $(MONITOR_PORT) -ca 0x00000 -cf $(TARGET_DIR)/$(SKETCH).bin 

upload: all flash

	rm -rf $(TARGET_DIR)

	screen $(MONITOR_PORT) 9600