piRemote
ZERO-CONFIGURATION REMOTE ACCESS TO ANY MODEL PI VIA WIFI
I needed a way to simplify connecting other people's Pi's to a projector at user group meetings. I normally have my Pi connected via a long HDMI cable to the projector, which is mounted overhead. If someone else needs to use the projector, I have to unplug my Pi and plug their Pi in. It doesn't sound like a big problem, but it doesn't always work due to HDMI peculiarities. And I can't put my Pi up with the projector since the HDMI cable needs to hang down for other people to use, which looks kind of ugly.
The normal way you'd solve this problem is with a wireless HDMI link. That would cost over $200 as of this writing, and would only get rid of the dangling cable. I'd still have to unplug my Pi, and HDMI problems could still mess things up.
It would be nice if the solution would also work with a Pi with a freshly imaged SD card, that might not have been configured yet, or might not have a network interface (such as an A+). The solution should also be inexpensive. And it would be nice if it works when the computer connected to the display is running Windows.
Sounds like a pretty daunting specification, doesn't it? This project details a way to meet all the requirements using just a Pi Zero W.
All Pi's have HDMI output, but they also all have at least one USB port. And a Pi Zero W can emulate most any kind of USB device, even a network adapter. Can you see where this is going? Plug a Zero W into another Pi's USB port, configure it to act as a USB network adapter and WiFi access point, and bridge the connection between the two interfaces. Connect to the Zero W via WiFi from the computer connected to the display, and you have SSH and VNC access to the Pi. The only configuration you might have to do is create an ssh file on the Pi SD card boot partition if SSH hasn't been enabled yet - a task easily done from almost any computer since the partition is formatted as FAT32.
And there you have it. A tiny device, plugged into and powered by any version of the Pi, that lets you have remove access to it from another computer. Even after booting from a fresh SD card. And even if you only have on hand a Windows computer that can't mount Linux partitions.
The necessary configuration files for the Zero W are in this project's files section, but I'll detail the changes below if you want to hand edit them. Please note that the config.txt and fstab files are fragments - their contents need to be added to the END of their respective files, otherwise the Zero W will fail to boot. Don't ask me how I know this.
DOWNLOADING SOFTWARE
Boot up the Pi Zero and, if you haven't already, run raspi-config to make the usual configuration settings. In particular turn on ssh and set the WiFi country.
Connect the Pi Zero to the internet and run the following commands:
sudo su
apt-get install dnsmasq hostapd bridge-utils
touch /boot/ssh
touch /etc/address.sh
chmod 755 /etc/address.sh
GETTING THE WIFI ACCESS POINT WORKING
The /etc/dnsmasq.conf file needs to look like this:
interface=br0
dhcp-range=10.10.10.1,10.10.10.6,5m
port=0
The /etc/default/hostapd file needs to look like this:
DAEMON_CONF="/etc/hostapd/hostapd.conf"
The /etc/hostapd/hostapd.conf file needs to look like this. It will need to be created:
interface=wlan0
bridge=br0
ssid=PiRemote
max_num_sta=1
hw_mode=g
channel=6
wmm_enabled=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=raspberry
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
GETTING THE USB NETWORK ADAPTER GADGET WORKING
The /etc/modules file needs to look like this:
libcomposite
The /boot/config.txt file needs the following 2 lines added at the end:
dtoverlay=dwc2
dtoverlay=gpio-shutdown
The /etc/rc.local file needs to look like this. Make sure it also has executable permissions:
#!/bin/sh -e
#set up network gadget
cd /sys/kernel/config/usb_gadget
mkdir g1
cd g1
echo "64" > bMaxPacketSize0
echo "0x100" > bcdDevice
echo "0x200" > bcdUSB
echo "0x0500" > idProduct
echo "0x03fd" > idVendor
cd functions
mkdir rndis.rn0
cd rndis.rn0
cd ..
cd ..
cd configs
mkdir c.1
cd c.1
echo "500" > MaxPower
cd ..
cd ..
ln -s functions/rndis.rn0 configs/c.1
ls /sys/class/udc > UDC
#display assigned addresses
gpio -g mode 26 out
gpio -g mode 19 out
gpio -g mode 13 out
gpio -g mode 6 out
gpio -g mode 5 out
gpio -g mode 0 out
/etc/address.sh &
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi
exit 0
BRIDGING THE INTERFACES
Reboot the Zero W and log in. Run the following commands:
sudo su
systemctl stop hostapd
brctl addbr br0
brctl addif br0 usb0
The /etc/network/interfaces file needs to look like this:
source-directory /etc/network/interfaces.d
allow-hotplug usb0
auto usb0
iface usb0 inet static
address 10.10.10.11
netmask 255.255.255.0
auto wlan0
iface wlan0 inet static
address 10.10.10.12
netmask 255.255.255.0
auto br0
iface br0 inet static
address 10.10.10.10
netmask 255.255.255.0
bridge_ports usb0 wlan0
The /etc/dhcpcd.conf file needs to look like this:
hostname
clientid
persistent
option rapid_commit
option domain_name_servers, domain_name, domain_search, host_name
option classless_static_routes
option ntp_servers
option interface_mtu
require dhcp_server_identifier
slaac private
nohook wpa_supplicant
denyinterfaces usb0
denyinterfaces wlan0
denyinterfaces br0
The /etc/sysctl.conf file needs to look like this:
net.ipv4.conf.default.rp_filter=1
net.ipv4.conf.all.rp_filter=1
net.ipv4.tcp_syncookies=1
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
FIGURING OUT WHICH IP ADDRESS HAS BEEN ASSIGNED TO THE PI
The /etc/address.sh file needs to look like this. Make sure it also has executable permissions:
#!/bin/bash
while true; do
#all lights off
gpio -g write 26 0
gpio -g write 19 0
gpio -g write 13 0
gpio -g write 6 0
gpio -g write 5 0
gpio -g write 0 0
#parse leases file
for ADDR in `grep -v "*" /var/lib/misc/dnsmasq.leases | cut -d . -f 4 | cut -c 1`; do
#turn on correct lights
case $ADDR in
1) gpio -g write 26 1 ;;
2) gpio -g write 19 1 ;;
3) gpio -g write 13 1 ;;
4) gpio -g write 6 1 ;;
5) gpio -g write 5 1 ;;
6) gpio -g write 0 1 ;;
esac
done
sleep 10
done
Wire an LED to each of the Pi's GPIOS 0, 5, 6, 13, 19 and 26. Each LED anode is connected to one GPIO. All of the LED cathodes are connected together, and then connected via a 1K ohm resistor to one of the ground connections on the Pi GPIO header.
LIMITING SD CARD CORRUPTION
Connect a momentary switch between GPIO 3 and one of the ground connections on the Pi GPIO header. This will be a shutdown switch.
The following four lines need to be added to the end of the /etc/fstab file:
tmpfs /tmp tmpfs defaults,noatime,nosuid,size=0755,size=10m 0 0
tmpfs /var/log tmpfs defaults,noatime,nosuid,mode=0755,size=10m 0 0
tmpfs /var/cache tmpfs defaults,noatime,nosuid,mode=0755,size=10m 0 0
tmpfs /var/tmp tmpfs defaults,noatime,nosuid,size=10m 0 0
tmpfs /var/lib/misc tmpfs defaults,noatime,nosuid,size=10m 0 0
The /etc/dphys-swapfile file needs to look like this:
CONF_SWAPSIZE=0
Reboot and you're ready to go.
TODO: add an RO setting to kernel/sd card?
USING IT
Activate SSH on the Pi you're going to remote access. This can be done by simply putting a file called ssh on it's SD card boot partition. It's contents don't matter.
Plug the Pi Zero into the Pi using a Micro USB cable. Use the USB connector on the Zero W closest to the HDMI connector. Make sure the cable has data lines - some inexpensive cables that come with chargers or power banks do not.
Power up the Pi and let it finish booting up. Notice which LED is lit on the Zero W - each corresponds to the IP address assigned to the Pi, from 10.10.10.1 (the LED closest to the end of the Zero W) through 10.10.10.6 (the LED closest to the middle of the Zero W). As an aside, if you don't have LEDs installed you can SSH into the Zero W at 10.10.10.10 and view the /var/lib/misc/dnsmasq.leases file to see which IP address was assigned.
Connect to the Zero W with any computer via WiFi. The SSID is PiRemote, the password in raspberry. (These can be changed in the /etc/hostapd/hostapd.conf file on the Pi Zero later if you wish.) Another LED will light, corresponding to the IP address of the computer. Make note of this if you reboot the Pi, as the address assigned to the Pi will most likely change after a reboot.
Start up an SSH program (such as Putty for windows, or ssh on a Linux computer). Connect to the IP address of the Pi and log in. From here, you can run sudo raspi-config to enable VNC if you wish.
When done, run the sudo shutdown +1 command on the Pi, then immediately press the shutdown switch on the Zero W. The Zero W will shut down in about 20 seconds, the Pi in about 1 minute 30 seconds. Watch the power LED on the Pi to determine when it's safe to disconnect power.
You can also use the Zero W by itself by powering it with an adapter or power bank, connecting to it via WiFi, and connecting to 10.10.10.10 via SSH. Or just plug it into a USB port - it will show up as a network adapter at the same address.