I’m sharing a Wi-Fi manager component I built for ESP-IDF, designed to handle connection state, reconnection, and persistence in a predictable way.
GitHub
Note: English is not my native language. If it sounds AI-generated, it’s because I translate my drafts.
Why I built it
In my embedded projects I often need reliable Wi-Fi management without relying on Arduino-style libraries. Most existing solutions either are tied to the Arduino ecosystem, use blocking APIs, or lack good state control and reconnection logic. I wanted something that:
- works natively with ESP-IDF (not Arduino),
- gives controlled, testable Wi-Fi state transitions,
- works well in real deployments where connectivity is intermittent,
- meshes cleanly with event-driven embedded designs.
That’s what led me to build wifi_manager, initially for my solar automation setup but now generalized for reuse.
What it does
wifi_manager wraps the low-level esp_wifi driver behind a state machine and a singleton interface. Key features include:
- Dedicated task for Wi-Fi operations, decoupled from your main application.
- Automatic reconnection with exponential backoff on disconnects.
- Graceful handling of timeouts and failures.
- Thread-safe API via mutexes and queues.
- Persistent credentials stored in NVS.
- Both blocking (sync) and non-blocking (async) APIs.
- Built with C++, but usable from C projects too.
It’s designed to be used like this:
auto &wm = WiFiManager::get_instance();
wm.init();
wm.start();
wm.set_credentials("SSID", "PASSWORD");
if (wm.connect(10000) == ESP_OK) {
printf("Connected!\n");
}
This approach gives you fine-grained control over how your application handles Wi-Fi without forcing you into a particular pattern.
Credentials handling and persistence
In the example above, credentials are passed directly in code:
wm.set_credentials("SSID", "PASSWORD");
This is one of the supported paths.
Credentials can also be configured via Kconfig (idf.py menuconfig). Internally, Wi-Fi credentials are stored by the ESP-IDF Wi-Fi driver itself in NVS, and are automatically reused across reboots.
The component maintains an additional is_credential_valid (private) flag, also stored in NVS, to decide which source to use in boot:
- If credentials are marked as valid, the saved credentials from NVS are used.
- If not, the component falls back to credentials provided via Kconfig (if configured).
This validity flag is managed through Wi-Fi events:
- A successful connection marks the credentials as valid.
- A disconnection caused by authentication errors invalidates them.
This allows the system to recover cleanly from wrong credentials without hardcoding values or requiring recompilation.
Current limitations
At the moment, the component does not implement provisioning or signal quality evaluation.
In particular:
- There is no RSSI-based logic to distinguish very weak signal conditions.
- The
WIFI_REASON_4WAY_HANDSHAKE_TIMEOUTusually occurs when the access point aborts the handshake due to invalid credentials. Currently, it is treated only as an authentication failure, even though in practice it may also occur under marginal signal conditions.
These cases are known limitations and candidates for future improvement.
Testing from the start
The component comes with a comprehensive test suite (40+ cases) covering lifecycle, state machine behavior, persistence, stress tests, and error handling. Running these tests on real hardware is part of how I validate changes.
Design decisions
A few decisions you’ll find in the code:
- Thread safety first — Wi-Fi in real products often runs concurrently with other tasks.
-
State machine core — lets you reason about connection state instead of relying on sequences of
esp_wifi_*calls scattered around your code. - CMake / IDF component layout — makes integration with existing ESP-IDF apps trivial.
Where it fits
While popular Arduino-based Wi-Fi managers are great for quick prototypes, for embedded production systems I find I need more structure:
- reliable recovery from disconnects,
- testability,
- integration with FreeRTOS tasks and event loops.
Esp-IDF’s own netif and event system are solid foundations, but a clean wrapper like wifi_manager makes it easier to build bigger systems on top of them.
Try it out
Check out the repo: https://github.com/aluiziotomazelli/wifi_manager
It’s MIT-licensed and ready for use or adaptation. Contributions welcome.
Top comments (0)