ESP32 & Wireless MCUs
The ESP32 brought Wi-Fi and Bluetooth to low-cost microcontrollers. Learn its dual-core Xtensa/RISC-V architecture, peripherals, ESP-IDF with FreeRTOS, Wi-Fi station/AP, MQTT/HTTP, BLE, power modes and deep-sleep battery life, OTA updates and security.
The ESP32 family (ESP32, S3, C3, C6) integrates CPUs, radios, and rich peripherals for a few dollars, making it the go-to chip for IoT devices — smart plugs, sensors, displays and gateways.
An analogy
An ESP32 is like a smartphone's brain shrunk into a sensor: it can measure, think and talk to the internet — but must sleep most of the time to save battery.
The chip
ESP32: dual-core Xtensa LX6 up to 240 MHz, 520 KB SRAM, Wi-Fi b/g/n, Bluetooth Classic + BLE, 12-bit ADCs, DACs, touch sensors, PWM (LEDC), I²C, SPI, UART, I²S, CAN (TWAI). Newer variants use RISC-V (C3, C6 with Wi-Fi 6 and 802.15.4).
ESP-IDF and FreeRTOS
The official framework runs FreeRTOS: Wi-Fi and BT stacks run as tasks; your application creates tasks, queues and event groups. Arduino-ESP32 and MicroPython are simpler layers on top.
Connectivity
Wi-Fi station/AP, HTTP(S) clients and servers, MQTT for IoT messaging, BLE GATT services for phones, ESP-NOW for low-latency peer links, provisioning via BLE or SoftAP.
Power, OTA and security
Active Wi-Fi ≈ 100–240 mA peaks; light sleep ≈ 1 mA; deep sleep ≈ 10 µA. OTA updates with dual partitions and rollback; secure boot and flash encryption protect firmware and keys.
Formulas
- Average current:
I_avg = (I_active t_on + I_sleep (T − t_on)) / T - Battery life:
Life = C_bat / I_avg
Worked example: Battery life
Given: Wake every 10 min, 2 s at 120 mA; Deep sleep 10 µA, 2000 mAh
Find: Average current and life.
- I_avg = (2 × 120 + 598 × 0.01)/600 = 0.41 mA
- Life = 2000/0.41 = 4880 h ≈ 203 days
Answer: ≈ 200 days
Worked example: Shorter awake time
Given: Awake 0.5 s instead of 2 s
Find: Life.
- I_avg = (0.5 × 120 + 599.5 × 0.01)/600 = 0.11 mA
- Life ≈ 18 000 h ≈ 2 years
Answer: ≈ 4× longer — optimise Wi-Fi connect time
Wi-Fi sensor with deep sleep (Arduino-ESP32)
#include <WiFi.h>
#include <PubSubClient.h>
const char* SSID = "my-network";
const char* PASS = "********";
WiFiClient net;
PubSubClient mqtt(net);
void setup() {
WiFi.begin(SSID, PASS);
while (WiFi.status() != WL_CONNECTED) delay(50);
mqtt.setServer("broker.local", 1883);
if (mqtt.connect("esp32-sensor")) {
float t = analogReadMilliVolts(34) / 10.0f; // LM35: 10 mV/°C
mqtt.publish("home/room1/temp", String(t, 1).c_str());
}
esp_sleep_enable_timer_wakeup(10ULL * 60 * 1000000); // 10 minutes
esp_deep_sleep_start(); // ~10 µA until next wake
}
void loop() {} // never reached: device reboots on wakeDeep sleep powers down CPUs and radio; the RTC timer wakes the chip, which reboots into setup(). Keeping awake time short is the key to battery life.
Common mistakes
- Wrong: Leaving Wi-Fi on in battery devices. — Right: Deep sleep and connect briefly.
- Wrong: Hard-coding credentials and no OTA security. — Right: Use provisioning, secure boot and signed OTA.
Applications
- Smart home: Plugs, lights, sensors over Wi-Fi/Matter.
- Wearables & BLE: Phone-connected gadgets.
- Industrial IoT: Gateways and data loggers.
Key takeaways
- Wi-Fi + BLE MCU with FreeRTOS.
- I_avg drives battery life.
- Minimise awake radio time.
- Secure boot + OTA for products.
Going further
- ULP coprocessor: Sensing during deep sleep.
- Matter & Thread: ESP32-C6/H2 smart-home stacks.
- RF certification: FCC/CE compliance for products.