Sat, 11 Sep 2021
There are a few reasons you might want to build your own image instead of using my pre-built one. Maybe I got hit by a bus and havenât kept the repository up to date. Maybe you are running a different SBC and canât run Raspbian. (If you find a different SBC that works in gadget mode, [tell me]({{ site.url }}contact/)!) Maybe you just donât trust me. These are all good reasons (except the bus).
This is how to build the image that I built. If youâre starting from a different base, hopefully I explain what Iâm doing well enough to figure out how to do the equivalent.
Download an image for Raspberry Pi OS Lite.
Flashing the OS
Weâre going to unpack that image onto the SD card, in a format that the Pi will run off of. Put the SD card in the reader and open whichever imager youâve chosen. Both work the same way: pick a device, pick what you want to put on it, push the button. With Etcher youâll have to point it to the image youâve downloaded, with Imager youâll have to pick Lite. Both should find the card, though if you have other USB storage devices plugged in make sure you pick the right one. Thatâll take awhile.
Naming your Pi
Once thatâs done, your computer should recognize the SD card just like a thumb drive. It will have two partitions, boot
and rootfs
. Open rootfs
, and then the etc
folder. There will be a file named hostname
and a file named hosts
. Edit those using a basic text editor â Notepad, Leafpad, etc. hostname
is just what it says: the hostname only. Thatâs your Piâs name, as itâll appear on your network. You could leave it as raspberrypi
, sure, but what if you get more Piâs? Give it a simple letters-and-maybe-numbers name, lowercase, something like pe800
or janome
. Save that, and go to hosts
and do the same thing â there will be other stuff in that file, but the last line will contain raspberrypi
and thatâs what you want to replace.
Let it on the wifi
Now go to the partition named boot
. First weâre going to tell the Pi that itâs okay to allow ssh connections. Create a file named ssh
. Thatâs it. No extension, no contents, it just has to exist.
Next weâre going to tell the Pi the wifi password. Create a file named wpa_supplicant.conf
, also in boot
. Edit that file to contain this:
country=US
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="WIFI_SSID"
scan_ssid=1
psk="WIFI_PASSWORD"
key_mgmt=WPA-PSK
}
Put in your actual wifi ssid (the network name) and password, of course. Save that file, unmount the SD card, and take it out of the reader.
Wake up the Pi
Put the SD card in the slot on the end of the Pi, and connect it to power. It should light up, and in a moment or two if all goes well it will be on your wifi network. The fun part is finding it. Open your SSH client and do what you need to do to connect â add a host in something like Termius. Unless your base OS multicasts, you have to figure out what numeric address your network assigned it.
Your router/cable-modem may give you a list of everything itâs assigned numbers to, in which case you just have to look for your Piâs name in the list. If not, your computer should be able to tell you its own numeric address, and then itâs just a matter of knocking on all the doors in that neighborhood. The address is going to be something like 192.0.0.100
or 10.0.0.115
and you just have to keep trying to connect to .101, .102, etc. as user pi
with password raspberry
until you find the right door and it lets you in.
(There are more technical ways of finding the Pi â Iâm trying to keep this simple and OS-agnostic.)
(hacker voice) âIâm inâ
The Pi will greet you by telling you you need to change the password. You probably do, because anybody else on your wifi can do that same door-knocking thing and log into your Pi. Unless your network is really badly configured, nobody outside the network can, but thereâs malware that hangs around just looking for devices with factory passwords to build spamming and denial-of-service networks. Change it, and put that password in your password manager now.
Enable the gadget-mode drivers
The drivers to run the thing in gadget mode are pre-installed but not enabled, so letâs do that.
sudo nano /boot/config.txt
This will bring up an editor: use your arrow keys to navigate to the bottom and add:
# Go go gadget mode
dtoverlay=dwc2
Hit Ctrl-X to exit, Y to save, enter to keep the same filename. Now do the same thing with the next file:
sudo nano /etc/modules
but this time add
# Go go gadget mode
dwc2
Carving a decoy
Now weâre going to have the Pi build a carefully-crafted file that it is going to hold up to its USB port for the embroidery machine to see as a USB drive. Type this at the command line.
sudo dd bs=1M if=/dev/zero of=/piusb.bin count=2048
When you hit enter, nothing will appear to happen. The Pi is busy making the blank for the decoy. Seriously, itâs building a file of two billion zeroes, itâs going to take awhile. When itâs done, the prompt will come back. Now tell it to carve that blank into the shape of a USB drive.
sudo mkfs -t fat /piusb.bin
This will go quite a bit faster. Itâs now got a file that looks like a 2GB FAT flash drive. Not large, but it should be compatible even with older embroidery machines. (If you want a larger flash drive for a 3d printer or TV or whatever, youâll need to go with exfat
instead; thatâs a little outside the scope of this but DuckDuckGo is your friend.)
Now you need to give your imaginary USB drive an imaginary port (my analogy is getting a little stretched, bear with me.
sudo nano /etc/fstab
Thatâll bring up an editor. Go to the bottom of the file and add this line:
/piusb.bin /mnt/usb_share auto users,umask=000 0 2
Hit Ctrl-X to exit, Y to save, enter to keep the same filename. Now every time the Pi boots up, it will mount the imaginary USB drive into its imaginary port. Letâs do that
sudo shutdown -r 0
The Pi will kick you out of your ssh (Termius, etc.) session. Give it a few moments to finish all its rebooting, and log back in (remember to use the new password you created. You recorded it somewhere, right?)
Testing the decoy
Now youâre ready to tell the Pi to hold that imaginary flash drive up to its data port for the embroidery machine to see.
sudo modprobe g_mass_storage file=/piusb.bin stall=0 ro=0 removable=1
At this point, if you plug the cable into the Piâs data port (donât forget the power blocker!), the embroidery machine will see a blank USB drive. If itâs prone to âformattingâ a newly-installed drive by putting directories on it, it will probably do that now, so let that finish before moving on. If your machine has internal storage and can save designs from it to the USB, you can give it a try. dir /mnt/usb_share
from the Pi should show you those files when itâs done. When youâre done with that, take the imaginary drive away:
sudo modprobe -r g_mass_storage
The embroidery machine should react as though you unplugged a physical USB drive.
Connecting from a PC
If you run Linux on the desktop like I do, you can just use sshfs
to mount /mnt/usb_share
to a local directory and skip this section. Itâs much simpler to connect Linux-to-Linux that way, but Iâm assuming you want to connect from a Windows machine, which requires Samba.
Back at the ssh session, type these three commands:
sudo apt-get update
sudo apt-get install samba winbind -y
sudo nano /etc/samba/smb.conf
There will be a little pause and some scrolling as the install works, some prompts that you can just press Enter for, and then youâll be editing a configuration file. Go to the bottom of the file and add:
[usb]
path = /mnt/usb_share
browsable = yes
public = yes
available = yes
force user = pi
read only = no
create mask = 0700
directory mask = 0700
Ctrl-X, Y, enter. Then reload Samba to enact the changes:
sudo systemctl restart smbd.service
Now letâs assign a Samba password:
sudo smbpasswd -a pi
It will ask for the old password (press enter), and then a new password twice. Record this one in your password manager too.
Now you can press Windows+e to open the Windows explorer, type \\PIHOSTNAME. You should see the usb_share folder, and be able to read, write, and delete files to it. Itâs open to your whole network, so if you donât want everyone in your house to be able to access it, remove the public = yes
line and use the password you created.
If you also want to mount it on a Linux machine, from that machine you just need to type:
sudo mount -t cifs -o username=pi%SAMBAPASSWORD,user=pi,uid=LOCALUSERNAME //XX.XX.XX.XXX/usb /mnt/PIHOSTNAME
(The mount point doesnât have to be named with the Pi hostname if you have a different convention on your machine.)
Automate the reconnect
The imaginary USB drive needs to disconnect from the embroidery machine while youâre writing it, and reconnect when youâre done. Weâre kind of bypassing some of the conflict resolution because everything assumes a USB stick can only be plugged into one machine at a time, and this will help make up for it. Itâs not perfect, but itâll help keep things from being corrupted. Type these commands on the Pi:
sudo apt install python3-pip
sudo pip3 install watchdog
When the installations are done, type
sudo nano /usr/local/share/usb_share.py
Go to this link, copy the whole page, and paste it into the editor.
We need to make a few little changes to it,
Right at the top, we want to add a sudo
in front of each of the commands:
CMD_MOUNT = "sudo modprobe g_mass_storage file=/piusb.bin stall=0 ro=0 removable=1"
CMD_UNMOUNT = "sudo modprobe -r g_mass_storage"
CMD_SYNC = "sudo sync"
Ctrl-X, Y, enter. Now weâre going to tell the Pi to run that little watchdog program every time it boots:
sudo chmod +x /usr/local/share/usb_share.py
sudo nano /etc/systemd/system/usbshare.service
In the editor, paste:
[Unit]
Description=USB Share Watchdog
[Service]
Type=simple
ExecStart=/usr/local/share/usb_share.py
Restart=always
[Install]
WantedBy=multi-user.target
Ctrl-X, Y, enter.
sudo systemctl daemon-reload
sudo systemctl enable usbshare.service
sudo systemctl start usbshare.service
Thatâs it! Your Pi is now a wireless USB stick!
You can type exit
to leave the ssh session. Donât forget to delete the Raspbian image off your PC if you downloaded it there. It takes up a lot of space and you wonât need it again.
Shutting down the Pi
To turn off the Pi, you want to do a clean shutdown. You could just unplug it, but that risks corrupting the SD card. Open the SSH client and log in as pi with the password you set at the very beginning. Type these commands to turn everything off.
sudo systemctl stop usbshare.service
sudo systemctl stop smbd.service
sudo modprobe -r g_mass_storage
sudo umount /mnt/usb_share
sudo shutdown -h 0
Itâll give you a quick warning and boot you out of the session (the zero is the number of seconds before shutdown, so we told it not to wait for anything).
After a second or so, you can unplug the Pi safety. Plugging it back in will turn it on, and it will restart everything and be ready to serve files again.
If you regularly turn the Pi on and off, youâll probably want to do two things. One, get a USB cable with a switch in it, so you donât have to physically unplug it every time. Two, you can shorten those commands:
nano cleanstop
Copy and paste the above shutdown commands into the file, then ctrl-X, Y, enter. Now type
chmod u+x cleanstop
to tell the Pi thatâs a file full of commands you can run. Now instead of typing all five commands, you can just say ./cleanstop
and it will shut down. You can even just type ./c
+ tab and it will autocomplete it for you to press enter on.
Rebuilding the decoy
The watchdog isn't perfect - my Janome apparently pokes at the USB drive now and again, enough to occasionally cause corruption if I forget and open the mounted directory while the machine is powered on. For this you'll want the newusb
command file.
nano newusb
Copy and paste these commands into it, ctrl-X, Y, enter.
sudo systemctl stop usbshare.service
sudo systemctl stop smbd.service
sudo modprobe -r g_mass_storage
sudo umount /mnt/usb_share
sudo mkfs -t fat /piusb.bin
sudo shutdown -r 0
If you look closely, you'll see it's shutting down all the services that use the drive - the watchdog, Samba, the Mass Storage Gadget bits - and then doing that mkfs
on the decoy. That will completely clear it. And then it's doing a slightly different shutdown, this one with -r
for restart.
chmod u+x newusb
Now if your machine starts objecting to files, you can just say ./newusb
and it will reinitialize. You may need to re-mount the directory on your desktop machine to properly recognize it, and it will be completely empty. REMEMBER: never put your only copy of anything on a USB drive, real or virtual.