ESP8266 Using GPIO0/GPIO2/GPIO15 Pins





Introduction: ESP8266 Using GPIO0/GPIO2/GPIO15 Pins

Update 1st July 2018 -- Added note on re-programming when GPIO0 is an output

This is a very short note on how to use GPIO0 / GPIO2 and GPIO15 pins on the ESP8266 module.

Update: Also check out How to use the ESP8266-01 pins


ESP8266 is a low cost wifi enabled chip. It comes in a variety of module types and can be programmed in a variety of ways. All modules make GPIO0 and GPIO2 accessible. Most modules, other than ESP8266-01, also make GPIO15 accessible. These GPIO's control how the module starts up and as such require special handling if they are to be used at all. GPIO6-GPIO11 also require special treatment as described below.

Step 1: Flash GPIO Pins – GPIO6 to GPIO11

Most ESP8266 boards have a flash chip connected to some or all of GPIO6-GPIO11. Most programs use flash memory, as well as RAM, so unless you specifically make sure your code only runs from RAM, you can't use these pins for other purposes.

The exact number of pins used in the range GPIO6 to GPIO11 depends on the type of flash hardware used on your module. Quad IO uses 4 lines for data (6 pins total) for up to 4 times the speed of standard. Dual IO uses 2 lines for data (4 pins total) Standard uses a single line for data ( 3 pins total).

Unless you know exactly what your board requires, you are best to just ignore GPIO6 to GPIO11 and do not refer to them from your code.

Step 2: GPIO0, GPIO2 and GPIO15 Pins

These pins determine what mode the chip starts up in.

For normal program execution GPIO0 and GPIO2 need to be pulled up to Vcc (3.3V) and GPIO15 needs to be pulled to GND, each with a resistor in the range 2K to 10K resistor. A 2K resistor gives better noise immunity. OLIMEX uses 2K resistors SparkFun uses 10K resistors. I use 3K3 resistors.

The settings of these inputs is only checked during the power up (or reset) of the chip. After that the pins are available for general use, but as discussed below their use is restricted by these external pull up/down resistors.

Step 3: Using GPIO0, GPIO2 and GPIO15 As Outputs

As noted above, these pins will already have a resistor connected to either VCC (GPIO0 and GPIO2) or GND for GPIO15. This determines how any external device, like a relay or led+resistor, must be connected. For GPIO0 and GPIO2, an external relay must be connected between VCC and the pin so that it does not interfere with the action of the pull up resistor. Conversely an external relay connected to GPIO15 must be connected between GND and the pin so that is does not interfere with the action of the pull down resistor.

To activate the external device, GPIO0 or GPIO2 must be driven LOW (Active LOW) while GPIO15 must be driven HIGH (Active HIGH).

The schematic above shows how to use GPIO0 and GPIO2 and GPIO15 as outputs. This circuit includes the necessary pullup/pulldown resistors as well. Note the 5V relay module driven by GPIO0 is opto-isolated and has a separate common connection for the input. It is important that the 5V VCCA voltage is not applied to the ESP8266 pin.

How to reprogram when using GPIO0 as an output

Note: GPIO0 is needs to be grounded to get into programming mode. If you sketch is driving it high, grounding it can damage you ESP8266 chip. The safe way to reprogram the ESP8266 when your code drives the GPIO0 output is to :-
a) Power down the board
b) short GPIO0 to gnd
c) power up the board which goes into program mode due to the short on GPIO0
d) remove the short from GPIO0 so you don't short out the output when the program runs
e) reprogram the board
f) power cycle the board if necessary.

Step 4: Using GPIO0, GPIO2 and GPIO15 As Inputs.

Using these pins as inputs is a bit tricky. As noted above on power up, and during reset, these pins must be pulled up or down as required to have the ESP8266 module start up in normal running mode. This means, in general, you cannot just attach an external switch to the these pins because at power up you usually cannot guarantee the switch will not be pulling the input to ground and so prevent the module from starting correctly.

The trick is to not connect the external switch directly from the GPIO0 or GPIO2 to GND but to connect it instead to another GPIO pin which is driven to ground (as an output) only after the ESP8266 starts up. Remember, when used as outputs, the GPIO pins provide a very low resistance connection to either VCC or GND depending on whether they are driven HIGH or LOW.

Here only GPIO0 and GPIO2 will be considered. Using this method you can get one (1) addition input using these two (2) GPIO's.

A similar method can be used for GPIO15 by using another GPIO pin to connect its switch to +VCC, but this does not gain an extra input, you might as well just use the other GPIO pin directly as an input.

The circuit above uses the ESP8266-01 module as an example. Without using this trick, the ESP8266-01 does not have any free pins to use as an input if you are already using pins RX/TX for a UART connection.

