loading...
Cover image for Build a safe way to shutdown a headless raspberry pi with a tiny button.

Build a safe way to shutdown a headless raspberry pi with a tiny button.

stephaniecodes profile image Stephanie ・3 min read

When you work with a hardware project using the raspberry pi, it is important to always shut down the pi gracefully to prevent the pi's SD card from data corruption.

In my latest project, I am using a RPI 3B+ in a wearable that is attached to my body. In order to safely shut it down without having to SSH to it from my laptop, I created this little button that plugs into the GPIO header that can trigger a safe and graceful shutdown of the Pi when it's time to turn it off.

raspberry pi with shutdown button attached

1. Make the button:

  • Cut a female-female jumper cable in half.
  • Strip the ends and solder each to one pin on one side of the button.
  • Clip off the pins on the other side of the button.
  • Plug ends into 1 ground and 1 GPIO pin on your pi. I used GPIO #12 & the ground next to it.

My soldered button:
Soldered button

Attached to the Pi:
button attached to GPIO 12 and a ground on the pi

2. Write a program for the button:

Thanks to Alex Glow's article on creating a similar button, I was able to use the script mentioned and modified it for my pi.

(I created this program by typing touch shutdown_pi.py, then opening the file: sudo nano shutdown_pi.py and pasting the following code and saving it (CTRL+X).

#!/bin/python 
# Simple script for shutting down the raspberry Pi at the press of a button. 
# by Inderpreet Singh 

import RPi.GPIO as GPIO  
import time  
import os

# Use the Broadcom SOC Pin numbers 
# Setup the Pin with Internal pullups enabled and PIN in reading mode. 
GPIO.setmode(GPIO.BCM)  
GPIO.setup(12, GPIO.IN, pull_up_down = GPIO.PUD_UP)

# Our function on what to do when the button is pressed 
def Shutdown(channel):  
   os.system("sudo shutdown -h now")  

# Add our function to execute when the button pressed event happens 
GPIO.add_event_detect(12, GPIO.FALLING, callback = Shutdown, bouncetime = 2000)  

# Now wait! 
while 1:  
   time.sleep(1)

3. Create a cronjob:

We want this program to run on boot and run in the background
so that when the button is pressed, the program will trigger
the shutdown script to run. You can trigger programs to run at boot
a few diff ways on the pi, but I already use cronjobs, so I edited that file.

  • Run crontab -e (if it's your first time, I'd choose option 2 and use nano to edit the file).
  • At bottom of the file, add @reboot python /home/pi/shutdown_pi.py & (Tip: the & at the end tells the pi to run the program in the background)
  • Press CTRL+X to save & exit.

4. Test it!

  • Run sudo shutdown -r now to reboot the pi.
  • Press the button after it reboots and it should safely shutdown the pi now! 🎉

UPDATE (4-Aug-2019):

I wasn't aware at the time I built this, but there is a potentially easier solution!

Solder the button, but plug it into GPIO #3 (I2C-SCL) and ground (pins 5 & 6). Add the line dtoverlay=gpio-shutdown,gpio_pin=3 to the /boot/config.txt file and reboot. Should allow for booting AND shutdown.

In my experience, only the booting was working, not the shutdown, so I stuck with the cronjob above! ✌️

Posted on by:

stephaniecodes profile

Stephanie

@stephaniecodes

web dev. she/her js, react, a11y, fashion, arduinos, LEDs & ML. I create dev comics @ https://twitter.com/lolsobjs

Discussion

pic
Editor guide
 

this is a great tutorial! It was latenight and I wasn't going to be able to get the supplies, mainly the button! Since my headless project wasn't dependent on the USB ports, I used lsusb in python to detect (changes) in the number of devices plugged in to trigger a shutdown script. I'm new here, so will post the code once I have a moment. Once the buttons arrive in the mail, gonna give this a try. So grateful to this example to get me in the pattern! Thanks!

 

This is a great example. Thanks for sharing.