I got a bunch of $1 ESP-12F’s with the venerable ESP8266 for some projects and although there are some other posts out there that try to describe which pins to use for what purposes, I couldn’t find one detailed enough to meet my needs. So here’s my reference:
IMPORTANT NOTE: This post was never completed, but I’m publishing it anyway because I think it’s still a good framework for testing the pins.
Test Scenarios
I used these test scenarios. I’ll refer to them throughout.
- No software. This is just the device, straight out of the packaging.
- Empty Sketch. I use the “NodeMCU 1.0 (ESP-12E Module)” board when programming, using the default settings, including 80 MHz clock. I use this configuration for all the Arduino sketches.
- Outputs, LOW. The code sets all pins to OUTPUT and sets them all LOW with digitalWrite().
- Outputs, HIGH. The code sets all pins to OUTPUT and sets them all High with digitalWrite().
- Outputs, PWM. The code sets all pins to OUTPUT and sets them all to PWM with analogWrite(). The PWM range is from 0-1023.
- Inputs, No Pull. The code sets all pins to INPUT but does not specify a pullup, with these exceptions:
- 1, 3: For GPIO 1 (TX) and 3 (RX), I first call pinMode() using FUNCTION_3 to set them to GPIOs.
- Inputs, Pulled. The code sets all pins to INPUT_PULLUP, with these exceptions:
- 1, 3: For GPIO 1 (TX) and 3 (RX), I first call pinMode() using FUNCTION_3 to set them to GPIOs.
- 16: For GPIO16, I set the pint to INPUT_PULLDOWN_16 instead of INPUT_PULLUP.
I test each of these in the following configurations:
- Frog board (“Frog”). Running on a common development board, connected to USB.
- Production (“Prod”). Running in my standard operating configuration, which includes
- 10k pull-up on EN,
- 10k pull-up on GPIO0, and
- 10k pull-down on GPIO15
GPIO0 (D3)
GPIO0 behaves pretty much the same way in all cases at boot. About 35ms after power is applied, we get what looks from this distance to be a 1.86ms period (537Hz) PWM signal at about a 66% duty cycle, but when you zoom in, it’s a bit more nuanced, with a couple extra toggles at the beginning of each period. That goes on for about 44ms, and then at about 80ms, it goes LOW for 8ms, then toggles again for 2ms before settling HIGH at 90ms. The effects of the actual code can be seen at about 130ms (where here I’m setting the value LOW).
GPIO0 Function | Frog | Prod |
---|---|---|
Digital Out | Y | |
Analog Out (PWM) | Y | |
Digital In | Y | |
Start State | HIGH | |
Unstable starting (duration) | 35ms (55ms) | |
Stable starting (duration) | 90ms (40ms) | |
Stable state | HIGH | |
Responsive starting | 130ms | |
Held HIGH at boot | Normal | |
Held LOW at boot | Upload Mode | |
Interrupt | Y |
GPIO1 (D10, TX)
This pin behaves the same at boot in all cases, starting HIGH and then varying for 62ms in two bursts — the first lasting 11ms and the second starting 4ms later and lasting 7ms. The pin then settles HIGH until it becomes responsive at about 130ms. The GPIO2 pin behaves identically.
The first burst is UART at about 75k baud that says the following. (Line breaks are all CRLFs, except where noted.) The “rst cause:2” means the reset pin was used, and boot mode apparently means FLASH, and SDIO LowSpeed V2 IO, according to https://esp8266.ru/esp8266-pin-register-strapping/.
ets Jan 8 2013,rst cause:2, boot mode:(3,4)
load 0x4010f000, len 3584, room 16
The second burst is at the same baud rate and says:
tail 0
chksum 0xb0
csum 0xb0
v2843a5ac
~ld[0A]
GPIO1 serves as the TX pin, so to use it as a GPIO, you needs to first use pinMode() with FUNCTION_3.
GPIO1 Function | Frog | Prod |
---|---|---|
Digital Out | Y* | |
Analog Out (PWM) | Y* | |
Digital In | Y | |
Start State | HIGH | |
Unstable starting (duration) | 40ms (22ms) | |
Stable starting (duration) | 62ms (28ms) | |
Stable state | HIGH | |
Responsive starting | 130ms | |
Held HIGH at boot | ||
Held LOW at boot | ||
Interrupt |
* Use pinMode() with FUNCTION_3 to change this pin to a GPIO. You will not be able to use UART TX/RX, but the chip will still be programmable when reset into upload mode.
GPIO2 (D4)
This pin behaves the same at boot in all cases, starting HIGH and then varying for 62ms in two bursts — the first lasting 11ms and the second starting 4ms later and lasting 7ms. The pin then settles HIGH until it becomes responsive at about 130ms. The GPIO1 pin behaves identically.
The UART signal is sent to this pin as well as GPIO1 (TX), according to https://github.com/espressif/esptool/wiki/ESP8266-Boot-Mode-Selection.
GPIO2 Function | Frog | Prod |
---|---|---|
Digital Out | Y | |
Analog Out (PWM) | Y | |
Digital In | Y | |
Start State | HIGH | |
Unstable starting (duration) | 40ms (22ms) | |
Stable starting (duration) | 62ms (28ms) | |
Stable state | HIGH | |
Responsive starting | 130ms | |
Held HIGH at boot | ||
Held LOW at boot | ||
Interrupt |