Overview
The ESP-01 (also called ESP-01S) is a tiny Wi-Fi module built around the Espressif ESP8266EX SoC. It originally shipped to add Wi-Fi to existing Arduino projects via AT commands over a UART, and it's still the cheapest way to drop 2.4 GHz Wi-Fi into a microcontroller project. The board exposes 8 pins on a 2x4 header: VCC, GND, CH_PD (chip enable), Reset, GPIO0, GPIO2, plus UART TX/RX.
Out of the box, the ESP-01 runs Espressif's AT command firmware — perfect for sending commands like AT+CWJAP="ssid","password" from an Arduino. With a USB-to-serial adapter you can also reflash it with custom firmware: NodeMCU/Lua, MicroPython, or your own Arduino/PlatformIO project. The module has 1 MB of flash (the original ESP-01 had 512 KB).
Two important quirks: the ESP-01 is strictly 3.3V — never feed it 5V — and it draws brief peaks of 300+ mA during Wi-Fi transmission. A bench supply or a beefy LDO is mandatory; do not power it from an Arduino's 3.3V regulator.
At a Glance
Specifications
| Parameter | Value |
| SoC | Espressif ESP8266EX (32-bit Tensilica L106) |
| Clock Frequency | 80 MHz (default), 160 MHz max |
| Flash Memory | 1 MB (ESP-01S) or 512 KB (older ESP-01) |
| Wireless | Wi-Fi 802.11 b/g/n, 2.4 GHz |
| Antenna | On-board PCB trace |
| Operating Voltage | 3.0 - 3.6V (3.3V nominal) |
| Average Current | ~80 mA |
| Peak Current (TX) | ~300 mA |
| Logic Level | 3.3V (NOT 5V tolerant) |
| GPIO | 2 (GPIO 0, GPIO 2) + UART TX/RX |
| Default Firmware | Espressif AT command set |
| Default Baud Rate | 115200 (varies by AT firmware) |
| Pin Header | 2x4, 2.54 mm pitch |
| Dimensions | ~24 x 14 mm |
Pinout Diagram
Wiring Guide
Arduino - Talk via AT Commands
Wire the ESP-01 as an AT-command Wi-Fi peripheral over a software-serial UART. The ESP-01 is 3.3V only, so you MUST level-shift the Arduino's 5V TX line before it reaches the module's RX pin.
| ESP-01 Pin | Arduino Pin | Details |
|---|---|---|
| VCC | External 3.3V supply | ~300 mA capable, NOT Arduino's 3.3V pin |
| GND | Common GND | Tie to Arduino GND |
| CH_PD (CH_EN) | 3.3V (with 10k pull-up) | Must be HIGH to enable |
| Reset | 3.3V (with 10k pull-up) | Optional - leave high for normal run |
| GPIO0 | 3.3V (with 10k pull-up) | HIGH = run; LOW at boot = flash mode |
| GPIO2 | Not connected (or 3.3V) | |
| TX (U0TXD) | Arduino D2 (RX of SoftwareSerial) | 3.3V signal, safe for Arduino |
| RX (U0RXD) | Arduino D3 (TX of SoftwareSerial) | Through 1k/2k divider |
Reflash the ESP-01 Over USB
To flash custom firmware (Arduino, MicroPython, NodeMCU, Tasmota, etc.) you need a USB-to-serial adapter (CP2102, FT232RL, etc.) running at 3.3V logic levels. GPIO0 must be LOW at power-on to enter flash mode.
| ESP-01 Pin | USB Adapter / Other | Details |
|---|---|---|
| VCC | 3.3V supply | External; not adapter's 3.3V if low-current |
| GND | Adapter GND | |
| CH_PD | 3.3V via 10k pull-up | |
| GPIO0 | GND (during flashing) | Tie to GND, then power on |
| GPIO2 | Leave open | |
| RST | 3.3V via 10k pull-up | Briefly to GND to reset |
| TX | Adapter RX | |
| RX | Adapter TX | Adapter must be 3.3V logic |
Raspberry Pi - Talk via AT Commands
The Raspberry Pi UART runs at 3.3V, so you can wire it directly without level shifting. Disable the Linux serial console first (raspi-config) so you have exclusive access to /dev/ttyAMA0 (or /dev/serial0).
| ESP-01 Pin | Pi Pin |
|---|---|
| VCC | External 3.3V supply |
| GND | Pi GND (Pin 6) |
| CH_PD | 3.3V via 10k |
| RX (U0RXD) | Pi TX (Pin 8 / GPIO 14) |
| TX (U0TXD) | Pi RX (Pin 10 / GPIO 15) |
sudo raspi-config > Interface Options > Serial Port. Disable the login shell, enable the serial port hardware. Reboot. Then talk to the ESP-01 with screen /dev/serial0 115200.
Raspberry Pi Pico - Talk via AT Commands
The Pico has two hardware UARTs at 3.3V — perfect for the ESP-01. Use UART0 on GP0/GP1 or UART1 on GP4/GP5.
| ESP-01 Pin | Pico Pin |
|---|---|
| VCC | External 3.3V supply (or VBUS via an LDO) |
| GND | Pico GND |
| CH_PD | 3.3V via 10k |
| TX (U0TXD) | GP1 (UART0 RX) |
| RX (U0RXD) | GP0 (UART0 TX) |
Code Examples
Arduino - AT Command Pass-Through
// Arduino - manually talk to the ESP-01 from the Serial Monitor
// Open Serial Monitor at 9600, set "Both NL & CR" so AT commands end correctly
// Try: AT, AT+GMR (firmware version), AT+CWLAP (scan APs)
#include <SoftwareSerial.h>
SoftwareSerial esp(2, 3); // RX = D2, TX = D3 (through divider)
void setup() {
Serial.begin(9600);
esp.begin(9600); // some AT firmwares default to 115200; try both
Serial.println("ESP-01 AT pass-through. Type commands above.");
}
void loop() {
while (esp.available()) Serial.write(esp.read());
while (Serial.available()) esp.write(Serial.read());
}
Arduino - Connect to Wi-Fi via AT
// Arduino - join a Wi-Fi network using ESP-01 AT commands
#include <SoftwareSerial.h>
SoftwareSerial esp(2, 3);
void send(const char* cmd, unsigned long ms = 2000) {
Serial.print("> "); Serial.println(cmd);
esp.println(cmd);
unsigned long start = millis();
while (millis() - start < ms) {
while (esp.available()) Serial.write(esp.read());
}
Serial.println();
}
void setup() {
Serial.begin(9600);
esp.begin(9600);
delay(500);
send("AT");
send("AT+CWMODE=1"); // station mode
send("AT+CWJAP=\"YOUR_SSID\",\"YOUR_PASSWORD\"", 8000); // join network
send("AT+CIFSR"); // print IP
}
void loop() {}
Arduino - HTTP GET via AT
// Arduino - simple HTTP GET via ESP-01 AT commands
// Assumes the ESP-01 is already joined to Wi-Fi
#include <SoftwareSerial.h>
SoftwareSerial esp(2, 3);
void send(const String &cmd, unsigned long ms = 2000) {
esp.println(cmd);
unsigned long start = millis();
while (millis() - start < ms) {
while (esp.available()) Serial.write(esp.read());
}
}
void setup() {
Serial.begin(9600);
esp.begin(9600);
delay(500);
send("AT+CIPSTART=\"TCP\",\"example.com\",80", 4000);
String req = "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n";
send("AT+CIPSEND=" + String(req.length()), 1000);
send(req, 4000);
send("AT+CIPCLOSE");
}
void loop() {}