This is probably pretty niche.
tl;dr: you can keep gadget mode working on the Pi Zero with Balena’s soft-AP mode if you disable dhcpcd only for wifi (see how below).
Jasmine, Henry and I are doing a workshop at work (we’re making Radiodan-neues). We’ve got 20 people making their own, using Raspberry Pi Zeros. Some of them have no experience with Pis, command line interfaces, linux etc, so we wanted to make getting the device on the wifi network easy.
This is something we’ve been going on about in Radiodan for years – it’s the difficult part of making a device from a Pi that’s end-user-ready. If you’re happy with the command line and text files you can create a
wpa_supplicant.conf file, put it in
/boot while the SD card is in your laptop and all is well (it gets copied to the correct place on the Pi on boot). But we thought in our case it would be tough to lead 20 people through that process remotely.
Wifi-enabled Arduino-like things like ESP 8266 and ESP 32 can be made to create their own access point, offer up a webpage that you can enter your wifi credentials into, then join the specified wifi network using those creds (“soft-AP mode“). Andrew Nicolaou modified Balena’s similar technique to work with the Pi without Docker or their infrastructure.
The way Balena do this trick is by using NetworkManager (and some other things like a web server) wrapped in some Rust code. It only offers the access points that NetworkManager finds on a scan, and you can’t add your own wifi network if it’s not on the list. For some reason, only on a Pi Zero, my wifi network doesn’t show up. Lots of other networks show up, it’s just mine. :head-desk-emoji:.
So I’ve been setting up Balena’s technique using a Zero in the amazing gadget mode (which means you can access the device via USB). Because it can’t find my wifi network, when I test it by unplugging the USB, I’ve essentially bricked that card (I can still access it over its own AP but I can’t do anything that requires going on a network). Gadget networking stops working, I’m guessing because it depends on dhcpcd which is uninstalled by the Balena code, because it’s not compatible with NetworkManager, at least on the Pi.
So, we were looking for way to keep the Balena AP stuff but also have a back up method, e.g. the wpa_supplicant file technique, or the gadget network.
You can keep gadget mode working if you disable dhcpcd only for wifi. Which is dead easy – edit
/etc/dhcpcd.conf and add
denyinterfaces wlan0 to the bottom, and restart dhcpcd:
sudo systemctl restart dhcpcd.service
It took me so long to figure that out. I do not enjoy linux networking stuff.
Digging into it a bit more:
You can’t use the
wpa_supplicant.conf trick with Balena. This is because NetworkManager (and so Balena) can’t access the wifi when dhcpcd has control over it, and this is how wpa_supplicant works on the Pi, via dhcpcd. With NetworkManager dhcpcd both enabled, you get wlan0
nmcli dev status
DEVICE TYPE STATE CONNECTION
wlan0 wifi unavailable --
usb0 ethernet unmanaged --
lo loopback unmanaged --
But we can use gadget mode and that’s good enough for us I think: we can rescue any people having trouble with wifi and lead them individually through gadget mode, but we don’t have to do that for everyone.
The final step is to include a bash scipt like this and run it on startup e.g. with systemd:
if [ $? -eq 0 ]; then
printf 'Got wifi - skipping WiFi Connect\n'
printf 'No wifi, trying ethernet'
output=$(curl -Is http://www.google.com | head -n 1)
if [[ $output =~ $pat ]]; then # we have ethernet
printf 'Got ethernet - skipping WiFi Connect\n'
printf 'No wifi or ethernet found - starting WiFi Connect\n'
sudo wifi-connect -o 7777
if [ $? -eq 0 ]; then
An additional note: I discovered that if the Zero is in gadget mode then you can access its Samba-enabled directories, so you could for example, allow people to use Samba to drag a
wpa_supplicant.conf file to the
/boot directory. There’s an example of how to enable Samba on a Pi which Dan Nuttall set up for radiodan-neue here. This is no good for us, but pretty cool nonetheless.