Shutdown your Raspberry Pi using a paper clip

paper-clip

When you’re running your Raspberry Pi headless, one of the first things you should concern yourself with is how to shut it down safely. Shutting it down by simply pulling the power out can result in a corrupt SD card or damaged files. If you had it connected to a network, you could of course just SSH into it and issue the ‘halt’ command. However, what if you couldn’t connect to it? Or what if you just wanted a way to simply and easily shut it down without touching a keyboard at all?

Here’s where Adafruit steps in and gives us a simple script that will monitor a GPIO pin and shut down if it detects a change in state. What use is that? Well, it means you just simply need to connect two pins on the GPIO together with a paper clip (or anything conductive) to issue the halt command. I’ve taken the Adafruit tutorial and some other guides online and put together the following instructions.

Please note: the current version of the software provided by Adafruit takes a second parameter – this is how long you need to “hold” the connection in order to trigger the shutdown. For consistency with Adafruit, I’ve made this “hold time” 3000 milliseconds (3 seconds).

Installation

First of all, you will need a Pi with Git installed on it.

sudo apt-get install git

Next, you download the script from Adafruit’s Github:

git clone https://github.com/adafruit/Adafruit-GPIO-Halt

If this doesn’t work, try:

git clone git://github.com/adafruit/Adafruit-GPIO-Halt

An aside: The script is written in C, so is able to be modified if you want to, say, light up an LED when the halt command is issued. You could re-write it as a Python program, of course, which might make it easier for some to adapt.

Change into the new directory, compile and install:

cd Adafruit-GPIO-Halt
make
sudo make install

This installs the script to /usr/local/bin/gpio-halt. You then need to run it as a service.

Please note

In the following sections, if you’re using an older Pi with a 26-pin GPIO header, use GPIO pin 7 instead of 21.

Run it automatically on Jessie/Buster

If you’re running Raspbian Jessie, you will need to do it via systemd:

sudo nano /lib/systemd/system/gpio-halt.service

This will create a file and open it. The following is the contents of that file:

[Unit]
Description=Short pins 21 and ground to shutdown the Pi
After=multi-user.target

[Service]
Type=idle
ExecStart=/usr/local/bin/gpio-halt 21 3000 &

[Install]
WantedBy=multi-user.target

Then, make the script executable by the right users:

sudo chmod 644 /lib/systemd/system/gpio-halt.service

Then, tell systemd to use the script:

sudo systemctl daemon-reload
sudo systemctl enable gpio-halt.service

And reboot your Pi

sudo reboot

When the Pi comes back up, you can check the status of the service by doing:

sudo systemctl status gpio-halt.service

Run it automatically on Wheezy

If you’re running the older Raspbian Wheezy, you will need to do it via rc.local:

sudo nano /etc/rc.local

Before ‘exit 0’, add the line:

/usr/local/bin/gpio-halt 21 3000 &

Now reboot your Pi:

sudo reboot

Now use it

Take a paper clip (or other conductive object) and touch the last two vertical GPIO pins at the same time and hold for at least 3 seconds. If you’re using a 26-pin Pi, it will be GND and GPIO7. If you’re using a 40-pin Pi, it will be GND and GPIO21. See the diagram below. The first time you do this, it might be worth having a monitor connected so that you can see it happening. Wait about 15 seconds for the halt procedure to complete and then unplug your Pi safely.

raspberry_pi_gpio-shutdown-pins

Acknowledgements

Thanks to Alex Eames for spotting the Adafruit shutdown script. Thanks to Adafruit, obviously. Thanks to Matt Hawkins for the systemd instructions. Thanks to commenter Bartwick for noticing that my instructions were out-of-date.

