"They recognize the Master, now that I have preached Truth to them. All the robots do."

- Isaac Asimov, I, Robot

Follow us on


Share this page with friends via

email icon facebook icon twitter icon
linkedin icon google plus icon blogger icon

Creating the shutdown button


In this article we are going to learn how to construct a simple hardware button, how to connect it to the Raspberry Pi and how to handle a press of the button with a simple Python script running as a Daemon process in the background.

Since the Blue Seal Robot should one day act on its own with an artificial intelligence, it is important to have a proper way how to manually shutdown the Raspberry Pi without risking any damage to the system installed on the SD-card.

The Button

Therefore we will construct a simple hardware button which we connect to the GPIOs on the Raspberry Pi and create a process waiting in background for a pressing of the button. Once the button is pressed, the script will notice this and start a shell command which will call for the full system stop in our case(but there are no limits for the reader's fantasy).

The button is shown on the right and consists of two main parts:

The resistor is important to ensure that we will not burn the Raspberry Pi if we make a mistake.

There are many good tutorials on the internet on how to make a button and use it with the Raspberry Pi. I would recommend this one, to learn more details about various ways how to connect and use a button with the RPi.

The schematics of the button and its wiring is shown on the following picture:

The circuits of the button

Once the button is connected to the RPi as shown on the upper circuit, we can write a simple program in Python to detect the pressing of the button and send the shutdown signal to the core. This can be managed by a simple script as this one:

    ###    This code is a part of a tutorial for the Blue Seal Project 
    ###     created by Jiří Daněk (www.bluesealproject.com).
    ###    Please, do not remove this remark from the code.

import RPi.GPIO as GPIO
import time
import os

port = 26            # the GPIO port used for pull-down detection       
GPIO.setup(port, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)   
                     # set the port to use the internal pull-down of the RPi 

   while True:                               # neverending loop              
      if (GPIO.input(port) == 1):            # if pull-down action detected 
         os.system("sudo shutdown now -h")   # execute the full stop of the system

except KeyboardInterrupt:
	GPIO.cleanup()     # in case of keyboard interruption release ports

The code can be dowloaded here.

Where we used the 26-th GPIO port for the pull-down and connected the resistor to it. The button is connected to the GPIO pin with the lower voltage of 3.3V. You should always check the layout of your Raspberry Pi which differs from version to version in order to avoid using GPIO ports which are specified for the I2C.

Run the button script as daemon

On the previous lines we have learned how to connect and operate the button with a simple script. Now we just need to tell the RPi to run this script at the start of the system. This can be done by the daemon tool. Daemon is a part of the system and we do not need to take care of this.

Nevertheless, we need to tell the system to run the Python script as daemon at the start of the system. This can be easily done by the following shell script:


    ###    This code is a part of a tutorial for the Blue Seal Project 
    ###     created by Jiří Daněk (www.bluesealproject.com).
    ###    Please, do not remove this remark from the code.

# Provides: 		runBUTTON
# Required-Start:	$remote_fs $syslog
# Required-Stop:	$remote_fs $syslog
# Default-Start:	2 3 4 5
# Default-Stop:		0 1 6
# Short-Decription:	Starts set of PYTHON scripts as daemon in background.

DIR=/home/pi/Code/BS			#Directory of the switch_of_button script
DAEMON=$DIR/button.py			#script's name
DAEMON_NAME=SWITCH_OFF_BUTTON           #identification

# Which user runs the button script

#The process ID of the script when it runs is stored here

. /lib/lsb/init-functions

#Carry out specific functions when asked to by the system
case "$1" in
    echo "Starting switch off button-script on one GPIO port"

    start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON

    echo "Stopping button-script on port GPIO 26"

    start-stop-daemon --stop --pidfile $PIDFILE --retry 10

    status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?
    echo "Usage: /etc/init.d/runBUTTON {start|stop|status}"
    exit 1

exit 0

The code can be dowloaded here.

This script must be save in folder /etc/init.d/ under the name runBUTTON.sh. The Python script for the button must be called button.py and be saved in the library /home/pi/Code/BS/ since these values are defined in the upper script as variables DIR and DAEMON, respectively.

After we have named and copied all files into the right folders, we need to make the script runBUTTON.sh executable by providing it the proper rights by executing command

sudo chmod 755 runBUTTON.py

Now, we should be able to start our Python script as daemon in the background using command

sudo /etc/init.d/runBUTTON.sh start

There is one last step required: we need to run the command

sudo update-rc.d runBUTTON.sh defaults

This command adds in symbolic links to the /etc/rc.x directories so that the init script is run at the default times(we can see these links if we execute command ls -l /etc/rc?.d/*runBUTTON.sh).

Now the button is ready to be pressed after every start of the RPi and to send the system back to sleep. A nice tutorial explaining the last steps in greater details can be found here.

In this article we learned many new things. We demonstrated how to construct a button and connect it to the Raspberry Pi and detect its pressing with a simple Python script. Moreover, we have show how to manage the script to start as daemon at the start of the system and run as a background process.

Blue Seal Project created by Jiří Daněk (2013-2016)