RSS

Posts Tagged ‘ESP32’

ESP32 and Hidden Networks

Monday, June 1st, 2026

ESP32 and Hidden Networks Banner

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.

Espressif Installation Manager (EIM)

Sunday, March 29th, 2026

EIM Banner

Espressif has recently released a cross-platform installation manager for the SDK used with ESP32 boards.
ESP-IDF Installation Manager (EIM)
is available for macOS, Linux, and Windows. The aim of the tool is to simplify the installation of ESP-IDF and its associated tools.

EIM also allows multiple copies of the framework to be installed on the same machine, allowing developers to switch between versions. This is ideal for testing different IDF versions against a code base.

Various IDF archives can be found on the
EIM Offline Installer downloads page.

First Impressions

So far, the tool has delivered on the promise of providing an easy, switchable way to install the various tools and SDKs. Installation of the tool is straightforward, and the SDKs are downloaded as archives and then loaded into the system using EIM. The same tool is used to switch from one IDF version to another.

Aside from one caveat, which will be covered later, the tool does exactly what it says on the tin, offering a simple way to install and switch between IDF versions.

Installing an IDF Version

Installation of the tool itself went smoothly; only two brew commands were needed.

brew tap espressif/eim
brew install eim

It is then necessary to download and install the archives for the IDF versions of interest. This is simply a case of navigating to the
EIM Offline Installer downloads page,
selecting the desired IDF version or versions, and downloading them locally. These archives can be large, with some coming in at 2.5 GB.

Once downloaded, an archive can be installed into the EIM system with a command such as the following:

eim install --use-local-archive archive_vv6.0_macos-aarch64.zst

The downloaded archive file can be deleted once an IDF version has been installed. The full list of installed versions can be obtained using the command:

$ eim list
2026-03-29 09:00:12 -  9 - 03 - INFO - Listing installed versions...
Installed versions:
- v5.5.3 (selected) [/Users/username/.espressif/v5.5.3/esp-idf]
- v6.0 [/Users/username/.espressif/v6.0/esp-idf]

An installed version can be activated with the command:

source /Users/username/.espressif/tools/activate_idf_v5.5.3.sh

This command registers the various environment variables, Python environments, and related settings:

Added environment variable ESP_IDF_VERSION = 5.5
Added environment variable IDF_TOOLS_PATH = /Users/username/.espressif/tools
Added environment variable IDF_COMPONENT_LOCAL_STORAGE_URL = file:///Users/username/.espressif/tools
Added environment variable IDF_PATH = /Users/username/.espressif/v5.5.3/esp-idf
Added environment variable ESP_ROM_ELF_DIR = /Users/username/.espressif/tools/esp-rom-elfs/20241011
Added environment variable OPENOCD_SCRIPTS = /Users/username/.espressif/tools/openocd-esp32/v0.12.0-esp32-20251215/openocd-esp32/share/openocd/scripts
Added environment variable IDF_PYTHON_ENV_PATH = /Users/username/.espressif/tools/python/v5.5.3/venv
Added proper directory to PATH
Activated virtual environment at /Users/username/.espressif/tools/python/v5.5.3/venv
Environment setup complete for the current shell session.
These changes will be lost when you close this terminal.
You are now using IDF version 5.5.
eim select v5.5.3

Once complete, the selected IDF version is ready to use.

Scripting

Now to the caveat mentioned earlier.

Using idf.py from the command line works fine, as do all the other tools. Things are a little different when it comes to scripting.

On macOS, EIM exposes idf.py via a shell alias. In practice, it looks something like this:

alias idf.py='/Users/username/.espressif/tools/python/v5.5.3/venv/bin/python /Users/username/.espressif/v5.5.3/esp-idf/tools/idf.py'

As mentioned, this works on the command line. However, it does not work in a bash script, as aliases are not normally expanded in non-interactive bash scripts. The solution is to define a variable in the bash script that points to the idf.py Python script file:

IDF=$IDF_PATH/tools/idf.py

It then becomes a simple case of replacing idf.py with $IDF within the script. So far, this solution has worked both locally and in a GitHub Action.

EIM GUI

Espressif also offers a GUI version of the installation manager. This was installed briefly but removed after Malwarebytes detected an attempt to access a website that it identified as potentially serving a Trojan.

This was did not seem to be a problem with the command line version of EIM.

Conclusion

EIM provides a simple way to install ESP-IDF versions and switch between them. It should make the setup process more straightforward, particularly for users on platforms where ESP-IDF installation has traditionally been less convenient.

Getting Started with Rust

Wednesday, October 1st, 2025

Rusty Bolts

Last year saw the push towards using safer programming languages. Languages such as C# and Rust, languages that help the developer avoid mistakes common to C and C++ (although there is a movement to make C++ safer to use).

It is time to take a look at Rust as a language and more specifically how easy it is to develop code that will run on a micrcontroller.

General Rust

The usual place to start is the The Rust Programming Language (Rust 2021) book.

There are also a number of online resources:

Only time will tell how good these resources are.

Microcontroller Specific

Initial learning will be laptop based as it will be easier to gain familiarity with the language. It will certainly be quicker than the usual develop, deploy and debug cycle that slows down firmware development.

The eventual aim is to move over to development for microcontrollers, likely the ESP32 variants or Raspberry Pi Pico boards. With this in mind the following Rust and micrcontroller resources are looking like they will be useful:

The microcontroller part of the journey will look at using the ESP32C6 microcontroller as this is on the supported list for both the bare metal and IDF versions of the HALL (see below).

ESP Hardware Abstraction Layer (HAL)

Espressif have released two versions of the HAL one supporting the IDF framework and one for bare metal applications:

Installation and use is covered in the Rust on the ESP Book.

Let’s get started and see where this takes us.