Because of their low price, mini button switches are useful for many purposes. We have already analyzed how they work (ref. Using mini Switch Button with Raspberry PI and Python) and a funny use case (ref. Reaction Game (v2) with Raspberry PI and Mini Button Switch).
One more way to use these buttons allows people to solve a practical need: shutting down their Raspberry PI.
You know that powering off a RPI requires being logged in and following procedure:
- for headless setups (Raspberry PI OS Lite) typing “sudo shutdown -h” command
- for desktop setups (Raspberry PI OS Desktop), going to main menù -> Shutdown -> Shutdown
In this tutorial I’m going to show you how to create a physical shutdown button for Raspberry PI.
I’ll use a Raspberry PI Zero W, but this tutorial applies to all Raspberry PI boards.
What We Need
As usual, I suggest adding from now to your favourite ecommerce shopping chart all needed hardware, so that at the end you will be able to evaluate overall costs and decide if continuing with the project or removing them from shopping chart. So, hardware will be only:
- Raspberry PI Zero W (including proper power supply or using a smartphone micro usb charger with at least 3A) or newer Raspberry PI Board
- high speed micro SD card (at least 16 GB, at least class 10)
- Dupont Wiring
- Solderless breadboard
- Mini button switch
You can also evaluate the useful Elegoo kit, including electronic components (excluding Raspberry PI and it accessories) plus many other useful sensors.
Check hardware prices with following links:
This wiring diagra is really simple to arrange, as it requires only 2 wires, a button and a button. Please note that cables are connected to ground and GPIO 21 (according to Raspberry PI pinout):
Please find below some detail pictures:
Prepare Operating System
Make your OS up-to-date. From terminal, issue following command:
sudo apt update -y && sudo apt upgrade -y
You don’t need to install Python, as it is already installed in all Raspberry PI OS distros.
The only package to install regards RPI.GPIO, which enables PIN interfacing and management from Python:
sudo apt install rpi.gpio
Prepare Shutdown Button Script with Python
You can easily get a copy of my shutdown script directly in your Raspberry PI with following terminal command:
Following lines explain script parts.
Required libraries are imported to be used in script. We use RPI.GPIO libary to manage PINs and OS library to get shutdown command working:
import RPi.GPIO as GPIO import os
Then we associate shutdownPIN variable to improve code reading and PINs management. Change it if you use a different wiring:
shutdownPIN = 21
We then set used PIN according to our needs. First row set naming convention to Broadcom (BCM), then shutdownPIN is defined as INPUT, also using a pull-up software defined resistance to get it up when reading undefined state (please read Using mini Switch Button with Raspberry PI and Python about this configuration):
GPIO.setmode(GPIO.BCM) GPIO.setup(shutdownPIN,GPIO.IN, pull_up_down=GPIO.PUD_UP)
We also use a shutStarted variable. This will start to 0 and will be set to 1 once a shutdown procedure is started, so avoiding repeated shutdown commands if button is keep pushed:
shutStarted = 0
Then main program starts. The “try:” … “except” statement manages script running, catching and driving correctly exceptions.
All the work is performed by an endless while loop. Only if a previous shutdown has not performed by this script (“not(shutStarted)“) and button is pressed (“not(GPIO.input(shutdownPIN))“), then shutStarted variable is set to 1 and a “systemctl poweroff” command is send to operating system.
while True: if not(shutStarted) and not(GPIO.input(shutdownPIN)): shutStarted = 1 os.system("systemctl poweroff")
Last script part only manages script interruption (CTRL+C from keyboard), by cleaning GPIO status and printing an “interrupted” message on console:
except KeyboardInterrupt: print('interrupted!') GPIO.cleanup()
Managing Poweroff Permissions
As you know, poweroff/shutdown command in Raspberry PI requires root privileges (“sudo shutdown -h“). To avoid script from going in error because of missing superuser authentication, we need to allow pi user to execute poweroff command in “raspberrypi” host without needing to type root/superuser password. This can be achieved by appending a specific row in sudoers file. Open to edit this file:
sudo nano /etc/sudoers
And append at the end following row:
pi raspberrypi =NOPASSWD: /usr/bin/systemctl poweroff
Save and exit. You could need a reboot for this change to be running.
Test Shutdown Script
From here, you can test your shutdown script by using following command:
Then push your button and Raspberry PI will immediately start to power off.
Running Shutdown Script as a Daemon
You can also need to use shutdown script as daemon, running in background from boot and managing its staus from systemctl.
To reach this, move shutdown_button.py in /usr/bin/ folder:
sudo mv shutdown_button.py /usr/bin/
Create a new service under /etc/systemd/system/ folder:
sudo nano /etc/systemd/system/shutdownButton.service
and add following lines:
[Unit] Description=Shutdown button python script After=network.target StartLimitIntervalSec=0 [Service] Type=simple Restart=always RestartSec=1 User=root ExecStart=/usr/bin/env python3 /usr/bin/shutdown_button.py [Install] WantedBy=multi-user.target
Close and save. Start your new service with command:
sudo systemctl start shutdownButton.service
Chech it is running correctlywith systemctl status, getting something similar to following:
pi@raspberrypi:~ $ sudo systemctl status shutdownButton.service ● shutdownButton.service - Shutdown button python script Loaded: loaded (/etc/systemd/system/shutdownButton.service; disabled; vendor Active: active (running) since Tue 2020-11-24 16:52:11 GMT; 22s ago Main PID: 1088 (python3) Tasks: 1 (limit: 881) CGroup: /system.slice/shutdownButton.service └─1088 python3 /usr/bin/shutdown_button.py Nov 24 16:52:11 raspberrypi systemd: Started Shutdown button python script.
Moreover, if you want this script running after each reboot, enable it with systemctl:
sudo systemctl start shutdownButton.service
And test your button.
Before closing this tutorial, I want to share some considerations.
Using a mini button switch for shutdown is a simple and practical way to trigger RPI power off without the need of entering its desktop or terminal and avoiding risks to corrupt filesystem with mere power supply detachment.
If you use RPI.GPIO python library within other scripts and closing them with GPIO.cleanup(), you need to manage shutdown PIN from being cleaned and disabled.
An alternative way to implement a shutdown button is also acting on overlay settings from /boot/config.txt (refer to https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README for more info).
We are sorry that this post was not useful for you!
Let us improve this post!
Tell us how we can improve this post?