Pico WiFi Settings library released
Thursday, 27 March 2025
Today I have released the first version of pico-wifi-settings. This is a library for Raspberry Pi Pico W devices which manages WiFi connections for a Pico application.
It exists because I developed two personal projects using Pico W with WiFi and in both cases I found a need to store a list of hotspots and passwords. It's a simple requirement, taken for granted on phones, tablets and laptops, all of which will remember the details of the WiFi hotspots you have used: the hotspot name ("SSID") and the password. But Pico W has no filesystem and no operating system unless these are part of your application. There is no easy way to store WiFi details.
The Pico examples provided by Raspberry Pi don't solve this problem. Instead, the user is expected to provide the WiFi settings when building the examples, like this:
cmake -DWIFI_SSID=MyHomeWiFi -DWIFI_PASSWORD=MyWiFiPassword -DPICO_BOARD=pico_w
The settings are built into the application. They can't be changed without rebuilding, and only one hotspot is supported. This is fine for a small example but not very practical:
- You can't use your Pico application in a different location (with different WiFi) unless you recompile.
- You can't change your WiFi password unless you recompile.
- You can't share your Pico application binary with someone else as it is hardcoded with your WiFi details.
This is the problem I set out to solve. I wanted to separate application settings from application software: a simple enough matter when there is an OS, and settings are kept in the registry or ~/.config, but more challenging in this small embedded system.
The pico-wifi-settings library is actually an improved version of an earlier solution which I created for a personal project, and then reused for a second project. Both projects required some flexibility for the WiFi configuration. In both cases I really wanted to be able to use the project on my home WiFi and also on mobile WiFi, so I needed support for at least two hotspots. And I change my WiFi passwords periodically, so I wanted support for that too.

I don't have to open this box and connect by USB to update it!
Initially I made a command-line interface for WiFi setup which could be accessed via USB, and reused it in both projects. Settings were saved in Flash, in a fixed data structure. But the implementations diverged and became harder to maintain, and it wasn't easy to update WiFi settings, since it required physical access to the USB port. I found that I wanted to add other types of configuration to Flash, and that I wanted to be able to update it via WiFi, but I didn't want to have to implement these features twice! The solution was to create a reusable library with all of the features I wanted, which could be used any project. I ended up extending it with a feature for over-the-air (OTA) firmware updates which allows me to update my project firmware without any USB connection - highly useful in one case, as the Pico is inside a box and the USB port can only be accessed by unscrewing the lid.
The features of pico-wifi-settings are:
- Flash storage for WiFi passwords and hotspot names ("SSIDs"), completely separate from the application, so that the settings and the application can be updated independently,
- a background async_context service to automatically connect to WiFi using the stored WiFi settings,
- an optional remote update service, secured with AES-256, which allows you to update the WiFi settings remotely,
- an optional over-the-air (OTA) update service for uploading new firmware,
- a Pico W setup tool for first-time setup,
- C/C++ functions to allow access to the WiFi settings file so that it can be used to store application settings as well as WiFi settings.
While I was working on it, Raspberry Pi released Pico 2 W, with twice as much Flash storage and many other improvements. I haven't been able to support all of the Pico 2 W features - for example, the library has never been tested on the Risc V CPU cores, and I have only partial support for partitioning. Full support would be a useful way to support safer over-the-air (OTA) updates by storing both a new and old copy of the firmware and falling back to the old firmware if the new one does not boot. However, this is for the future. I have also not looked at support for the firmware security features. For now, Pico 2 W is working, but support is limited to features that also existed on Pico W.
Particularly fun parts of the project have been:
- Finding a way to replace the current Pico program while it is running for OTA update. The update procedure has to run entirely from RAM and the built-in ROM, and must be written carefully to avoid calling anything in Flash! Then it must reboot into the new firmware. My solution took a few attempts to get right. The J-Link debugger was invaluable.
- Writing an MS-DOS style text-mode setup program - a real throwback to the first programs I wrote (though hopefully a bit more useful). This solves the problem of getting initial WiFi settings onto the board; you can do this by transferring them via USB with picotool (see instructions) but it seemed more helpful to provide an automated search process, since that's how WiFi is generally used.
- Coming up with an encrypted protocol for remote access and thinking about how to make it work securely. It's definitely not SSH - it lacks perfect forward secrecy, for instance. I wanted something really simple that wouldn't require generating SSL certificates with dozens of obscure openssl commands. This is a "shared secret" scheme in which both the Pico and your development PC have the same password/passphrase/key, and then exchange authentication codes to establish a secure connection. The crypto algorithms used are HMAC SHA-256 and AES-256. I initially intended to just have a Telnet or web interface for this, but the lack of security just bothered me too much.
I intend to make further improvements in the future. The project has taken a while to complete, and there will certainly be some bugs in this initial release. The best place to report issues is the issue tracker. As it is open-source (BSD license) you can also contribute to it if you like, and in any case I am happy to hear feedback by email.