Automating Wi-Fi setup testing on the ESP32

The very first thing a buyer does with a brand new Wi-Fi-enabled related product is full the Wi-Fi setup, so it needs to be dependable and work each time, it doesn’t matter what else modifications within the product.
This is one thing we are able to do with the Groundrun system. Let’s set it up.
Setting it up
First we have to get the {hardware} within the loop, the identical approach we did for testing an over-the-air (OTA) update on the ESP32. We used an ESP32-C6 devboard from Espressif for this check. With Groundrun, getting it into the loop is straightforward: we simply do that:
- Connect the ESP32-C6 board by way of USB to the Groundrun rig.
- Connect an Android cellphone by way of USB to the identical Groundrun rig.
And that is it.
Wi-Fi commissioning
There are a number of methods to arrange a Wi-Fi community on a related gadget, and the ESP32 household helps a variety of them:
- Bluetooth. The cellphone pairs with the board over Bluetooth Low Energy and sends it the community title and password instantly.
- Soft AP. The board begins its personal non permanent Wi-Fi community, and the cellphone joins it to ship the true credentials earlier than the board switches onto the true community.
- Wi-Fi captive portal. The similar Soft AP community, however the cellphone will get redirected straight to an internet web page for coming into the credentials, the way in which a lodge or an airport Wi-Fi login web page works. No app required.
- SmartConfig. Espressif’s personal method, operating on the ESP32 as ESPTouch v2 and constructed into their ESP-IDF SDK. The cellphone stays related to the house community and broadcasts the credentials as a stream of encoded packets; the board, not but on any community, picks them up by listening in promiscuous mode.
- WPS (Wi-Fi Protected Setup). The Wi-Fi Alliance’s business normal. Pressing the button on the router lets the board be a part of by itself, negotiating the credentials instantly with the router.
Our purpose right here is to check all of them.
The cellphone stays related to the house community and broadcasts the credentials as a stream of encoded packets; the board, not but on any community, picks them up by listening in promiscuous mode.
The smartphone app
In the everyday case, you have already got a smartphone app. In our case, we wanted one thing easy, simply to show find out how to join the Wi-Fi, so we requested Claude to develop a fast app. It must ship the correct bytes on the proper second for every of the 5 strategies, and nothing extra. The app would not have to look good, and it would not.
The app would not have to look good, and it would not.
The firmware
For an current related product, the firmware is already written. In this case, we have to observe the perfect practices for getting AI growth instruments to grasp it (see how to start using AI coding agents in connected product development).
We requested Claude to develop the firmware code for us. The Groundrun system helps right here, by offering the abilities for working with ESP32 firmware, and we ended up with code recordsdata that implement every of the Wi-Fi setup mechanisms above.
Because Claude Code has entry to the rig and its {hardware}, it does this work independently. We give it the plan, the purpose, and the stopping situation, so it is aware of what to intention for and when to cease.
The ensuing firmware code seems like this (that is the WPS mechanism):
void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &got_ip_event_handler, NULL));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
/* Read any Wi-Fi credentials esp_wifi's personal config retailer already holds
* (WIFI_STORAGE_FLASH, the default -- backed by NVS) BEFORE beginning
* the driving force. A freshly mass-erased board has none; a board that
* already accomplished WPS as soon as and rebooted does. */
wifi_config_t stored_config;
memset(&stored_config, 0, sizeof(stored_config));
esp_err_t get_config_err = esp_wifi_get_config(WIFI_IF_STA, &stored_config);
bool has_stored_creds = (get_config_err == ESP_OK) && (stored_config.sta.ssid[0] != ' ');
ESP_ERROR_CHECK(esp_wifi_start());
if (has_stored_creds) {
esp_wifi_connect();
} else {
start_wps();
}
}
Setting up the person flows
The person flows listed below are easy: the person opens the app, enters the Wi-Fi password, and the ESP32 joins the community. The specifics differ by methodology, so every of the 5 will get its personal path to get there, written out step-by-step in Groundrun’s movement builder.


Claude did the mapping, with the Groundrun talent set, and every movement is one thing Claude Code can run once more by itself.
Running the exams
Now the whole lot is up and operating, so we are able to run the Wi-Fi setup flows, each interactively within the Groundrun coordinator and as a Continuous Integration (CI) regression check run.
We run the regression exams on each change: no matter we modify within the system, this half has to remain stable.

These regression runs additionally include the over-the-air replace exams we focus on in breaking an OTA update on the ESP32 on purpose.
Timing
Every CI run is timed mechanically, and the coordinator information every step individually, so we are able to break that point down by what it was spent on: flashing the firmware, putting in and launching the app, operating the mechanism itself, and ready for the board to substantiate it joined.
The graph exhibits that flash and boot price about the identical in all places, 22 to 24 seconds, aside from SmartConfig, which additionally flashes a second board we use to observe for its broadcast, pushing that part to 37 seconds. Past that, the mechanism phase varies rather a lot from methodology to methodology, so it is price evaluating by itself.
Isolated this manner, Soft AP’s mechanism time is almost 13 instances WPS’s, which tracks with its system dialog and multi-screen movement. SmartConfig and WPS each keep below 15 seconds, nicely behind Bluetooth, Soft AP, and captive portal.
Quirks
Testing all 5 strategies facet by facet turned up actual variations between them.
Captive portal is the trickiest of the 5. The sign-in web page the cellphone exhibits stays open for only some seconds, and the cellphone’s personal working system alone decides precisely when to shut it. The entire type has to get crammed in and submitted inside that window, or the credentials by no means attain the board.
Bluetooth and Soft AP each set off a system pop-up earlier than the cellphone joins the board’s community, and that pop-up can take a number of seconds to look whereas the cellphone scans for the board. Our exams anticipate it.
WPS wants no app in any respect. Once somebody presses the button, the router and the board alternate credentials instantly.
SmartConfig ran noticeably slower than the opposite 4 in our testing, and infrequently a lot slower than that, with the uncommon failure that had no single traceable trigger.
Testing WPS additionally meant standing in because the router ourselves. Our rig brings up its personal non permanent Wi-Fi community, pinned to 2.4 GHz because the board’s radio would not attain 5 GHz, then tears it down once more after every run.
Conclusions
The very first thing a person does with any Wi-Fi-enabled related product is ready up the Wi-Fi, so it needs to be essentially the most stable mechanism within the system.
The Groundrun system lets us arrange person flows and automatic testing for this mechanism, with {hardware} within the loop.
See how Groundrun runs hardware-in-the-loop eventualities on the platform overview.