24 comments for “Shutdown your Raspberry Pi using a paper clip

  1. How do I know that it’s safe to turn the power off/remove power cable from Pi, after I use this turn off workaround (paperclip)? Should I look at the LEDs on the Pi?

    • If you wait 30 seconds, you’ll be safe. What should happen is that the green light flashes about 10 times and then stops. Then it’s safe to remove power.

  2. If I have a c-program running (XXX) what might I include to make sure this halt allows a proper shut down of (XXX), e.g. turning off a couple of PWM pulses in sequence before closing.

    My present scheme is to use a hidden command sequence in (XXX) and have it return 2 which the calling script interprets as a HALT otherwise it exits into Terminal.

    • I think what you need to do (to do it properly) is to merge your code and the shutdown code into one script and then detect the GPIO change and do the shutdown. That may not be what you meant.

  3. Not being a Linux expert, I looked up systemd on Wikipedia and found that there has been a great debate running on the unnecessary complexity of systemd compared with previous initialisation demons. Must look up how and why the Raspberry Pi foundation decided to use Jessie which uses systemd. Anyway thanks for showing us how something which should be supremely simple needs complex obscure code to implement – I would never have guessed this????

  4. The same “complex obscure code” runs on your PC and laptop when the on/off/sleep/hibernate button is pressed/released. Since RPi doesn’t include such a button ( it would make it much more expensive ) you need to add this type of functionality yourself. Like with everything RPi. That is what makes it so much fun!

  5. The following is a Python script to perform the same function. I have modified it so the button needs to he held for 1 second to halt to prevent spurious halts. NOTE that halting with poweroff causes the LED to flash 10 times indicating when it has run.
    #!/usr/bin/env python2.7
    #——————————————————————————-
    # Name: Shutdown Daemon
    #
    # Purpose: This program gets activated at the end of the boot process by
    # cron. (@ reboot sudo python /home/pi/shutdown_daemon.py)
    # It monitors a button press. If the user presses the button, we
    # Halt the Pi, by executing the poweroff command.
    #
    # The power to the Pi will then be cut when the Pi has reached the
    # poweroff state (Halt).
    # To activate a gpio pin with the poweroff state, the
    # /boot/config.txt file needs to have :
    # dtoverlay=gpio-poweroff,gpiopin=27
    #
    # Author: Paul Versteeg
    #
    # Created: 15-06-2015, revised on 18-12-2015
    # Copyright: (c) Paul 2015
    # https://www.raspberrypi.org/forums/viewtopic.php?p=864409#p864409
    #——————————————————————————-

    import RPi.GPIO as GPIO
    import subprocess
    import time

    GPIO.setmode(GPIO.BCM) # use GPIO numbering
    GPIO.setwarnings(False)

    # I use the following two GPIO pins because they are next to each other,
    # and I can use a two pin header to connect the switch logic to the Pi.
    # INT = 17 # GPIO-17 button interrupt to shutdown procedure
    # KILL = 27 # GPIO-27 /KILL : this pin is programmed in /boot/config.txt and cannot be used by any other program
    INT = 21 # GPIO button interrupt to shutdown procedure

    # use a weak pull_up to create a high
    GPIO.setup(INT, GPIO.IN, pull_up_down=GPIO.PUD_UP)

    def main():

    while True:
    # set an interrupt on a falling edge and wait for it to happen
    GPIO.wait_for_edge(INT, GPIO.FALLING)
    # print “button pressed”
    time.sleep(1) # Wait 1 second to check for spurious input
    if( GPIO.input(INT) == 0 ) :
    subprocess.call([‘poweroff’], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    if __name__ == ‘__main__’:
    main()

  6. Hi, I’m new to the Pi. The instructions all make sense to me apart from “This installs the script to /usr/local/bin/gpio-halt. You then need to run it as a service.” – How do I do so for the current verion of Raspian?
    thanks.

  7. Obviously, whats done here is a short circuit. Generally this is told to be dangerous for the pins or even the whole controller – why does this not matter here?!

  8. The ‘make install’ command installs the executable in “/usr/local/sbin/gpio-halt”, not “/usr/local/bin/gpio-halt”.

    • That’s odd… must be something OS related that causes it to go to the wrong place as this used to work as is.

  9. Very nice. Thanks.
    The code has changed slightly so this is a bit out of date. Hopefully Michael will update this page as I suspect it still gets significant traffic.
    But until then, after installing with the command “sudo make install”, follow the directions on github at https://github.com/adafruit/Adafruit-GPIO-Halt/tree/master
    On github they seem to have left out the command,
    sudo chmod +x /etc/systemd/system/gpio-halt.service
    This is necessary to enable systemctl to run the program at startup.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.