Project 5: OTA-Updatable Smart Home Hub
Project 5: OTA-Updatable Smart Home Hub
Project Overview
| Attribute | Value |
|---|---|
| Difficulty | Advanced |
| Time Estimate | 1 month+ |
| Main Language | C |
| Alternatives | Rust, MicroPython, Arduino C++ |
| Primary Book | Making Embedded Systems by Elecia White |
| Knowledge Areas | OTA Updates, Partitions, ESP-NOW, REST API, System Architecture |
What Youโll Build
A central hub that communicates with multiple sensor nodes via ESP-NOW, provides a REST API for integration with Home Assistant, and can update its own firmware over-the-air.
Physical Setup:
- One ESP32 hub connected to power and WiFi
- Multiple ESP32 sensor nodes (battery-powered, using ESP-NOW)
- Hub aggregates data and exposes REST API
- Push firmware updates without physical access
Home Assistant Dashboard View:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Smart Home Hub - Living Room โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ Sensor Nodes (5 active) โ
โ Living Room - Temp: 22.3ยฐC โ
โ Bedroom - Motion: Detected 2m ago โ
โ Kitchen - Temp: 24.1ยฐC โ
โ Front Door - Status: Closed โ
โ Garage - Motion: Clear โ
โ โ
โ Hub Status โ
โ Uptime: 15d 4h 23m โ
โ WiFi: -42 dBm (Excellent) โ
โ Firmware: v2.3.1 โ
โ Last Update: 2024-12-20 โ
โ โ
โ [Update Firmware] [Restart Hub] โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Learning Objectives
By completing this project, you will be able to:
- Design and implement OTA update systems with rollback capability
- Understand ESP32 partition tables and bootloader behavior
- Run WiFi and ESP-NOW simultaneously on the same radio
- Build REST APIs on embedded systems
- Manage concurrent connections with FreeRTOS
- Implement production-quality firmware practices
- Design state machines for complex device coordination
Deep Theoretical Foundation
ESP32 Flash Partition Architecture
The ESP32โs flash memory is divided into partitions. Understanding this is critical for OTA updates.
Flash Memory Layout (4MB typical):
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 0x0000 โ 2nd stage bootloader (0x8000 bytes) โ
โโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 0x8000 โ Partition Table (0x1000 bytes) โ
โโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 0x9000 โ NVS - Non-Volatile Storage (0x6000 bytes) โ
โโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 0xF000 โ OTA Data (0x2000 bytes) - which partition to boot โ
โโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 0x10000โ ota_0 - First app partition (1.5MB) โ
โ โ Contains: Application firmware image โ
โโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 0x190000โ ota_1 - Second app partition (1.5MB) โ
โ โ Contains: OTA update image โ
โโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 0x310000โ SPIFFS/FAT - Filesystem (remaining space) โ
โโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Partition Table Definition
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x6000,
otadata, data, ota, 0xF000, 0x2000,
ota_0, app, ota_0, 0x10000, 0x180000,
ota_1, app, ota_1, 0x190000,0x180000,
storage, data, spiffs, 0x310000,0xF0000,
OTA Update Mechanism
The OTA process ensures safe firmware updates with automatic rollback.
OTA Update Flow
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Normal Operation โ
โ โ
โ Bootloader reads OTA data partition โ
โ โ โ
โ "Boot from ota_0" โ
โ โ โ
โ Load and run firmware from ota_0 โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
User triggers update
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ OTA Update โ
โ โ
โ 1. Get next update partition (ota_1) โ
โ 2. Begin OTA: esp_ota_begin() โ
โ 3. Download firmware in chunks โ
โ 4. Write each chunk: esp_ota_write() โ
โ 5. Finalize: esp_ota_end() โ
โ 6. Verify SHA256 checksum โ
โ 7. Set next boot partition: esp_ota_set_boot_partition() โ
โ 8. Reboot โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
Reboot
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ First Boot (Pending Verify) โ
โ โ
โ Bootloader loads ota_1 (new firmware) โ
โ โ โ
โ Firmware runs diagnostic checks โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Checks PASS? โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ
โ โ YES: esp_ota_mark_app_valid_cancel_rollback() โ โ
โ โ โ OTA committed, ota_1 is now the boot partition โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ
โ โ NO: Don't mark valid โ โ
โ โ โ Reboot โ Bootloader sees invalid โ boots ota_0 โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Rollback States
esp_ota_img_states_t state;
esp_ota_get_state_partition(running, &state);
switch (state) {
case ESP_OTA_IMG_NEW:
// Just written, never booted
break;
case ESP_OTA_IMG_PENDING_VERIFY:
// First boot after OTA, must validate
if (run_diagnostics()) {
esp_ota_mark_app_valid_cancel_rollback();
}
break;
case ESP_OTA_IMG_VALID:
// Confirmed working
break;
case ESP_OTA_IMG_INVALID:
// Boot failed, will rollback
break;
case ESP_OTA_IMG_ABORTED:
// OTA was aborted
break;
}
WiFi + ESP-NOW Coexistence
ESP32 has a single 2.4GHz radio shared between WiFi and ESP-NOW. They can coexist with constraints.
Single Radio Sharing
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 2.4 GHz Radio โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Time Division โ โ
โ โ โ โ
โ โ WiFi TX โ ESP-NOW โ WiFi RX โ ESP-NOW โ WiFi TX โ... โ โ
โ โ โโโโโโโ โ โโโโโโโ โ โโโโโโโ โ โโโโโโโ โ โโโโโโโ โ โ โ
โ โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ CRITICAL: Both must use the SAME WiFi channel! โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Channel Synchronization
// 1. Connect to WiFi first
esp_wifi_set_mode(WIFI_MODE_STA);
wifi_config_t wifi_config = {
.sta = {
.ssid = "YourNetwork",
.password = "YourPassword",
},
};
esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
esp_wifi_start();
esp_wifi_connect();
// 2. After connection, get the channel
wifi_ap_record_t ap_info;
esp_wifi_sta_get_ap_info(&ap_info);
uint8_t wifi_channel = ap_info.primary;
// 3. ESP-NOW uses same channel automatically
esp_now_init(); // Will use wifi_channel
// 4. Lock WiFi to this channel (prevent roaming)
esp_wifi_set_channel(wifi_channel, WIFI_SECOND_CHAN_NONE);
If WiFi roams to a different channel, ESP-NOW will break! Use esp_wifi_set_channel() to lock it.
REST API Design for Embedded Systems
REST APIs on microcontrollers are simpler than traditional web servers but follow the same principles.
HTTP Methods:
GET - Retrieve data (read-only)
POST - Create/trigger action
PUT - Update resource
DELETE - Remove resource
Endpoints for Smart Hub:
GET /api/sensors โ All sensor readings
GET /api/sensors/{mac} โ Single sensor
GET /api/status โ Hub status
POST /api/ota/update โ Trigger OTA update
POST /api/hub/restart โ Restart hub
POST /api/sensors/{mac}/pair โ Pair new sensor
JSON Response Format
// GET /api/sensors
{
"sensors": [
{
"mac": "A8:42:E3:4D:2F:11",
"name": "Living Room",
"type": "temperature",
"temperature": 22.3,
"humidity": 45,
"battery": 87,
"rssi": -45,
"last_seen": "2024-12-27T16:15:12Z"
},
{
"mac": "A8:42:E3:4D:2F:22",
"name": "Bedroom",
"type": "motion",
"motion": true,
"last_seen": "2024-12-27T16:15:18Z"
}
],
"count": 2,
"hub_uptime": 1324980
}
State Machine Design
Complex embedded systems benefit from explicit state machines.
Hub State Machine:
โโโโโโโโโโโโโโโ
โโโโโโโโโโโโ BOOTING โโโโโโโโโโโโ
โ โโโโโโโโฌโโโโโโโ โ
โ โ โ
โ init completeโ โ rollback
โ โผ โ
โ โโโโโโโโโโโโโโโ โ
โ โ VALIDATING โโโโโโโโโโโโ
โ โ (first boot)โ
โ โโโโโโโโฌโโโโโโโ
โ โ
โ validation โ pass
โ โผ
โ โโโโโโโโโโโโโโโ
โ โโโโโโ RUNNING โโโโโโ
โ โ โโโโโโโโฌโโโโโโโ โ
โ โ โ โ
โ โ OTA โ WiFi โ
โ โ request โ lost โ
โ โ โผ โ
โ โ โโโโโโโโโโโโโโโ โ
โ โ โ UPDATING โ โ
โ โ โโโโโโโโฌโโโโโโโ โ
โ โ โ โ
โ โ success โ fail โ
โ โ โ โ
โ โโโโโโโโโโโโโผโโโโโโโโโโโโ
โ โ
โ reboot
โ โ
โโโโโโโโโโโโโโโโโโโ
Memory Management Considerations
Long-running embedded systems must carefully manage memory.
ESP32 Memory Map:
Total DRAM: 520 KB
โโโ Static allocations (code, globals): ~150 KB
โโโ FreeRTOS heaps: ~50 KB
โโโ WiFi/BLE stacks: ~100 KB
โโโ HTTP server buffers: ~30 KB
โโโ JSON parsing: ~10 KB per request
โโโ Sensor database: ~5 KB
โโโ Free heap: ~175 KB
CRITICAL: OTA requires ~50-100KB continuous block!
Heap Fragmentation
Healthy Heap:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โโโโโโโโโโโโโโโโโ FREE โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Fragmented Heap:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โโโโ FREE โ FREE โโโ FREE โโ FREE โโโโโ FREE โโโ FREE โโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Largest free block might be only 10KB even with 100KB total free!
Prevention:
- Allocate large buffers at startup
- Use fixed-size pools for repeated allocations
- Avoid string manipulation with dynamic allocation
Project Specification
Hardware Requirements
| Component | Quantity | Purpose |
|---|---|---|
| ESP32 DevKit (Hub) | 1 | Central controller |
| ESP32 DevKit (Nodes) | 2-5 | Sensor nodes |
| BME280 Sensors | 2-5 | Environmental sensing |
| PIR Motion Sensors | 1-2 | Motion detection |
| Door/Window Sensor | 1-2 | Reed switch + magnet |
| 3.7V LiPo Batteries | 2-5 | Node power |
System Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โ Home Network โ
โ โ
โ โโโโโโโโโโโโโโโ โ
โ โ Router โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโฌโโโโโโโ โ โ
โ โ WiFi โ โ
โ โ โ โ
โ โโโโโโโโดโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ โ Smart Home Hub โโ โ
โ โ Home โ โ โโ โ
โ โ Assistant โโโโโโโโโค โโโโโโโโ โโโโโโโโ โโโโโโโโ โโ โ
โ โ โ REST โ โWiFi โ โESP-NOWโ โHTTP โ โโ โ
โ โโโโโโโโโโโโโโโ API โ โStack โ โRecv โ โServerโ โโ โ
โ โ โโโโโโโโ โโโโโโโโ โโโโโโโโ โโ โ
โ โ โฒ โโ โ
โ โ โESP-NOW โโ โ
โ โ โ โโ โ
โ โโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ โ โ โ
โ โโโโโโโโดโโโโโโโ โโโโโโโโดโโโโโโโ โโโโโโโโดโโโโโโโโ
โ โ Sensor Node โ โ Sensor Node โ โ Sensor Node โโ
โ โ (Battery) โ โ (Battery) โ โ (Battery) โโ
โ โ โ โ โ โ โโ
โ โ BME280 โ โ PIR Motion โ โ Door Reed โโ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/sensors |
GET | List all sensors |
/api/sensors/{mac} |
GET | Single sensor data |
/api/status |
GET | Hub status info |
/api/ota/update |
POST | Trigger OTA update |
/api/ota/status |
GET | OTA progress |
/api/hub/restart |
POST | Restart hub |
/api/config |
GET/PUT | Hub configuration |
Functional Requirements
- ESP-NOW Reception
- Receive data from up to 20 sensor nodes
- Support multiple sensor types (temp, motion, door)
- Track last-seen timestamp for each node
- Detect offline nodes (>5 minute timeout)
- REST API
- Serve JSON responses
- Handle concurrent clients
- CORS headers for browser access
- Basic authentication (optional)
- OTA Updates
- Download firmware from HTTP URL
- Verify SHA256 checksum
- Automatic rollback on boot failure
- Progress reporting via API
- Data Persistence
- Store sensor names in NVS
- Preserve configuration across reboots
- Log recent events to circular buffer
- Reliability
- Watchdog timer for recovery
- WiFi reconnection handling
- Graceful degradation under load
Solution Architecture
Task Structure
// Task list and priorities
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Task Name โ Priority โ Core โ Stack โ Purpose โ
โโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโโโโโโโค
โ wifi_manager โ 10 โ 0 โ 4KB โ Connection mgmt โ
โ espnow_receiver โ 8 โ 0 โ 4KB โ Receive sensors โ
โ http_server โ 5 โ 1 โ 8KB โ REST API โ
โ sensor_manager โ 4 โ 1 โ 4KB โ Data processing โ
โ ota_handler โ 6 โ 1 โ 12KB โ Firmware updates โ
โ watchdog โ 15 โ 0 โ 2KB โ Health monitoringโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Data Structures
// Sensor node representation
typedef struct {
uint8_t mac[6];
char name[32];
sensor_type_t type;
union {
struct {
float temperature;
float humidity;
float pressure;
} environmental;
struct {
bool motion_detected;
uint32_t last_motion_time;
} motion;
struct {
bool is_open;
} door;
} data;
uint8_t battery_percent;
int8_t rssi;
uint32_t last_seen;
bool online;
} sensor_node_t;
#define MAX_SENSORS 20
sensor_node_t sensor_db[MAX_SENSORS];
// Hub configuration
typedef struct {
char hub_name[32];
uint16_t sensor_timeout_sec;
bool ota_auto_update;
char ota_url[128];
} hub_config_t;
// OTA state
typedef struct {
ota_state_t state;
uint32_t bytes_written;
uint32_t total_bytes;
char error_message[64];
} ota_status_t;
ESP-NOW Protocol
// Sensor data packet (sent from nodes)
typedef struct {
uint8_t packet_type;
uint8_t sensor_type;
uint8_t battery_percent;
union {
struct {
float temperature;
float humidity;
float pressure;
} env;
struct {
uint8_t motion;
} motion;
struct {
uint8_t door_open;
} door;
} data;
uint32_t sequence;
} __attribute__((packed)) sensor_packet_t;
// Maximum: 250 bytes per ESP-NOW packet
// This struct: ~20 bytes - plenty of room
Phased Implementation Guide
Phase 1: Basic Hub Structure (Day 1-3)
Goal: WiFi connected hub with REST endpoint
- WiFi Connection
- Connect to network
- Print IP address
- Handle disconnections
- HTTP Server
- Start server on port 80
- Serve
/api/statusendpoint - Return hub uptime and version
- Test with curl
curl http://192.168.1.150/api/status # {"version":"1.0.0","uptime":3600,"wifi_rssi":-42}
Checkpoint: Hub serves REST API over WiFi
Phase 2: ESP-NOW Reception (Day 4-7)
Goal: Receive data from sensor nodes
- ESP-NOW Initialization
- Initialize ESP-NOW stack
- Register receive callback
- Handle channel synchronization with WiFi
- Create Sensor Node
- Simple node firmware (separate project)
- Read BME280 sensor
- Send via ESP-NOW every 30 seconds
- Parse and Store Data
- Decode incoming packets
- Update sensor database
- Log to serial for debugging
- REST Endpoint
- Add
/api/sensorsendpoint - Return JSON array of sensors
- Add
Checkpoint: /api/sensors shows data from sensor node
Phase 3: Sensor Management (Day 8-12)
Goal: Robust multi-sensor handling
- Multiple Sensor Types
- Support temperature, motion, door sensors
- Different packet parsing per type
- Unified database structure
- Online/Offline Detection
- Track last_seen timestamp
- Mark offline after timeout
- Resume online when data received
- Persistence
- Store sensor names in NVS
- Load on boot
- API endpoint to rename sensors
- Add More Sensors
- Flash 2-3 sensor nodes
- Verify all appear in API
- Test offline detection
Checkpoint: Multiple sensors visible, offline detection works
Phase 4: OTA Implementation (Day 13-20)
Goal: Remote firmware updates with rollback
- Partition Table
- Configure dual OTA partitions
- Verify with
esptool.py read_flash
- OTA Download
- Accept URL in POST request
- Download firmware in chunks
- Write to inactive partition
- Verification and Boot
- Check SHA256 after download
- Set boot partition
- Reboot
- Rollback Logic
- Run diagnostics on first boot
- Mark valid if passing
- Automatic rollback if not marked valid
- API Integration
/api/ota/updatetriggers update/api/ota/statusshows progress- Test with intentionally broken firmware
Checkpoint: Can update firmware remotely, rollback works
Phase 5: Production Hardening (Day 21-30)
Goal: Reliable long-term operation
- Watchdog Timer
- Enable task watchdog
- Reset periodically in main loop
- Test by creating infinite loop
- Error Handling
- Catch and log all errors
- Graceful degradation
- Rate limiting for API
- Memory Monitoring
- Log heap usage periodically
- Alert on low memory
- Profile for leaks
- Home Assistant Integration
- Configure REST sensor in HA
- Create dashboard
- Test automations
Testing Strategy
Unit Tests
| Component | Test | Expected Result |
|---|---|---|
| WiFi | Connect | IP assigned |
| HTTP | GET /api/status | Valid JSON |
| ESP-NOW | Receive packet | Data in callback |
| OTA | Download file | Bytes written |
| NVS | Write/read | Same value |
Integration Tests
- Multi-Node Communication
- All 5 sensors sending data
- API shows all sensors
- No packet loss
- OTA Update Cycle
- Deploy new version remotely
- Hub updates and reboots
- New version running
- Rollback Scenario
- Deploy broken firmware
- Hub auto-rollbacks
- Previous version restored
Stress Tests
- Long Duration
- Run for 7 days continuous
- Monitor memory usage
- Check for WiFi drops
- Concurrent Clients
- 10 clients polling API
- No timeouts or errors
- Response time < 500ms
Common Pitfalls and Debugging
OTA Issues
Problem: OTA download fails
- Check URL is accessible from ESP32
- Verify firewall allows connection
- Check available heap (need ~50KB)
Problem: Rollback happens unexpectedly
- Boot validation not called
- Diagnostic check failing
- Power loss during verification window
Problem: Canโt fit firmware in partition
- Firmware too large
- Resize partitions
- Optimize with
-Osflag
ESP-NOW Issues
Problem: Packets not received
- WiFi and ESP-NOW on different channels
- Sender not added as peer
- Radio busy with WiFi traffic
Problem: Intermittent reception
- Signal too weak
- WiFi traffic saturating radio
- Reduce WiFi bandwidth
API Issues
Problem: Concurrent request crashes
- Stack overflow in HTTP task
- JSON buffer too small
- Memory exhaustion
Problem: Response too large
- Enable chunked transfer
- Paginate results
- Compress JSON
Extensions and Challenges
Beginner Extensions
- Web Dashboard
- Serve HTML from SPIFFS
- Real-time updates with WebSocket
- Mobile-friendly design
- Multiple Hubs
- Mesh of hubs for large homes
- Synchronized sensor data
- Failover capability
Intermediate Challenges
- Secure OTA
- HTTPS for firmware download
- Firmware signature verification
- Encrypted NVS
- MQTT Integration
- Publish sensor data to MQTT
- Home Assistant auto-discovery
- Control devices via MQTT
Advanced Challenges
- Full Edge Computing
- Run automation rules on hub
- No cloud dependency
- Local voice control
- Commercial Grade
- Factory provisioning
- Cloud management portal
- Mass OTA deployment
Real-World Connections
Commercial Products
| Product | Your Project Skill |
|---|---|
| Philips Hue Bridge | Hub + sensors, OTA |
| SmartThings Hub | Multi-protocol, REST API |
| Home Assistant | Local control, integration |
| AWS IoT Greengrass | Edge + cloud, OTA |
Industry Practices
| Practice | Where You Applied It |
|---|---|
| A/B Partitions | OTA update scheme |
| Rollback | Boot validation |
| State Machines | Device coordination |
| REST API | External integration |
| Watchdog | Reliability |
Resources
Official Documentation
| Resource | URL |
|---|---|
| ESP-IDF OTA | docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/ota.html |
| ESP-NOW | docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_now.html |
| Partition Tables | docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/partition-tables.html |
Books
| Book | Author | Relevant Chapters |
|---|---|---|
| Making Embedded Systems | Elecia White | Ch. 8 (State Machines), Ch. 10 (Updates) |
| Mastering FreeRTOS | FreeRTOS.org | All chapters (free PDF) |
| Design and Build Great Web APIs | Mike Amundsen | Ch. 1-3: REST principles |
Self-Assessment Checklist
Fundamentals
- I can explain the OTA update flow and rollback mechanism
- I understand why WiFi and ESP-NOW must share a channel
- I can design a REST API for embedded systems
- I know how to prevent heap fragmentation
Implementation
- Hub receives data from multiple sensor nodes
- REST API returns sensor data correctly
- OTA update completes successfully
- Rollback works when new firmware fails
Production Quality
- Watchdog prevents permanent hangs
- Memory usage is stable over 24+ hours
- System recovers from WiFi disconnections
- Sensors are properly detected as online/offline
Interview Preparation
Be ready to answer these questions:
- โExplain how OTA updates work without bricking the device.โ
- Dual partitions, download to inactive, verify, switch boot, rollback on failure
- โWhat happens if WiFi and ESP-NOW are on different channels?โ
- ESP-NOW packets lost, must lock WiFi channel
- โHow do you ensure sensor data isnโt lost during OTA?โ
- Brief interruption acceptable, or buffer in NVS
- โWalk through the partition table. Whatโs in each partition?โ
- Bootloader, partition table, NVS, OTA data, ota_0, ota_1, storage
- โHow do you verify firmware integrity?โ
- SHA256 hash comparison, optional RSA signature
- โWhat causes heap fragmentation and how do you prevent it?โ
- Variable-size allocations, use pools, allocate at startup
Complete Project Synthesis
After completing all five projects, youโll have built:
- Environmental Monitor - Core ESP32 skills
- BLE Controller - Wireless protocol mastery
- Deep Sleep Logger - Battery-powered IoT
- Audio Spectrum Analyzer - Real-time DSP
- Smart Home Hub - Production firmware
Combined, you can build a Complete Home Automation System:
- Multiple battery-powered sensors (Project 3)
- Central hub with web interface (Project 5)
- Mobile app via BLE (Project 2)
- Real-time feedback (Project 4)
- Environmental monitoring (Project 1)
This represents professional-level ESP32 expertise applicable to IoT product development, embedded systems engineering, and smart home technology.
This concludes the ESP32 Programming Learning Projects series.