mini project: the Raspberry Pi Zero USB gadget
Of all of my projects, this one is probably going to be one of the easier ones. This project is a little more open ended, but all you really need is the following:
- Raspberry Pi Zero W (Adafruit)
- Raspberry Pi Zero Case (this one or this one, for example)
- Micro USB Data Cable (not a charge-only cable) (Amazon)
The challenge for many of us that we’re not always at our test bench, and making Pi equipment portable gets bulky really fast. If you’re using a regular Raspberry Pi, you need a Pi, an enclosure, a power adapter, and a wireless network to join- just as an example.
Where this gets complicated is if you’re in a spot where wireless is expensive (like an airport) or tightly regulated (like your work or school). An easy workaround is to turn on tethering on your mobile phone, but running your PC’s internet through tethering gets expensive, and fast.
The fix is actually pretty simple, and uses some common approaches well documented already- but in a typical weekend project, we’ll pull a few articles together to get you this project.
As you can see there’s only a few things to do- enable networking over the USB port, and configure the wireless interface. There are already how-to’s for different PC/Mac platforms, but this guide covers all of them in a single approach.
First, what we need to do is enable the USB Gadget support on the Raspberry Pi Zero W. This will let the Raspberry Pi turn the USB data port into an Ethernet USB adapter. It’s pretty easy. Run the following command:
sudo nano /boot/config.txt
And add the following lines to the end- the # sign allows us to place a comment so we can leave a note for ourselves later.
#added for USB gadget support
dtoverlay=dwc2
Next, we need to modify another boot file, go ahead and run
sudo nano /boot/cmdline.txt
and add this specifically to the end of the line:
modules-load=dwc2,g_ether
It will look something like this:
If you haven’t already, go ahead and make sure you’re on the wireless network at home by running
sudo raspi-config
Go into Network Options -> Wi-Fi and enter your wireless network info. Next, go into Interfacing Options -> SSH -> Enable SSH when asked.
With an HDMI cable plugged in, go ahead and exit out of raspi-config and reboot.
When you reboot, look at the boot messages just before you get to the login prompt, you should have a wireless network IP. Let’s say it’s 10.1.1.22. Go ahead and login via SSH by running from your PC or Mac console:
ssh -l pi 10.1.1.22
Answer yes when prompted and go ahead and login. The next thing we’ll do is make some major changes to the networking system on your Pi, so if you have stuff you need to back up, or you’re not starting from a fresh Pi install, go back and resolve those things now.
OK, so before jumping in, here’s what we’re going to do- we’re going to remove the dhcpcd program, which handles address assignment for the Raspbian install on the Pi we have now. There are reasons why you want to leave that in place for other Pi systems, but in order to do what we want, we need it gone. We’re also going to install the DHCP server software dnsmasq, which will let us run our own little DHCP server on the USB port. This will let us connect the Pi to a Linux, Mac, or Windows PC without needing any additional software. Finally, we’ll also add network entries for the WiFi adapter and the USB Ethernet allowing us to do something pretty cool- connect to our PC over USB while also connecting to our phone’s tethered hotspot for the Pi Zero W.
Install dnsmasq:
sudo apt-get install -y dnsmasq
Configure dnsmasq:
sudo nano /etc/dnsmasq.conf
Add the following lines at the bottom:
dhcp-range=10.77.77.78,10.77.77.99,12h
dhcp-option=3
dhcp-option=6
The DHCP range will need to match the interface IP address we assign to the usb0 interface in the next step. DHCP options 3 and 6 are annotated in the config file, but they prevent dnsmaq from advertising a default route or dns- we don’t need this Pi to be a DNS server or a router for this tutorial.
Go ahead and save and exit from the file, we won’t start dnsmasq just yet though.
Next, we’re going to disable dhcpcd, the current system that assigns IP addresses. Disable it with:
sudo systemctl disable dhcpcd
Now let’s add our manual network interface setup:
sudo nano /etc/network/interfaces
In there you will probably see something that says:
source-directory /etc/network/interfaces.d
Go ahead and leave that in. Below it, add all of this text, paying attention to the indents:
auto lo
iface lo inet loopback
auto usb0
allow-hotplug usb0
iface usb0 inet static
address 10.77.77.77
netmask 255.255.255.0
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
Go ahead and save and exit- remember the address set for usb0 needs to line up with the dnsmasq.conf settings from above.
Finally, let’s make sure your phone’s hotspot connection is in /etc/wpa_supplicant/wpa_supplicant.conf.
Run:
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
In there, each network should be listed like this:
network={
ssid="Your-Phone-Hotspot-SSID"
psk="yourpassphrase"
}
With that done, go ahead and run this command to reboot:
sudo halt
Give the Pi 30 seconds or so to shut down, then unplug it. You should not need any power cord, just the USB data cable plugged into your desktop or laptop on one end, and the micro USB port on the Pi Zero W that’s closest to the middle of the Pi. When it boots it will look like a network adapter, and it should assign an IP address in the 10.77.77.x range to your computer. You should be able to open a command prompt on your PC or Mac and type:
ssh -l pi 10.77.77.77
And login. If you haven’t changed your password- do it now with this command:
passwd
After that, you should be able to run
ifconfig -a
and see an IP address on your wireless network adapter. The Pi Zero W is slower than many modern Pis, so it may take a couple minutes after boot to get an IP address.
Now that you’re setup, you can plug your Pi directly into your PC and get to it without any 3rd party software and the Pi can use a separate wireless network such as your phone. This helps create a setup that’s friendly for travel and requires very little cost. I hope you find this helpful.
Reference:
- Thanks to Kevin Shumaker (@Starbasessd on Twitter) for his nudge in the right direction, specifically that dhcpcd and /etc/network/interfaces were conflicting.
- Adafruit’s USB Gadget Learning Guide
- Setting static IP addresses for usb0
- Circuit Basics’ Raspberry Pi USB Gadget Guide
Comments ()