How to Make a Safe Shutdown Button for Raspberry Pi

Clinton just shared a new tutorial: "How to Make a Safe Shutdown Button for Raspberry Pi"

Pulling the power to your Raspberry Pi can cause image corruptions & other issues that can damage your Pi! In this article, we will create a small push button that will work as a ‘Safe-Shutdown’ option. We’ll connect it to our R…

Read more

Hey @Clinton

This is an awesome idea, especially since I’ve been thiking for sometime about getting one of these bad boys - NesPi Case for my RetroPie.

Quick (and probably dumb) question, will this also work to turn the RasPi back on again if it powered down???


Hey Shane,
No this won’t but if you wire the button to GPIO3 and add
to /boot/config.txt it will give you a safe shutdown and start up again.

You can find out more about it in the overlay readme search for shutdown and you will find it.
@Josh Told me about this just after I finished writing the tutorial.

Hey Clinton,

Thanks for replying so soon.

That all sounds like a great overall solution for the whole safe shutdown / power / power off questions in my head.

That was about my only reservation with purchasing the NesPi case. I think now you’ve talked me into it.


I am running an OpenCV tracker on my Pi, and now want to operate it with just a switch and the minimum number of buttons as follows:
Toggle switch to power on the Pi
Press button 1 to run (or re-run) OpenCV tracker program
Press button 2 to shut down safely (per your tutorial)

How would I edit your safe shutdown script to allow for another button to also run my tracker from startup?

Hi Richard,

Check out these discussions about how to start a program from a pushbutton:

A toggle switch to power the Pi would require no code, just a physical switch inline with the power:

See chapter 3.5 of the Raspberry Pi Tutorial for information on starting a program from startup.

Hi Richard

You can define more buttons by assigning them to free GPIO pins with this command
myButton = Button(8) # defines the button as an object and chooses GPIO 8
and anything you place inside the if statement will run, the os.system will run any terminal command you put in it.

Hi Clinton, thanks for your interest in my project. I had tried adding another button to your tutorial script as follows:
Above the line stopButton = Button(26) I inserted runButton = Button(21)

And then immediately under the line while True: I inserted

if runButton.is_pressed: 


    if runButton.is_pressed: 

        os.system("python3 /home/pi/")

When I ran this edited button script with a terminal command, the runButton runs my Picam tracking script at the first press only, but won’t re-run the tracking script again at a second press (if say the tracker looses its target). I have to use the shutdown button and then reboot the Pi to re-run the tracking script. Do you think I could improve either the button script or tracking script to be able to re-start the tracking script without re-booting the Pi or adding another button? I am hoping to run this improved button script at startup using rc.local so my tracker bot can be set free.

My guess is that the Python script is waiting for the Terminal operation to finish running before continuing.
Try running it with an “&” character at the end of the line to suppress the output and it may work,
os.system("python3 /home/pi/")

Thanks Clinton, I tried your “&” suggestion, which caused my Pi to freeze, and a black screen on reboot. Maybe I made a mistake with execution, but I think I should reinstall my card, hopefully find another solution, such as a third button to stop the tracker script so it can be re-started when it loses the target.

Sorry about that, I forgot that Playing with that script can be dangerous.
Another thing that might help is CRON it can be setup to run a process every few minutes.

Hi Richard,

It could be that your Pi is unable to run multiple instances of that program at once. Perhaps include a bit in your script that closes any already running instances before starting a new one.

I am using the script from your tutorial “How to Make a Safe Shutdown Button for Raspberry Pi”. My project is powered by 2 Lipo 18650 batteries via an Adafruit PowerBoost 1000C regulator, and I’d like an automatic shut down when the low battery LED flashes.
The Adafruit regulator specs state: " LBO - not a leveraged buy out! this is the Low Battery Output . By default it is pulled high to BAT but when the charger detects a low voltage (under 3.2V) the pin will drop down to 0V. You can use this to signal when its time to shut down or alert the user that the battery is low. There is also a red LED connected to this pin." Could you please explain how to use the output from LBO pin to shut down my Pi, and whether this output could be connected to the same GPIO 26 when pressing the stopButton.

@Clinton didn’t put a space (required) before the “&” so the process wouldn’t have gone into the background. Not that it matters as os.system waits for the process to finish.

Instead of os.system, use subprocess

import subprocess

subprocess.Popen("nohup python3 /home/pi/ >&/dev/null &", shell=True)

This doesn’t wait for subprocess to finish before continuing.

“nohup” prevents the subprocess dying when the parent process ends, or the controlling terminal closes.

The >&/dev/null redirects stdout and stderr to the bin basically. If you want to capture the output, substitute the name of your log file.

The final & puts the subprocess into background.

@Clinton, I noticed at the top you mention you could add the button at GPIO 3 and then add dtoverlay=gpio-shutdownto /boot/config.txt it will give you a safe shutdown and start up again. My question is, do I need to remove the other script I added from the tutorial and then only make this change to config.txt?
Thanks for your help.

The script from the tutorial will be a bit redundant with the pin three activated so it is probably best to remove it.

I realise this is super old now, but wanted to note for anyone coming along to use the code: on a Pi 4 I had to fix the first line as so:

from gpiozero import Button #import button from the Pi GPIO library

and also add # -*- coding: utf-8 -*- at the top of the code to get it to work. YMMV.

1 Like