Getting Started with ESP32: Complete Beginner's Guide
Learn everything you need to know about ESP32 microcontroller. From setup to your first IoT project with WiFi and Bluetooth.
Table of Contents
- 1. What is ESP32?
- 2. ESP32 Variants Compared
- 3. Getting Started - What You Need
- 4. Arduino IDE Setup
- 5. Your First Program - Blink LED
- 6. Understanding GPIO Pins
- 7. Connecting to WiFi
- 8. Bluetooth Classic & BLE
- 9. Deep Sleep & Power Saving
- 10. Complete Project Example
- 11. Troubleshooting
- 12. Next Steps & Resources
1. What is ESP32?
The ESP32 is a low-cost, low-power system on a chip (SoC) microcontroller with integrated Wi-Fi and dual-mode Bluetooth. Developed by Espressif Systems (the same company behind ESP8266), it's become the go-to choice for IoT projects.
- CPU: Dual-core Tensilica LX6 @ 160-240 MHz
- SRAM: 520 KB
- Flash: 4 MB (typical)
- WiFi: 802.11 b/g/n (2.4 GHz)
- Bluetooth: v4.2 BR/EDR and BLE
- GPIO: 34 pins with multiple functions
- ADC: 18 channels, 12-bit
- DAC: 2 channels, 8-bit
- Price: $3-10 USD
Why Choose ESP32?
- Powerful: Dual-core processor, 10x faster than Arduino Uno
- Wireless: Built-in WiFi and Bluetooth
- Low Power: Deep sleep mode (5 ΞA)
- Rich Peripherals: ADC, DAC, PWM, I2C, SPI, UART
- Affordable: Fraction of the cost of competitors
- Community: Large community and extensive libraries
2. ESP32 Variants Compared
| Board | CPU | WiFi | Bluetooth | Price |
|---|---|---|---|---|
| ESP32 DevKit V1 | Dual-core 240MHz | â | â Classic + BLE | $6-10 |
| ESP32-WROOM-32 | Dual-core 240MHz | â | â Classic + BLE | $5-8 |
| ESP32-S3 | Dual-core 240MHz | â | â BLE 5.0 | $8-12 |
| ESP32-C3 | Single-core 160MHz | â | â BLE 5.0 | $3-5 |
| NodeMCU-32S | Dual-core 240MHz | â | â Classic + BLE | $6-10 |
Start with ESP32 DevKit V1 or NodeMCU-32S. They're well-documented, widely supported, and perfect for learning.
3. Getting Started - What You Need
4. Arduino IDE Setup
Step 1: Install Arduino IDE
- Download from arduino.cc
- Install for your operating system
- Launch Arduino IDE
Step 2: Add ESP32 Board Support
- Go to File â Preferences
- In "Additional Board Manager URLs", add:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json - Click OK
- Go to Tools â Board â Boards Manager
- Search for "esp32"
- Install "esp32 by Espressif Systems"
- Wait for installation to complete (may take a few minutes)
Step 3: Select Your Board
- Go to Tools â Board â ESP32 Arduino
- Select your board (e.g., "DOIT ESP32 DEVKIT V1")
- Go to Tools â Port and select your COM port
If your board isn't recognized, you may need USB driver:
âĒ CP2102: Download here
âĒ CH340: Download here
5. Your First Program - Blink LED
Let's start with the classic "Hello World" of hardware - blinking an LED!
Hardware Setup
LED Connection:
ESP32 LED
âââââ âââ
GPIO 2 âââââââķ|ââââ
LED â
GND âââââââââââīââ[220ÎĐ]âââķ GND
Note: Many ESP32 boards have built-in LED on GPIO 2
Blink Code
void setup() {
// Initialize GPIO 2 as output
pinMode(2, OUTPUT);
}
void loop() {
digitalWrite(2, HIGH); // Turn LED on
delay(1000); // Wait 1 second
digitalWrite(2, LOW); // Turn LED off
delay(1000); // Wait 1 second
}
/*
Upload Instructions:
1. Copy this code into Arduino IDE
2. Click Upload button (â arrow)
3. If upload fails, hold BOOT button while uploading
4. Release BOOT button when upload starts
*/
Upload Troubleshooting
If upload fails with "Failed to connect to ESP32":
- Hold the BOOT button on ESP32
- Press EN (or RST) button
- Release EN button
- Release BOOT button
- Try uploading again
6. Understanding GPIO Pins
GPIO Pin Capabilities
| Pin Type | GPIO Numbers | Notes |
|---|---|---|
| Digital I/O | Most GPIOs | Input or output, 3.3V logic |
| ADC | GPIO 32-39 | Analog input only (12-bit) |
| DAC | GPIO 25, 26 | Analog output (8-bit) |
| PWM | Most GPIOs | Software PWM on any pin |
| I2C | Any GPIO | Default: SDA=21, SCL=22 |
| SPI | GPIO 5, 18, 19, 23 | VSPI pins |
| UART | GPIO 1, 3, 16, 17 | TX0=1, RX0=3 |
| Touch | GPIO 0, 2, 4, 12-15 | Capacitive touch sensors |
- GPIO 34-39: Input only (no internal pull-up)
- GPIO 6-11: Connected to flash chip (don't use)
- GPIO 1 (TX0): Avoid during boot
- GPIO 2: Built-in LED, affects boot
- GPIO 12: Affects boot mode
- GPIO 34-39: No internal pull-up/pull-down
- Voltage: 3.3V logic (NOT 5V tolerant!)
Basic GPIO Examples
// Digital Output
pinMode(2, OUTPUT);
digitalWrite(2, HIGH); // 3.3V
digitalWrite(2, LOW); // 0V
// Digital Input with Pull-up
pinMode(4, INPUT_PULLUP);
int value = digitalRead(4); // HIGH or LOW
// Analog Read (ADC)
int sensorValue = analogRead(34); // 0-4095
float voltage = sensorValue * (3.3 / 4095.0);
// PWM (LED Control)
ledcSetup(0, 5000, 8); // Channel 0, 5kHz, 8-bit
ledcAttachPin(2, 0); // Attach GPIO 2 to channel 0
ledcWrite(0, 128); // 50% duty cycle (0-255)
7. Connecting to WiFi
Basic WiFi Connection
#include <WiFi.h>
const char* ssid = "YourWiFiName";
const char* password = "YourWiFiPassword";
void setup() {
Serial.begin(115200);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
// Your code here
delay(10000);
}
WiFi Connection with Status Check
void checkWiFi() {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi disconnected! Reconnecting...");
WiFi.reconnect();
delay(5000);
}
}
WiFi Scanner
#include <WiFi.h>
void setup() {
Serial.begin(115200);
// Scan for networks
int n = WiFi.scanNetworks();
Serial.println("Available Networks:");
for (int i = 0; i < n; i++) {
Serial.print(i + 1);
Serial.print(". ");
Serial.print(WiFi.SSID(i));
Serial.print(" (");
Serial.print(WiFi.RSSI(i));
Serial.print(" dBm)");
Serial.println(WiFi.encryptionType(i) == WIFI_AUTH_OPEN ? " " : "*");
}
}
void loop() {}
8. Bluetooth Classic & BLE
Bluetooth Classic (Serial)
#include <BluetoothSerial.h>
BluetoothSerial BT;
void setup() {
Serial.begin(115200);
BT.begin("ESP32-Serial"); // Device name
Serial.println("Bluetooth Serial Ready");
}
void loop() {
if (BT.available()) {
Serial.write(BT.read());
}
if (Serial.available()) {
BT.write(Serial.read());
}
}
Bluetooth Low Energy (BLE) Server
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
// UUIDs (generate your own at uuidgenerator.net)
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
BLEServer *pServer = NULL;
BLECharacteristic *pCharacteristic = NULL;
bool deviceConnected = false;
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
}
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
void setup() {
Serial.begin(115200);
// Create BLE Device
BLEDevice::init("ESP32-BLE-Server");
// Create Server
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create Characteristic
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY
);
pCharacteristic->addDescriptor(new BLE2902());
// Start Service
pService->start();
// Start Advertising
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->start();
Serial.println("BLE Server Ready");
}
void loop() {
if (deviceConnected) {
pCharacteristic->setValue("Hello from ESP32");
pCharacteristic->notify();
delay(2000);
}
}
9. Deep Sleep & Power Saving
ESP32's deep sleep mode reduces power consumption to ~5-10 ΞA, perfect for battery-powered projects!
Deep Sleep with Timer Wake-up
#define uS_TO_S_FACTOR 1000000ULL // Conversion factor
#define TIME_TO_SLEEP 10 // Sleep for 10 seconds
RTC_DATA_ATTR int bootCount = 0;
void setup() {
Serial.begin(115200);
// Increment boot number
++bootCount;
Serial.println("Boot number: " + String(bootCount));
// Configure timer wake-up
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println("Going to sleep for " + String(TIME_TO_SLEEP) + " seconds");
Serial.flush();
// Enter deep sleep
esp_deep_sleep_start();
}
void loop() {
// This won't run (ESP32 sleeps in setup)
}
Deep Sleep with External Wake-up
#define BUTTON_PIN 39 // GPIO 39 (input only)
void setup() {
Serial.begin(115200);
// Configure ext1 wake-up on GPIO 39
esp_sleep_enable_ext1_wakeup(BUTTON_PIN, ESP_EXT1_WAKEUP_ALL_LOW);
// Check wake reason
esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();
switch(wakeup_reason) {
case ESP_SLEEP_WAKEUP_EXT1:
Serial.println("Woken by GPIO button press");
break;
case ESP_SLEEP_WAKEUP_TIMER:
Serial.println("Woken by timer");
break;
default:
Serial.println("Woken by other reason");
}
Serial.flush();
esp_deep_sleep_start();
}
Power Consumption Comparison
| Mode | Current Draw | Description |
|---|---|---|
| Active (WiFi on) | 80-100 mA | Full operation, transmitting |
| Active (WiFi off) | 50-70 mA | CPU running, no WiFi |
| Modem Sleep | 15-20 mA | WiFi disconnected, CPU running |
| Light Sleep | 0.8-1 mA | CPU paused, RAM retained |
| Deep Sleep | 5-10 ΞA | Most circuits off, RTC on |
| Hibernate | 2-5 ΞA | Everything off, no wake |
10. Complete Project Example
WiFi Weather Station
Build a simple weather station that reads temperature and publishes to MQTT:
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
// WiFi & MQTT
const char* ssid = "YOUR_WIFI";
const char* password = "YOUR_PASSWORD";
const char* mqtt_server = "broker.hivemq.com";
// DHT Sensor
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
WiFiClient espClient;
PubSubClient client(espClient);
void setup_wifi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}
void reconnect() {
while (!client.connected()) {
String clientId = "ESP32Weather-" + String(random(0xffff), HEX);
if (client.connect(clientId.c_str())) {
Serial.println("MQTT connected");
} else {
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
dht.begin();
setup_wifi();
client.setServer(mqtt_server, 1883);
}
void loop() {
if (!client.connected()) reconnect();
client.loop();
// Read sensor
float humidity = dht.readHumidity();
float temp = dht.readTemperature();
if (isnan(humidity) || isnan(temp)) {
Serial.println("Failed to read from DHT");
return;
}
// Publish to MQTT
char tempStr[8];
char humStr[8];
dtostrf(temp, 1, 2, tempStr);
dtostrf(humidity, 1, 2, humStr);
client.publish("weather/temperature", tempStr);
client.publish("weather/humidity", humStr);
Serial.print("Temp: ");
Serial.print(temp);
Serial.print("°C, Humidity: ");
Serial.print(humidity);
Serial.println("%");
// Deep sleep for 60 seconds
esp_sleep_enable_timer_wakeup(60 * 1000000ULL);
esp_deep_sleep_start();
}
11. Troubleshooting
Problem: Board Not Recognized
- Try different USB cable (some are charge-only)
- Install USB driver (CP2102 or CH340)
- Check Device Manager (Windows) or System Information (Mac)
- Try different USB port
Problem: Upload Fails
- Hold BOOT button while uploading
- Check correct COM port is selected
- Try different upload speed (115200)
- Press EN button, then BOOT, release EN, release BOOT
Problem: WiFi Won't Connect
- ESP32 only supports 2.4GHz WiFi (not 5GHz)
- Check SSID and password (case-sensitive)
- Move closer to router
- Check for MAC filtering
- Try static IP configuration
Problem: Brownout Reset
- Use better power supply (500mA+)
- Use separate power for peripherals
- Add capacitor (10ΞF) across 3.3V and GND
- Reduce WiFi transmit power
Problem: GPIO Not Working
- Check if pin is input-only (34-39)
- Avoid GPIO 6-11 (flash pins)
- Remember 3.3V logic (not 5V tolerant)
- Check for conflicting functions (I2C, SPI)
12. Next Steps & Resources
Continue Learning
Now that you know ESP32 basics, try these projects:
- Smart home temperature monitoring
- MQTT-based sensor network
- Web server on ESP32
- Bluetooth remote control
- Battery-powered sensor node
- OTA (Over-The-Air) updates
Useful Resources
- Official Docs: Espressif Documentation
- Arduino Core: ESP32 Arduino GitHub
- Random Nerd Tutorials: Excellent ESP32 tutorials
- ESP32.com Forum: Community support
Related Articles:
Smart Home Temperature Monitoring |
MQTT Protocol Complete Guide
Useful Tools:
MQTT Message Generator |
IoT Payload Generator