The Wemos D1 Mini, sold by LOLIN and by many clone makers, is about as small as a full ESP8266 development board gets. It carries an ESP-12F module, a USB-to-serial chip and a 3.3 V regulator on a board roughly 34 × 26 mm, with 16 pins along its edges that fit a breadboard or a stack of Wemos shields.
It is also easy to wire wrong. The labels printed beside the pins, D0 to D8, are not the GPIO numbers the ESP8266 uses internally, and three of those pins are read by the chip while it boots. Get either detail wrong and the board misbehaves in ways that look like software bugs: a relay that clicks at power-up, a sketch that never starts, a sensor read from the wrong pin.
This guide walks through the board pin by pin: the D-pin to GPIO mapping, power, digital I/O and the boot pins, PWM and interrupts, UART, SPI, I2C and the single analog input, followed by a complete pin table to keep open while you wire. If you have used a NodeMCU, most of it will look familiar, and the differences are called out.
What's Actually on the Board
The D1 Mini is built around the ESP8266EX inside an ESP-12F module: a 32-bit core running at 80 MHz (it can be raised to 160 MHz), built-in 2.4 GHz WiFi, and typically 4 MB of flash. There is no Bluetooth. Logic is 3.3 V throughout. A CH340 chip handles USB-to-serial, so uploads and the Serial Monitor work over the micro-USB port, although Windows and older macOS releases may need the CH340 driver first.
Sixteen pins run along the two edges: nine digital I/O (D0–D8), TX and RX, one analog input (A0), and the power and reset pins. That is fewer than the chip offers. GPIO6 to GPIO11 are wired to the flash memory inside the module, so they are unavailable on every ESP8266 board.
Two Numbering Systems on One Board
The silkscreen uses Wemos's own D0–D8 labels, while the ESP8266 datasheet and low-level code use GPIO numbers. They do not line up in order: D1 is GPIO5, D2 is GPIO4, D3 is GPIO0, and so on. The Arduino core for ESP8266 defines constants D0 to D8 for this board, so digitalWrite(D1, HIGH) reaches GPIO5 without any translation on your part. The trap runs the other way: a bare number in your code is a GPIO number, so digitalWrite(1, HIGH) reaches GPIO1, which is the TX pin.
| Label | GPIO | Default role |
|---|---|---|
| D0 | GPIO16 | Deep-sleep wake |
| D1 | GPIO5 | I2C SCL |
| D2 | GPIO4 | I2C SDA |
| D3 | GPIO0 | Boot mode select |
| D4 | GPIO2 | Onboard LED, boot pin |
| D5 | GPIO14 | SPI SCK |
| D6 | GPIO12 | SPI MISO |
| D7 | GPIO13 | SPI MOSI |
| D8 | GPIO15 | SPI CS, boot pin |
| TX | GPIO1 | UART TX |
| RX | GPIO3 | UART RX |
| A0 | ADC0 | Analog input |
Power Pins
| Pin | Description |
|---|---|
| 5V | Power input to the regulator. Carries USB voltage when the board is USB-powered |
| 3V3 | 3.3 V output from the onboard regulator |
| G | Ground (the only one on the board) |
| RST | Reset. Pull LOW to restart the chip |
All logic is 3.3 V, and no pin is 5 V tolerant. Connecting a 5 V signal directly to a GPIO, whether it is a 5 V Arduino output or the data line of a 5 V sensor, can damage the pin. Use a level shifter, or a voltage divider for one-way signals such as a sensor output.
The 5V pin is a power pin, not a logic pin. You can power the board through it from a 5 V supply, and the regulator steps that down to 3.3 V. When the board runs from USB, the same pin carries the USB voltage and can feed a small 5 V module. Avoid connecting a separate supply to 5V while USB is plugged in.
The 3V3 pin is limited by the regulator. Current LOLIN boards use a regulator rated for roughly 500 mA, and clones vary. WiFi transmit bursts alone can draw well over 100 mA, so what is left for sensors and modules is smaller than it looks.
There is only one ground pin. A project with several modules needs a shared ground rail on the breadboard. Chaining every ground back through the board's single G pin is asking for noise and voltage drop.
Digital I/O Pins (D0–D8)
Nine general-purpose pins, each configured with pinMode() and switching between 0 V and 3.3 V. Espressif's datasheet puts the drive strength at around 12 mA per pin, well below the 20 mA an Uno pin can handle. Treat 12 mA as the ceiling. A single LED with a 330 Ω resistor is fine, but relays, buzzers and motors need a transistor or MOSFET.
The Boot Pins: D3, D4 and D8
Every time the ESP8266 resets, it reads three pins to decide how to start.
| Pin | GPIO | Level needed at reset | If it is wrong |
|---|---|---|---|
| D3 | GPIO0 | HIGH | LOW at reset enters flash mode, so your sketch does not run |
| D4 | GPIO2 | HIGH | LOW at reset can stop the boot |
| D8 | GPIO15 | LOW | HIGH at reset stops the chip booting from flash |
The board's own resistors set the defaults, so a bare D1 Mini boots normally. Trouble starts when something you add pulls one of these pins the other way at power-up: a relay module with an active-low input on D3, a sensor that holds D8 high, a leftover pull-down resistor on D4. The symptom is a board that uploads fine over USB but will not run your sketch after a reset.
D4 also drives the onboard LED, which is active-low: writing LOW turns it on and HIGH turns it off. It flickers briefly during boot, before your code runs.
D0 (GPIO16): The Odd One Out
D0 sits in a different part of the chip, the RTC domain, and behaves differently from every other GPIO. It has no PWM, no interrupts, no I2C, and no INPUT_PULLUP, although INPUT_PULLDOWN_16 gives it a pull-down. It works fine for plain digital input and output. Its real job is deep sleep: when the sleep timer expires, the chip wakes by pulling GPIO16 LOW, and the board only restarts if D0 is wired to RST.
Without that wire, the sketch runs, the board goes to sleep, and it never wakes. Some boards also refuse to upload while D0 is connected to RST, so disconnect the wire when flashing.
PWM and Interrupts
PWM. The ESP8266 has no hardware PWM. analogWrite() generates software PWM on any GPIO from 0 to 15, so D1 to D8 all work and D0 does not. Software PWM depends on timers, so it can jitter when WiFi is busy. That is fine for dimming an LED and a poor choice for servo timing or audio. The default range and frequency depend on your core version, and analogWriteRange() and analogWriteFreq() change them.
Interrupts. attachInterrupt() works on every GPIO except D0. Interrupt handlers must live in IRAM, so mark them with IRAM_ATTR (older cores use ICACHE_RAM_ATTR). Without it, the board can crash the moment the interrupt fires. Keep handlers short, and leave delay() and Serial calls out of them.
UART: TX, RX and Serial1
UART0 sits on TX (GPIO1) and RX (GPIO3), shared with the CH340 that handles uploads and the Serial Monitor. Three consequences follow:
- Peripherals on TX and RX interfere with uploads. Disconnect a GPS or Bluetooth module while flashing.
- Boot messages look like garbage. At every reset the ESP8266 prints a burst of diagnostics at 74880 baud. In a Serial Monitor set to 115200 they appear as random characters before your sketch's output starts. It is harmless, and setting the monitor to 74880 shows them readably.
Serial.swap()moves UART0 to D7 (RX) and D8 (TX). This frees the USB serial pins for other use, but you lose USB serial output while it is active.
There is also Serial1, a transmit-only UART on D4 (GPIO2). It is useful for debug logging while UART0 talks to another device, and the onboard LED flickers as it transmits.
SPI Pins
| Pin | Function | GPIO |
|---|---|---|
| D5 | SCK (clock) | GPIO14 |
| D6 | MISO | GPIO12 |
| D7 | MOSI | GPIO13 |
| D8 | CS (chip select) | GPIO15 |
These four form the ESP8266's hardware SPI bus, which is much faster than software SPI on arbitrary pins. It suits SD cards, TFT displays and radio modules. The catch is D8: as a boot pin it must be LOW at reset, and some SD card modules pull their CS line high. Because the SPI library lets you choose any pin for chip select, moving CS to D1 or D2 avoids the conflict entirely.
I2C Pins
| Pin | Function | GPIO |
|---|---|---|
| D1 | SCL (clock) | GPIO5 |
| D2 | SDA (data) | GPIO4 |
The ESP8266 has no hardware I2C. The Wire library bit-bangs the bus on whichever two pins you give it, and D1 and D2 are its defaults for the D1 Mini. Most breakout boards carry their own pull-up resistors. Bare I2C chips need 4.7 kΩ pull-ups to 3.3 V. The bus runs at 3.3 V, so a 5 V-only I2C module needs a level shifter.
Analog Input (A0)
The D1 Mini has one 10-bit ADC pin, returning 0 to 1023. The bare ESP8266 ADC only accepts 0 to 1 V, but the D1 Mini adds a resistor divider so A0 accepts up to 3.2 V. Each step is about 3.1 mV.
Most D1 Mini boards include that divider, but check a clone before connecting anything above 1 V, because feeding more than the chip allows can damage the ADC. Never connect a 5 V signal. Readings can also drift while WiFi is transmitting. If you need a second analog input, add an external ADC such as the ADS1115 over I2C, since the chip has no other analog pin.
Complete Pin Table
With the antenna at the top and the USB port at the bottom, the left header runs RST, A0, D0, D5, D6, D7, D8 and 3V3 from top to bottom. The right header runs TX, RX, D1, D2, D3, D4, G and 5V.
| Pin | GPIO | Functions | Boot and notes |
|---|---|---|---|
| RST | n/a | Reset input | Pull LOW to reset. D0 connects here for deep sleep |
| A0 | ADC0 | Analog input, 0–3.2 V | The only ADC pin |
| D0 | GPIO16 | Digital I/O, deep-sleep wake | No PWM, interrupts or I2C |
| D5 | GPIO14 | SPI SCK, PWM, interrupt | No boot restriction |
| D6 | GPIO12 | SPI MISO, PWM, interrupt | No boot restriction |
| D7 | GPIO13 | SPI MOSI, PWM, interrupt | No boot restriction. UART0 RX when swapped |
| D8 | GPIO15 | SPI CS, PWM, interrupt | Must be LOW at boot. UART0 TX when swapped |
| 3V3 | n/a | 3.3 V output | Limited by the regulator |
| TX | GPIO1 | UART0 TX | USB serial, boot messages |
| RX | GPIO3 | UART0 RX | USB serial |
| D1 | GPIO5 | I2C SCL, PWM, interrupt | No boot restriction |
| D2 | GPIO4 | I2C SDA, PWM, interrupt | No boot restriction |
| D3 | GPIO0 | PWM, interrupt | Must be HIGH at boot. LOW enters flash mode |
| D4 | GPIO2 | Onboard LED, Serial1 TX, PWM, interrupt | Must be HIGH at boot. LED is active-low |
| G | n/a | Ground | The only one on the board |
| 5V | n/a | 5 V power input | Not a logic pin |
Wemos shields stack onto these same pins, and each one claims specific pins. The relay shield typically uses D1, the DHT shield D4, the OLED shield the I2C pair D1 and D2, and the micro SD shield the SPI pins with CS on D8. Check the shield's documentation before combining several.
Practical Pin Usage Tips
Start with D1, D2, D5, D6 and D7. They have no boot restrictions and no special hardware quirks, and most projects fit on these five.
Treat D3, D4 and D8 as conditional. Use them only for signals that sit in a safe state at power-up, or put the load on a different pin. For a relay, D1 is usually the safer choice.
Write D-constants, not numbers. D2 in code means GPIO4. A bare 2 means GPIO2, which is D4.
Save D0 for deep sleep or simple outputs. A status LED is a good fit. Anything needing PWM or an interrupt belongs elsewhere.
Plan around one analog input. Multiplexing several sensors into A0 works, and an ADS1115 is the cleaner fix.
Give heavy loads their own supply. A pin's 12 mA and the shared regulator are easy to exceed with motors, LED strips or servos. Connect the grounds together.
Keep TX and RX free while flashing. Anything wired there competes with the USB chip.
Common Mistakes and How to Avoid Them
Using a GPIO number where a D-pin was meant. digitalWrite(1, HIGH) toggles TX, not D1. Use the D-constants.
Connecting 5 V to a GPIO or to A0. Nothing on this board is 5 V tolerant, and A0 tops out at 3.2 V.
Loading D3, D4 or D8 at power-up. A relay input, a pull-down resistor or a sensor holding the line the wrong way stops the board booting.
Forgetting the D0 to RST wire, or leaving it on during upload. Deep sleep without it never wakes, and with it some boards fail to flash.
Assuming boot garbage means a fault. The 74880-baud boot message is normal.
Summary: D1 Mini Pin Reference at a Glance
| Feature | Detail |
|---|---|
| Header pins | 16 |
| Usable GPIO | 11 (D0–D8, TX, RX) |
| Analog input | 1 (A0, 10-bit, 0–3.2 V) |
| PWM | Software PWM on all GPIO except D0 |
| Interrupts | All GPIO except D0 |
| UART | UART0 on TX/RX, Serial1 transmit-only on D4 |
| SPI | Hardware SPI on D5–D8 |
| I2C | Software, default D1 (SCL) and D2 (SDA) |
| Boot pins | D3 HIGH, D4 HIGH, D8 LOW |
| Logic level | 3.3 V, not 5 V tolerant |
| Drive current | About 12 mA per pin |
| CPU and flash | 80 MHz (160 MHz optional), typically 4 MB |
| Power input | 5 V via micro-USB or the 5V pin |
| USB chip | CH340 |
| Wireless | 2.4 GHz WiFi |
The D1 Mini rewards a little planning. Once the D-pin mapping and the three boot pins are habits, it is one of the cheapest and most compact ways to put a project on WiFi.
Wemos D1 Mini · ESP8266 (ESP-12F) · 11 GPIO · 1 Analog Input · WiFi · 3.3 V Logic · Software PWM
Quick Answers to Common D1 Mini Pin Questions
Why is D1 not GPIO1? The D-labels are Wemos's own and follow board layout, not chip numbering. D1 is GPIO5, and GPIO1 is the TX pin.
Which pins are safe for general use? D1, D2, D5, D6 and D7 have no boot restrictions. D0 works for simple digital I/O as well.
Can I use D0 for PWM or interrupts? No. GPIO16 supports neither. Use any other D-pin.
Is the onboard LED active-high or active-low? Active-low, on D4. Writing LOW turns it on.
Is any pin 5 V tolerant? No. Every GPIO is 3.3 V only, and A0 accepts up to 3.2 V.
Why did my board stop booting after I wired something to D3, D4 or D8? Those are boot pins. A wrong level at reset changes how the chip starts. Remove the connection, confirm it boots, then move the load to D1, D2, D5, D6 or D7.
How many analog inputs does it have? One, on A0. Add an external ADC for more.
How does the D1 Mini compare with a NodeMCU? Same chip, and D0 to D8 map to the same GPIOs on both. The NodeMCU is larger and breaks out a few extra pins, while the D1 Mini is smaller and stacks with Wemos shields.
Where to Go From Here
The NodeMCU ESP8266 pinout guide covers the larger board with the same pin logic, and the ESP8266 Arduino IDE setup guide gets the toolchain working. For a first WiFi build, try Control an LED Over Wi-Fi Using NodeMCU ESP8266. When you outgrow the ESP8266, the ESP32 pinout guide is the natural next step, and the ESP32 deep sleep guide covers battery power in more depth.