Since the sketch's setup() method is only run after the ESP8266 module starts up, it is safe to make GPIO0 output LOW then and so provide a ground for S1 connected to GPIO2. You can then use digitalRead(2) elsewhere in your sketch to read the switch setting.


This short note shows how to used GPIO0, GPIO2 and GPIO15 as outputs and how to use get an extra input using GPIO0 and GPIO2 together.



    • Oil Contest

      Oil Contest
    • Clocks Contest

      Clocks Contest
    • Creative Misuse Contest

      Creative Misuse Contest

    17 Discussions


    Question 14 days ago

    I challenge you to show that GPIO0 can be used as an output and driven to LOW without issues. I tested several new ESP8266-12F and on every single one I get (70kHz) oscillations on its output. Even GPIO15 is working perfectly as an output.

    8 more answers

    I had a closer look at the ESP8266-01 that I used in ESP8266-01 Wifi Shield

    Just after the module powers up there is 50mS of 2.5kHz oscillations before the GPIO0 settles HIGH (due to the 3K3 external pullup resistor)

    Using the ESP8266 Arduino addon V2.4.1, I programmed that board with the standard Arduino IDE blink example with this code change

    int led = 0;

    i.e. driving GPIO0 on the ESP8266 and got a clean square wave output.

    So using GPIO0 for an output works fine for my ESP8266-01. I don't have a ESP8266-12F to test (which has more pins so less need to use GPIO0)

    So I don't know what the problem is with your chip.

    Some possibilities are

    i) it is continually rebooting and you are seeing the startup oscillations
    ii) you grounded the GPIO0 for reprogramming while the GPIO0 was still being driven high and low and so shorted out the GPIO0 output and damaged the chip

    The safe way to reprogram the ESP8266 when your code drives the GPIO0 output is to

    a) Power down the board
    b) short GPIO0 to gnd
    c) power up the board which goes into program mode due to the short on GPIO0
    d) remove the short from GPIO0 so you don't short out the output when the program runs
    e) reprogram the board
    f) power cycle the board if necessary.

    Please report back here if you get you board to work

    Hi, I checked again, with another brand new ESP8266-12F, this time using following manual programming procedure: at power up tie GPIO0 to GND, then remove GND connection (release floating), and download program. Then restart with GPIO0 connected with 3k3 to +3.3V. The output remains low!

    So no oscillations, (as I had with a 10k pullup), but no reaction at all.

    Your suggestions:

    i. no it is not rebooting continually because the other outputs work as expected

    ii. this was prevented with the latest new ESP8266-12F chip, so now guaranteed no jeopardising of chip output circuit


    1. 10k pullup causes oscillations when output is supposed to be low

    2. 3.3k pullup does not change the output state to anything but low

    I am lost now.

    Some progress! Your blink suggestion is excellent, I changed the program a bit to blink both GPIO 2 and 0, and now GPIO0 performs well.

    And then I discovered a defective component on the output stage of my development board.

    Conclusion: all works well, I made a mistake by not critically examining the fault symptoms. Thank you for your assistance!

    Yes, blink test is ok (uses GPIO2); I will do some more investigations and let you know

    Just now tested a brand new ESP8266-12F: manual download (wire GPIO0 to 0V, start up and download). Same issue. And when removing any load or pull up from GPIO0 it just stays low!

    I thought there is an internal pullup to GPIO0?

    You need pullups, as shown in steps 3 and 4 above for the ESP8266 to restart and run your sketch. BUT you need to ground GPIO0 when power is applied (or reset released) to get into programming mode.

    Hi, thanks for taking the time for such a complete response.

    By now I suspect an auto-reset circuit that I use in combination with a FTDI serial interface. The DTR isgnal is used to get the ESP8266-12F automatically in proramming mode in the following hardware fashion:

    1. GPIO0: Schottky diode, cathode to DTR and 330pF to ground

    2. CH_PD: Schottky diode, cathode to 3.3V and 100nF to DTR

    Reset to 3.3V over 10k.

    I will try and do programming the manual way on a new ESP8266-12F and report back here (as soon as I have time to do this).

    Taking GPIO2 as an example. Would it be possible to remove R2? Would LED1 and R6 pull GPIO2 high?

    1 more answer

    Most likely not. The led has voltage drop across it of a couple of volts and only conducts in one direction so not a good pullup for GPIO2

    Ill put a note here too . ESP-12 is just as cheap and much easier to work with .Go to for more recent updates and save yourself from working on outdated modules

    could you please tell me how can read pulses from gpio pin

    1 reply

    Thanks for referencing the pull-ups, it makes for a MUCH more reliable reset.

    This instructable has been completely re-written to using GPIO's as Outputs and Inputs