Why didn’t anyone make a cheap alternative available yet?
From the very beginning it was clear to me that, in order to prevent memory errors (yes this is a real danger and not an urban legend) an unexpected power loss should not occur. I have experienced filesystem corruptions on one of my Raspberry Pis before. Here’s a hint, why this could happen.
After giving up the idea of a UPS built from a simple circuit using super-capacitors, I was looking for an alternative. The requirement was still the same: When the user or the system itself instructs a shutdown, a software procedure should take care of gracefully halting the device and eventually disconnecting the power. Afterwards, no (leakage) current should be flowing from the battery into the device.
Being confident, that many people had similar issues and requirements and I would find a plethora of super cheap solutions to choose from, I was disenchanted pretty fast. Maybe I haven’t looked enough or there are really no boards available for cheap money. Eventually I went with the OnOff SHIM from Pimoroni. Its main disadvantage is the IMHO high price of 7€ per unit. Besides that, it is a very good product and fits perfectly into the project.
The device is able to pass through a power supply as soon as a built-in button (or optionally an external one connected to two pins called ‘BTN’) is pushed. When the system is running, that very button pulls down an output pin of the board (called ‘Status’ which I renamed to ‘Trigger’). The value will be read and used as an indicator to power off the system. At that point you are able to save the program state and gracefuly shutdown the operating system. The last thing to do for the microcontroller is to pull down an input pin of the OnOff SHIM (‘Power off’ or ‘Cut_Power). That will disconnect the power source completely. Using this pin actually has the benefit of being able to also cut power without any user interaction at all (e.g. a timeout triggered system halt). The OnOff SHIM is especially designed for the Raspberry Pi noticeable by its form factor, but can be used with more or less any microcontroller.
I connected all necessary pins in the same way they would be aligned when using the board on your Pi directly (i.e. GPIO 4 → Cut_Power, GPIO 17 → Trigger). This decision allows us to use the instructions without altering the pins and use available scripts without editing them.
Do not follow the installation instructions on Pimoroni’s GitHub for setting up the OnOff SHIM. I won’t even link it here to avoid any misunderstandings. Also, do not run the one-line-installer referenced in the product description. It would install a shell script which reads the ‘Trigger’ pin and then immediately shuts down the system.
We wanna rather read the pin ourselves and probably evaluate a few side conditions and only then initiate a system halt.
When the OS is going to shut down, the last thing we want to do is pull down GPIO pin 4 and thus tell the OnOff SHIM to cut the power supply. For that very purpose, the systemd service offers a special directory: /lib/systemd/system-shutdown. All executables within that folder will run just before the operating system is going to power off, reboot, halt or boot into another kernel. The OS provides an argument indicating which action will take place (poweroff, reboot, halt, kexec).
That’s exactly where we are adding a shell script that uses the kernel’s sys virtual file system to pull down GPIO pin 4 and thus cut power.
pi@raspberrypi $ sudo nano /lib/systemd/system-shutdown/gpio_poweroff #! /bin/sh case "$1" in poweroff) /bin/echo 4 > /sys/class/gpio/export /bin/echo out > /sys/class/gpio/gpio4/direction /bin/echo 0 > /sys/class/gpio/gpio4/value /bin/sleep 0.5 ;; esac pi@raspberrypi $ sudo chmod u+x /lib/systemd/system-shutdown/gpio_poweroff
Now, as soon as you stop the system (e.g. sudo shutdown now), the power source will be disconnected and you can startup the whole setup again via the OnOff SHIM button.