Building a simple safe power shutoff switch for Raspberry Pi.
Anyone who has worked with Raspberry Pi know that cutting the power while the Pi is writing to the SD card can corruption of the card. You can easily find a few articles about how to recover and how to prevent it. But the answer pretty simple, tell the device to undergo a controlled shutdown before pulling the plug.
sudo shutdown -h now
The shutdown results in the OS send a SIGTERM
to all running processes. Which is the signal to save data and exit. The OS then sends SIGKILL
to all remaining processes and unmount the filesystems.
But this does does not remove power from the Pi. And if you are running on batteries the Pi will continue to use power.
In my application, which will run inside a vehicle, this will result in draining my car battery over time. This is a problem, especially if the car sits for a few days..
Ideally I would like to disconnect the power going the the Pi when it completes the shutdown process.
Fortunately modern Raspberry Pies have an overlay feature called gpio-poweroff that can drive a GPIO line when the shutdown is complete. You can even specify which GPIO line is used and whether the signal is active high or low.
Name: gpio-poweroff
Info: Drives a GPIO high or low on poweroff (including halt)
Load: dtoverlay=gpio-poweroff,=
Params: gpiopin GPIO for signalling (default 26)
To enable this feature (in my case, I chose GPIO-16), edit the /boot/config.txt
file to include the following line.
dtoverlay=gpio-poweroff,gpiopin=16
This will cause the Raspberry PI so set the GPIO-16 high (3.3v) when the shutdown process is complete. But how does that help us? We need a way to use this signal to actually remove power. We need to add some form of relay that disconnects the power using this signal.
Relay, things are brewin'
(seriously Vinnie.. no-one remembers this song)
Searching the web, I came across a few shutdown circuits, one of my favorites is by Don at Novaspirit Tech. He uses a pair of relays and even includes a startup delay with an ESP. What he sends up with a a form of latching relay. But this was a bt more complicated than I wanted I’d like to avoid energizing the relay for an extended period of time.
Rather than hooking up something to the ignition switch I also wanted to leave it up to my application on the Raspberry Pi to decide when to shutdown the power.
The solution presented itself as an artifact from an automotive projects I worked on a number of years back. Some of the older diesel Mercedes an BWM employed a latching relay to activate the glow plugs. In particular the Hella Glow Plug Relay/Controller | 0025428119, a highly reliable bi-stable relay than can set or reset from an electrical signal.
They are not too expensive, if you know where to look. I was able to find one at Rock Auto or better yet Summit Racing for less than $30. They are very easy to use. Referring to the diagram above. There is a SPST switch on pins 3 and 5 that we can run our Raspberry Pi power through. The coil common is on pin 6, so we can apply + 12v from the battery there. We can momentarily ground the pin 1 (SET) to close the switch and turn the Raspberry Pi on. To open the switch, and disconnect the power we would momentarily ground pin 2 (RESET).
But of course, Darling-ton
This seems like a simple fit we connect pin 2 of the relay to the GPIO pin controlled by the gpio-poweroff function. But since the relay coil is an inductive 12v load, we need to put something in-between the two. The Raspberry Pi GPIO can not handle the load or voltage. A simple solution is to use a set of transistors in a Darlington configuration. The ULN2803A chip is a perfect fit for this application. It’s an array of 8 of these NPN Darlington pairs wired up common cathode and includes the clamping diodes for driving relays.
The ULN2803A is inexpensive, Mouser has them for less than $2. Someone was even industrious enough to mount it on a PCB to make prototyping easy.
The way we use this circuit is to connect the emitters (E) to ground, the GPIO signal to the input and the relay RESET signal to the output. We also connect the COM to same circuit as the relay coil pin 6. This allows the clamping diode to handle any inductive reverse voltages emanating from the relay coil.
To turn the Raspberry Pi on, we will wire another of the ULN2803A transistors output to the relay pin 1 (SET) signal. For now let’s just wire a momentary contact SPST switch to the ULN2803A and +12v. This will allow us to manually turn the Pi on.
I plan to automate this later using an ATmega32U4. This chip can run in lower power mode with minimal car battery drain. I will wire it to turn the Raspberry pi power on when it detects CAN bus activity. In retrospect I could probably do it with a 555. We shall see.
The final circuit looks like this.
Reliable power
Since this was an automotive project I need to employ a 12v to 5v DC/DC converter to supply the power for the Raspberry Pi. I have had some luck with the Daygreen B05-1224-05, It can handle about 5A, easily more than enough for my application. Last I checked you can get them from Daygreen for about $7.
Manual shutdown
Since this is a prototype circuit, I am also going to add a manual shutdown switch. We can do by wiring a line from one of the GPIO pins through a SPST switch to ground. Similar to what we did above for power off, we use the gpio-shutdown
overlay by adding the following line to the /boot/config.txt
file.
dtoverlay=gpio-shutdown,gpio_pin=17
Then when we ground that pin (in our case GPIO 17) the Raspberry Pi OS will initiate the shutdown process and consequently disconnect the power going to the Pi when it is complete.
So that’s it. We now have a reliable power supply and shutdown circuit for the Raspberry Pi that is applicable for automotive use.