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.