Wake-on-LAN is a great tool and allows your home PC to seem almost cloud-like. You can switch on your PC without needing to touch it, and have it available when you need it without it using power constantly.
However, there are some drawbacks. It won’t work from a cold-start, that is the first time you power cycle the PC. On some motherboards, it won’t work if you issue a shutdown command, and Windows and Linux can operate differently, even on the same motherboard. It does seem to work well for the suspend modes (S1-S3), but then you’re consuming more power than an S5 soft-off state. Of course, if you suspend and then lose AC power not only can you not restart, it may also corrupt your system.
Then, of course, it’s called wake-on-LAN, not sleep-on-LAN, so there’s no way to turn it off again. “Ah-ha”, you might say, “log on remotely and issue a shutdown command”.
That’s all possible if your machine hasn’t crashed or frozen, with a kernel panic or just the old-fashioned BSOD. What about a simple reset? These things are taken for granted when you’re physically near the machine.
After years of struggling with variable levels of success with W-O-L, I decided to fix the problem by fitting a second PC inside my home computer. It’s not as silly as it sounds, because of the internet-of-things and the truly amazing work of the Raspberry Pi foundation.
One of their latest IoT devices is the Raspberry Pi Zero W and it’s tiny. “I can’t believe it actually runs Linux”, sort of tiny. Even smaller than my CPC2 board, tiny. At 65mm by 30mm, it dwarfs the original ‘tiny’ Raspberry Pi. I bought mine from the awesome guys at Core Electronics. They’re a local Aussie start-up and sell all the coolest stuff from AdaFruit, SparkFun, Raspberry Pi Foundations and heaps more. Instead of ordering from overseas, paying USD and waiting for ages, ordering from these guys is quick and easy. I had two Raspberry Pi Zero W’s in my hands in a few days. What’s more, the version I ordered had the GPIO pins already soldered in, so connecting up was a breeze.
The objective was to have this tiny device, complete with its independent WiFi connection sitting inside the PC, connected to the motherboard pins for power and reset. This set-up would allow me to control these two buttons from anywhere on my local network. It’s then a small step then to use my existing Raspberry Pi WebServer to issue the correct network commands in response to a Web Page request from anywhere on the internet.
The really cool thing is where this Pi Zero gets its power from. Most modern motherboards have USB charging circuits built-in so that you can charge your phone, even when the PC is powered off. Of course, this can also power the Raspberry Pi Zero W, when the PC is off. This is exactly what we need to turn the PC back on. The Raspberry Pi waits for a command to be received over its Wi-Fi connection and based on the instruction either toggle the power pin, or the reset pin in response to the command.
To power on modern PC, the power pin on the motherboard header simply needs to be grounded. This is usually done with a momentary mechanical push switch, to connect the PowerOn line to GND. In this case, I’ll be using the GPIO pins on the Pi Zero to connect this signal to GND through the IO buffer of the Pi ARM SoC. Conveniently, as we’re powering the Pi from the USB charge ports, the GND signal is already connected to the Pi through the USB connection. All that needs to be done is to toggle the GPIO pin between High/1 and Low/0 to trigger a power or reset action and return it back to High/1.
A quick test with the multimeter shows that on my motherboard at least, the PowerOn line runs at 3.3v. This is the same voltage level that the Pi Zero uses, so they’re compatible. If you do this mod, I recommend you test your PowerOn line, just in case that it’s some exotic voltage like 1.8v or lower. It may still be possible to trigger this using a tristate GPIO pin, but not with the code below. Maybe a Tristate to GND and back to Tristate would work with other voltages.
This PDF file courtesy of SparkFun shows the pin-out. I’m using GPIO 21 (pin 40) for power, GPIO 20 (pin 38) for reset. I also connected the original power switch to pin 36+34 so that I can monitor the state of the power button. Through some monitoring software, the original power button can still function. More on that later.
Here’s the code I’m using to drive the GPIO pins, written in a simple Raspbian BASH script.
#!/bin/bash #source gpio export PATH=$PATH:/usr/bin POWERSW=16 POWER=21 RESET=20 gpio -g mode $POWER out gpio -g mode $POWERSW in gpio -g mode $POWERSW up gpio -g mode $RESET out gpio -g write $POWER 1 gpio -g write $RESET 1 while true; do D=`nc -l 0.0.0.0 12345` if [ "$D" == "p" ] then echo "Powering" gpio -g write $POWER 0 sleep 0.3 gpio -g write $POWER 1 fi if [ "$D" == "r" ] then echo "Reset" gpio -g write $RESET 0 sleep 0.3 gpio -g write $RESET 1 fi done
The script listens on port 12345 for either an ASCII ‘p’ or an ASCII ‘r’ representing power or reset respectively. Note that I could also do some other clever stuff like monitoring the power LED to check that the box came on, or remote sending the state of the HDD LED down a TCP connection. I didn’t in this case, but it’s trivial to add in.
The script uses the WiringPi package, so you’ll need to install this with:
sudo apt install -y wiringpi
The script sets up all the pins needed, two output to drive the power and reset lines and one input to monitor the power switch. To simplify the script, monitoring of the power switch is done in a separate script:
#!/bin/bash while true do R=`gpio -g read 16` if [ "$R" == "0" ] then echo -n "p" | nc -N localhost 12345 sleep 5 fi done
If it detects that the switch is pressed then it will send the “Power” command to the control port.
Both scripts are added to /etc/rc.local like this:
cd /tmp nohup /usr/local/bin/power & nohup /usr/local/bin/switch &
I don’t describe setting up the Pi Zero to prepare the Raspbian environment, but the Raspberry Pi Foundation has some great tutorials on that. So long as it boots and you can SSH into the Pi, the instructions above will get you the rest of the way.
So now, I can throw a ‘p’ or an ‘r’ at the Pi Zero on port 12345 and the Pi Zero will action the request. Yes, it’s not secure, and some idiot on my network can issue a reset while I’m in the middle of an important process, but for now it serves my purpose. I’ll look to set up some OpenSSL connections later.
The next logical extension to this is a PHP script callable from a web page, so that power can be turned on from anywhere on the internet. That would give the ultimate in remote access, all for $20 of parts and some time.
If you’re wondering what happened to the CPC2 project, then fear not, it’s still being worked on in the background. I’ve been struggling to get the caching SDRAM controller to work at speed and I’ve been sucked into the world of FPGA timing closure. Stay tuned for a write-up soon.