Hey! This is obsolete. There are better solutions out there now. You should use the system-supplied and supported gpio-shutdown option instead.
A very simple systemd service for Raspberry Pi that provides a software-controlled restart / shutdown button. Code: scruss/shutdown_button
Default behaviour is:
- your Raspberry Pi will reset if the button is held for more than two seconds but fewer than five seconds;
- your Raspberry Pi will shut down if the button is held for more than five seconds.
By default, the software assumes the switch is connected to pin BCM 27. Both the pin and the timing can be changed in the Python source file.
- A Raspberry Pi (tested on a model 2B, 3B and Zero, and on a model B after minor software modification)
- A normally open, momentary contact button. I use surplus ATX power buttons (as used on desktop PCs), as they’re cheap and come with a handy set of wires and header connectors. Virtually any button will do the job, though. Just make sure it’s normally open (push to close).
- A Debian-based operating system that uses systemd (tested on Raspbian Jessie and Stretch)
python3-gpiozeropackage to provide GPIO Zero (tested on version 1.4.0)
40-pin GPIO connector (B+, 2B, 3B, Zero)
Connect the button between GPIO 27 and GND. If you use an ATX power button and a Raspberry Pi with a 40-pin GPIO header, connect it across the seventh column from the left:
- Â· Â· Â· Â· Â· Â·|Â·|Â· Â· Â· Â· Â· Â· Â· Â· Â· Â· Â· Â· Â· Â· Â· Â· Â· Â· Â·|Â·|Â· Â· Â· Â· Â· Â· Â· Â· Â· Â· Â· Â· Â· -
This shorts GPIO 27 (physical pin 13) to ground (physical pin 14) when the button is pressed.
26-pin GPIO connector (models B and A only)
GPIO 27 is not exposed on the original Raspberry Pi header, so GPIO 17 is a reasonable option. If you use an ATX power button and a Raspberry Pi with a 26-pin GPIO header, connect it across the fifth and sixth columns of the second row:
. . . . ._. . . . . . . . . . . .|. .|. . . . . . . -
You will also need to change line 7 of shutdown_button.py to read:
Download the software first. I prefer to use
git clone https://github.com/scruss/shutdown_button.git
but you can download the zip file. If you do that, though, make sure to
unzip shutdown_button-master cd shutdown_button-master
The software is installed with the following commands:
sudo apt install python3-gpiozero sudo mkdir -p /usr/local/bin chmod +x shutdown_button.py sudo cp shutdown_button.py /usr/local/bin sudo cp shutdown_button.service /etc/systemd/system sudo systemctl enable shutdown_button.service sudo systemctl start shutdown_button.service
Enabling the service should produce output very similar to:
Created symlink /etc/systemd/system/multi-user.target.wants/shutdown_button.service â†’ /etc/systemd/system/shutdown_button.service.
You can check the status of the program at any time with the command:
systemctl status shutdown_button.service
This should produce output similar to:
â— shutdown_button.service - GPIO shutdown button Loaded: loaded (/etc/systemd/system/shutdown_button.service; enabled; vendor Active: active (running) since Sat 2017-10-21 11:20:56 EDT; 27s ago Main PID: 3157 (python3) CGroup: /system.slice/shutdown_button.service â””â”€3157 /usr/bin/python3 /usr/local/bin/shutdown_button.py Oct 21 11:20:56 naan systemd: Started GPIO shutdown button.
If you’re seeing anything other than Active: active (running), it’s not working. Does the Python script have the right permissions? Is it in the right place? If you modified the script, did you check it for syntax errors?
The output from
dmesg will show you any error messages generated by the service.
If you use a HAT/pHAT/Bonnet/etc. with your Raspberry Pi, check pinout.xyz to see if it uses BCM 27. If you do need to change the pin, best to pick one that doesn’t have a useful system service like serial I/O or SPI. If you’re using an ATX button with a two pin connector, make sure you choose a pin physically adjacent to a ground pin.
If you modify the timing, please ensure that you keep the shutdown button press duration longer than the reboot one. Otherwise you’ll only be able to shut down.
You should not need to reboot to enable the service. One machine of mine â€” a Raspberry Pi Zero running Raspbian Stretch â€” did need a reboot before the button worked.
The reboot code is based on the Shutdown button example from the GPIO Zero documentation.
This is not the only combined shutdown/reset button project to use GPIO Zero. gilyes/pi-shutdown also does so, but pre-dates the implementation of the various hold time functions in GPIO Zero.
GPIO 27 was used, as it’s broken out onto a physical button on the Adafruit PiTFT+ display I own.
This is my first systemd service, and I’m still at the â€œamazed it works at allâ€ stage. The service file may not contain the ideal configuration.
From GPIO Zero’s
3V3 (1) (2) 5V GPIO2 (3) (4) 5V GPIO3 (5) (6) GND GPIO4 (7) (8) GPIO14 GND (9) (10) GPIO15 GPIO17 (11) (12) GPIO18 GPIO27 (13) (14) GND GPIO22 (15) (16) GPIO23 3V3 (17) (18) GPIO24 GPIO10 (19) (20) GND GPIO9 (21) (22) GPIO25 GPIO11 (23) (24) GPIO8 GND (25) (26) GPIO7 GPIO0 (27) (28) GPIO1 GPIO5 (29) (30) GND GPIO6 (31) (32) GPIO12 GPIO13 (33) (34) GND GPIO19 (35) (36) GPIO16 GPIO26 (37) (38) GPIO20 GND (39) (40) GPIO21
3V3 (1) (2) 5V GPIO0 (3) (4) 5V GPIO1 (5) (6) GND GPIO4 (7) (8) GPIO14 GND (9) (10) GPIO15 GPIO17 (11) (12) GPIO18 GPIO21 (13) (14) GND GPIO22 (15) (16) GPIO23 3V3 (17) (18) GPIO24 GPIO10 (19) (20) GND GPIO9 (21) (22) GPIO25 GPIO11 (23) (24) GPIO8 GND (25) (26) GPIO7
Can I use this with hat on like hifiberry already on?
Yes, you should be able to, but you might have to solder the button connector on.
According to GPIO usage of HiFiBerry boards â€“ HiFiBerry, the pins I chose aren’t used by any of the HiFiBerry boards. You might want to check with them. I will, too: I work for one of their distributors.
Someone on reddit noted that shutdown is already available as an overlay if you short BCM 3 to GND.
BCM 3 (pin 5) is the IÂ²C clock, which a lot of people might have other uses for. I deliberately avoided the â€œbig nameâ€ pins.
GPIO 11 might also be a useful pin to use if you use a IoT pHAT for Raspberry Pi – Product
Iâ€™ve wondered about getting the pi running again with these systems. Do you have to pull and reinsert power?
Yes, AFAIK. I think you’d need an additional button on the RUN header to avoid that
Wow, i was searching that kind of code since week or more…
Its briliant! GpioZero also work on RaPi3B+
You need to install it and your go!
Nice job! I’m going to use this.
OK, just so i am clear.
I run the commands listed in the ‘Software’ section above and that is all the command line stuff that needs to be done.
I then connect a momentary switch across the correct pains, dependant on model.
that will then give me a button that does either
or Sudo reboot
depending on how long I press the button
I just want a way to shut down correctly a headless system (while I am in the crawl space in my attic where the Pi is located) without having to SSH in to it to shut it down before I pull the power plug.
sudo apt install python3-gpiozero
sudo mkdir -p /usr/local/bin
chmod +x shutdown_button.py
sudo cp shutdown_button.py /usr/local/bin
sudo cp shutdown_button.service /etc/systemd/system
sudo systemctl enable shutdown_button.service
sudo systemctl start shutdown_button.service
then connect button to correct GPIO pins
Yes, basically. Don’t forget to download the software too.
I usually make GPIO connections with the power off. You might get away with being less careful.
Is this power and restart button safe in terms of “Datacorruption”?
It uses the poweroff and reboot commands, so will shut everything down in an orderly manner. It doesn’t interrupt power or use any other restart signal. It should be relatively safe as long as it’s wired correctly and you don’t accidentally do something bad with the power connection while using it.
Something has changed?
Command -> chmod +x shutdown_button.py
gives error no such file or directory
so got stuck
Rasp 3 b+ with a DAC hat and volumio
Did you download and extract the software? chmod will work if the file exists.
After shutdown how I power on again?? Can I press the button again to power on?
Unfortunately not. You need to unplug and plug the power back in. I think you may be able to force restart by bringing RUN to ground, but I’m not sure about that.
Works great on RPI 3B+. Yes, to restart need to unplug and replug. Must short out via button for 5 seconds or more. Not ‘instantaneous’ 🙂
Unfortunately I have a problem!
When I launch “sudo systemctl enable shutdown_button.service” obtain:
Failed to enable unit: File shutdown_button.service: Invalid argument
If I check the status with “systemctl status shutdown_button.service” obtain:
Loaded: error (Reason: Invalid argument)
Active: inactive (dead)
Can you help me?
did you download the files and put them in their right places?
Scruss, many thanks for the brilliant example and sources. all works fine and I will be using it in my project.
One question though, is it safe to short GPIO and ground directly, no additional safety needed?
Yes, it is.
Thanks for the tutorial, I have successfully implemented it in a Rpi 3B .
My question is if it is possible to implement the ON button since I can not turn it on (only off and reset)
With the hardware the way it stands, you can’t. You’d need another momentary button to ground the RUN terminal to get the Raspberry Pi to restart. You’d have to be very careful not to touch that button unless your Raspberry Pi was in the shutdown state, as it causes an immediate catastrophic reset that would corrupt the SD card.
thanks for the great script, works perfectly!
Is there a way to add a 3rd option?
I would like to add something like this:
if (held_for> 1.0):
check_call ([‘sudo’, ‘openvpn’, ‘- cd / etc / openvpn –config openvpn.conf’])
But that does not work – unfortunately I can not see why.
Does somebody has any idea?
Thanks a lot!
1. get rid of sudo: this is running as the system user anyway
2. I don’t know anything about openvpn, but that command line looks wrong: is it ‘-cd’? There’s a space in there that doesn’t make much sense
You’re going to have to change the times a bit, since your option only gives you a 1 s window to run your command or reboot. I don’t think I can help you here as I’ve no idea about (or interest) in openvpn.
Thank for the code, great!
Now i’m trying to add a new function to it, with this modified code:
It works, but after the execution of script.sh I cannot reboot or poweroff anymore the Raspberry with the button.
I’m not a Python programmer, so how to modify your script to make it works repeatedly and not just once?
Thank in advance,
I’m not much of a Python programmer either, but on the line just above check_call([â€˜/usr/local/bin/script.shâ€™]), try:
The poweroff and reboot clauses don’t really care what happens to the value of held_for, but I think it stays â‰¥ 9 after your script is called.
A possible way of testing it is after you’ve done the 10 second hold to run your script and you’re sure it’s done its thing, try holding the button for just one second. This should hit the else clause and reset the timer, so reboot and poweroff should be able to work.
it works! Thanks again,
Installed on Raspberry pi 4, running Buster Linux rp4 5.4.51-v7l+. Working as described. Thank you for your good work.
PS. Proposed minor addition in the installation instructions near Software at “chmod +x shutdown_button.py”. It was to me not clear that the downloaded software had to be unzipped and I had to cd to the map with the file shutdown_button.py before executing the chmod command.
Thanks! I guess I’d been downloading via git, so didn’t think about the zip file. Don’t you always have to unzip files anyway?
Where do you put the files after you unzip them?
After the “chmod +x shutdown_button.py” command it says: “cannot access, no such file”
like I said previously, I usually use git pull. However, if you download the zip file, do this:
Please tell me where the files should go? The zip file ends up in my ‘Downloads’ folder, and when I go to extract it, I am asked where to put the files. They don’t seem to work anywhere I have tried.
I tell you exactly how to download the files and where to put them here:
In the service file you’ve got After=network.target
Is this needed? Is the network required for the GPIO buttons for some reason?
Not really. It could start at any time. I just put it after network so that more important things could start first.
You should probably not be using this. The system service is better.)
Comments are closed.