Below shows how I added a physical power switch to Raspberry Pi. It enables boot up, shutdown, and reboot Raspberry Pi board.
Note: This switch does not actually power-up or power-down, and Raspberry Pi board consumes some mA of current even after shutdown (i.e. halt state). To control actual power, additional circuit such as this is required.
Tested with
- Raspberry Pi Zero W running Raspbian Stretch November 2017 version.
- Raspberry Pi 4B running Raspberry Pi OS (32-bit) with desktop (2020-08-20)
Prerequisites
– Raspberry Pi board (e.g. Raspberry Pi Zero W, Raspberry Pi 4B) running Raspberry Pi OS
– Normally-Open Switch such as this
– Jumper wires
Steps
1. Wiring
1-1. Solder jumper wires with the switch.
1-2. Connect the wires with GPIO pin 5 & 6. Please refer this site for Raspberry Pi’s GPIO pinout.
Momentarily shorting pin 5 and 6 makes Raspberry Pi booting up from halt state [1]. Also, pin 5 will be used for detecting shutdown and reboot signals from the switch.
2. Test wiring
2-1. First, supply power to Raspberry Pi and boot it up.
2-2. Then, shut it down. After the activity LED (green LED) goes off, Raspberry Pi is in halt state.
sudo shutdown -h now
2-3. Push the switch to test. Raspberry Pi should boot up. If not, check the continuity of the switch with multimeter.
3. Script for shutdown and reboot
3-1. Create a python script file of any name or location.
sudo nano /usr/local/bin/power-switch.py
3-2. Write a code to detect shutdown and reboot signal.
import threading, subprocess import RPi.GPIO as GPIO if __name__ == '__main__': try: GPIO.setmode(GPIO.BOARD) GPIO.setup(5, GPIO.IN) GPIO.wait_for_edge(5, GPIO.RISING) pin = GPIO.wait_for_edge(5, GPIO.FALLING, timeout=3000) if pin is None: subprocess.call('sudo shutdown -h now', shell=True) else: subprocess.call('sudo reboot', shell=True) finally: GPIO.cleanup()
Pushing and holding the switch more than 3 seconds makes Raspberry Pi shutdown, and pushing the switch less than 3 seconds makes it reboot.
4. Enable script at boot
4-1. Open /etc/rc.local.
sudo nano /etc/rc.local
4-2. Add a line above “exit 0” to execute the script at boot.
python /usr/local/bin/power-switch.py &
4-3. Reboot.
sudo reboot
5. Verify
5-1. Verify reboot by pushing the switch less than 3 seconds when Raspberry Pi is running.
5-2. Verify shutdown by pushing and hold the switch more than 3 seconds when Raspberry Pi is running.
5-3. Verify booting up by pushing the switch when Raspberry Pi is in halt state.
References
[1] Wake from Halt
[3] How to add a power button to your Raspberry Pi
Hi,
In my case, I am using an RTC and I have pins 3 and 5 busy.
I tried to change pin 5 on the program in pin 7, but it does not work.
Can the program work with another pin other than 5?
Thanks and regards.
Hi Miguel,
If you use other GPIO pin, I don’t think you can boot up Raspberry Pi using the pin. (rebooting and shutting down should work). Another option is to use Reset pin (see this post) but in that case you cannot reboot or shutdown…
Does anyone know what 4-2. Add a line above “exit 0” to execute the script at boot. means? I do not see any “exit 0”?????????????
scroll down
brooooooooooo im stuck on this, i setup my own debian image for a 3b+ with the retroflag nespi+ case but the only shutdown i find are for emulation station and they dont work on my image. what do i have to modify so your script functions with my case in any situation and iniate a safe shutdown?
the gpio for my case:
# NESPI+ CASE
# http://www.retroflag.com
# Defaults are:
# ResetSwitch GPIO 2 (I2C, SDA), input, set pullup resistor!
# PowerSwitch GPIO 3 (I2C, SCL), input, set pullup resistor!
# PowerOnControl GPIO 4 (BCM 4), output, high, fan control!
# LEDiodeControl GPIO 14 (BCM 14,TxD ), output, high, low (flash LED)
# You will loose I2C function due connections using SDA und SCL
# Enter other BCM-connections to change behaviour
Hi nebu, I’ve never used the case or other OS than Raspbian on Raspberry Pi. I’m sorry I can’t help with this…
Debian no longer uses rc.local. You can either create a systemD service for the python script or create a service called rc.local https://www.linuxbabe.com/linux-server/how-to-enable-etcrc-local-with-systemd
Got it up and running – thanks
Hello, what about using a processor? htop shows 100% usage for this process.
Thank you Jack for pointing it out. Right, busy waiting was a bad idea… I updated the script without using busy waiting.
Hi
I have a 3.5 inch LCD screen installed from pin 1-26. SO that means i cannot use pin 5 and 6.
Is there some way i can reprogram or change the pins to some other location.
Hi AJ,
Sorry but I can’t think of any perfect solutions. Please see my response to Miguel above.
Thanks for your comprehensible howto. I got switch on and shutdown working, but the time delay is ignored completely. Just one press onto the (momentary) switch, and the RPI is shutdown. How is this possible?
The same for me! I use a RPi Zero W with latest rasbian OS.
Also, after some days, shutdown isn’t working anymore as expected: even though it shuts down, the power LED is still on.
Hi Adam,
The power LED (red LED) should be on after shutdown as long as power is supplied.
hmm, doesn’t work for me.
Cancel that…indentation matters apparently 😀
I plan to use this headless on a RPi0W where I boot the RPi0W and use as a file server. Do you need to remove requirement for admin password to execrate sudo command so that script will execute correctly?
Hello
I installed correct, but it’s only reboot himself, i can’t shut it down. wat do i wrong?
I did this, and it was working great, but then I was having some undervolt problems with it being powered off my desktop, so i had to disconnect power to switch power adapters and now every time it boots it automatically reboots before i can get to any prompt (booting to terminal) to be able to stop it.
Any advice?
Hi, I am using your script with mi RPi 4.
The Problem is that it does not matter how long / short I press the power button. The RPi is always shutting down.