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

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.

Answer: ≈ 200 days

Worked example: Shorter awake time

Given: Awake 0.5 s instead of 2 s

Find: Life.

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 wake

Deep 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

Applications

Key takeaways

Going further