ESP32 and Hidden Networks
Change occasionally throws us a curve ball and this was the case last month. The last two months have been devoted to working on rebasing NuttX firmware bringing an old code base up to the 12.12 release. This meant working on core features, no networking.
Time to break out the ESP32 and work on some work items to improve the code and add some new features.
Minor Code Change, Major Problem
The first changes were all minor bringing some consistency in the code base. For instance, deciding to use one of memset or bzero to clear a block of memory. Small changes that should not impact functionality.
Time to build and deploy the code and run the unit tests. First test, connect to access point – FAIL. A basic test failing and the analysis of the changes show that the changes should not have an impact on network connectivity.
In cases like this it is often useful to go back to basics and pick up one of the samples from the SDK, the examples/wifi/getting_started/station will be a good starting point. Running the sample application with the correct SSID and WiFI password also fails. The application does not generate any errors, it simply fails to log on to the network in exactly the same way that it would if the SSID or password were incorrect.
World Safe Country Code
By default the ESP32 uses a default country code of 01. This acts to restrict a number of features to ensure that the device is safe to use amongst the widest possible range of countries. Applying this code restricts the number of channels and power of the WiFi signal (amongst other things). A side effect of this is to change the scan mode which impacts the devices ability to connect to an access point.
From the ESP IDF Country Code Documentation:
Always keep in mind that if an AP with hidden SSID and station is set to a passive scan channel, the passive scan will not find it. In other words, if the application hopes to find the AP with hidden SSID in every channel, the policy of country info should be configured to WIFI_COUNTRY_POLICY_MANUAL.
and…
For scan: Use active scan from schan to schan + nchan – 1.
Active Scan: The ESP32 sends probe requests out to the channels and receives responses from access points.
Passive Scan: The ESP32 simply switches to a channel and listens for incoming beacons.
The side effect of this is that using the default configuration (WIFI_COUNTRY_POLICY_AUTO) will prevent an ESP32 device from logging on to a hidden network on channel 13.
This is precisely what had recently happened, the local access point had changed to a hidden network.
Code Change
The solution is simple, set the country code after the call to esp_wifi_init(). So something like:
esp_err_t result = ESP_OK;
if (result == ESP_OK)
{
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
result = esp_wifi_init(&cfg);
}
if (result == ESP_OK)
{
wifi_country_t country = {};
strcpy(country.cc, "GB"");
country.schan = 1;
country.nchan = 13;
country.policy = WIFI_COUNTRY_POLICY_MANUAL;
result = esp_wifi_set_country(&country);
}
Deploying this code resolves the problem in the sample application. Transferring the code to the production firmware also works.
Conclusion
The minor code changes were minor and were not impacting the application functionality. The issue turned out to be a recent infrastructure change designed to improve security of the local network.
On the plus side, the production firmware now deals with hidden networks on channel 13, something that would previously cause issues.
Next up, work out how to allow the user to specify the country code dynamically.
Tags: ESP32, Software Development
Monday, June 1st, 2026 at 12:01 am • ESP32, Software Development • RSS 2.0 feed • leave a response or trackback