Embedded SystemsSeptember 20, 2026

ESP32 Prototype to Production: Overcoming Wi-Fi and Power Instability

The ESP32 is arguably the most popular microcontroller for IoT development today. It offers Wi-Fi, BLE, and a dual-core processor at an incredibly low cost.

However, there is a massive gap between a prototype that works on an engineer’s desk and a production device deployed in an industrial environment. At SOLVEO, we have deployed hundreds of edge devices. This article outlines the architectural patterns we use to prevent field failures.

The Problem: The Laboratory vs. The Real World

When you build a prototype, you assume:

  1. The power supply is stable.
  2. The Wi-Fi router is always within range and never reboots.
  3. The MQTT broker never goes down.

In the real world, none of these are true. If your firmware relies on a standard while(WiFi.status() != WL_CONNECTED) loop during setup(), a temporary router outage will cause your device to hang indefinitely, blocking the execution of all other tasks (like reading sensors or saving data to local flash).

Pattern 1: Non-Blocking State Machines

The single most important architectural shift for production firmware is abandoning blocking loops. We utilize FreeRTOS, which comes natively with ESP-IDF, to manage tasks asynchronously.

Instead of blocking the main thread while waiting for Wi-Fi, we implement a state machine:

enum SystemState {
  STATE_BOOT,
  STATE_WIFI_CONNECTING,
  STATE_WIFI_CONNECTED,
  STATE_MQTT_CONNECTING,
  STATE_OPERATIONAL,
  STATE_OFFLINE_MODE
};

If the Wi-Fi connection fails after 30 seconds, the state machine transitions to STATE_OFFLINE_MODE. In this mode, the device continues to poll sensors and stores the telemetry data in Non-Volatile Storage (NVS) or a local SD card.

Pattern 2: Telemetry Ring Buffers

When a device is offline, data must not be lost. We implement a local ring buffer.

  1. Sensor Polling Task: Reads data every 5 seconds and pushes it to a local queue.
  2. Network Task: If STATE_OPERATIONAL, it pops data from the queue and publishes it via MQTT.
  3. Storage Task: If the queue is getting full (due to network failure), it writes the oldest data to NVS.

Once connectivity is restored, the Network Task flushes the stored data chronologically. This ensures zero data loss during network outages.

Pattern 3: Hardware Watchdogs

Software watchdogs are great, but they can fail if the underlying FreeRTOS kernel hangs due to memory corruption.

For production boards, we always wire an external Hardware Watchdog Timer (WDT). The ESP32 must pulse a specific GPIO pin every few seconds. If the firmware crashes and stops pulsing, the external WDT chip physically cuts power to the EN pin of the ESP32, forcing a hard hardware reset.

Conclusion

Building IoT products is fundamentally different from building web applications. You cannot simply SSH into an embedded device to restart a failed service.

By designing firmware with non-blocking state machines, local telemetry buffering, and aggressive hardware watchdogs, SOLVEO ensures that devices can recover autonomously from the unpredictable conditions of the real world.

WE BUILD WHAT OTHERS CAN'T.START A PROJECT
★★★★★
Trusted by 50+ Global Clients