Introduction: Raspberry Pi Shutdown Button

As everyone at some point will recognise the Raspberry Pi doesn' t include any kind of shutdown button. So the only way to power it off is by unplugging it from the power supply. To make sure you get no corruption of your data files on the SD card you should shutdown the Raspberry before powering it off. So the whole procedure can be a bit annyoing especially if you want to use the Raspberry as some kind of embedded PC e.g. a media server or an internet radio.

The Raspberry Pi Shutdown Button provides a small circuit that includes the features:

  • sending a shutdown signal to the Raspberry if the Shutdown Button is pressed
  • waiting for the Raspberry to shut down
  • Powering off the Raspberry after save shutdown
  • Powering on the Raspberry after the Button is pressed again
  • LED light indicating the current state: On / Shutdown / Off

Step 1: Parts

You need the following parts:

  • Atmel AVRtiny with 8 Pins (attiny13 / attiny85)
  • Pushbutton
  • 2 BC337 transistors
  • 1 relay
  • 1 electrolytic capacitor 680µF
  • 1 green LED
  • 4 pin connectors
  • a veroboard
  • some kind of AVR ISP programmer (I used AVR ISP MKii)
  • resistors

Step 2: Schematic

This is the Designspark Schematic I used for the Raspberry Shutdown Button. The AVR is connected to a relay that switches the supply voltage of the Raspberry Pi. A led indicates that the Raspberry is switched on. In shutdown mode it will start blinking. There is also a shutdown signal that tells the Raspberry to halt before the power is cut off.

Step 3: AVR Programming

Here is the short listing of the AVR program.

Step 4: Raspberry Pi Shutdown Script

The Raspberry Pi needs a script that tells it to shutdown if it gets the shutdown signal. So the next thing we' ll do is write a Python script that waits for this signal on a specified GPIO pin. Here we' ll watch out for GPIO pin 7. On the model B this is GPIO4. Save this short script in something like /home/pi/pishutdown/pishutdown.py.

pishutdown.py

#!/usr/bin/python

# Import the modules to send commands to the system and access GPIO pins
import RPi.GPIO as gpio
import os

#Set pin numbering to board numbering
gpio.setmode(gpio.BOARD)

#Set up pin 7 as an input
gpio.setup(7, gpio.IN) 

# Set up an interrupt to look for pressed button
gpio.wait_for_edge(7, gpio.FALLING) 

# Shutdown
os.system('shutdown now -h')

Next we need a shell script that starts our Python script with root access. Put the shell script in the same directory as our Python script.

pishutdown.sh

#!/bin/sh
cd / cd home/pi/pishutdown sudo python pishutdown.py cd /

Add a logging directory by typing:

mkdir /home/pi/pishutdown/logs

Use crontab to autostart the script. Open the crontab editor by typing sudo crontab -e in the Console. Append the following line:

@reboot sh /home/pi/pishutdown/pishutdown.sh >/home/pi/pishutdown/logs/cronlog 2>&1

Reboot...

Step 5: Put Everything Together

Now connect the Raspberry Pi and the Shutdown board via the GPIO pins. Add supply voltage to the shutdown board and after booting properly press the Shutdown button for about a second. Now the led should start blinking and the Raspberry should begin the halt sequence. After a while the supply voltage for the Pi will be switched of by the relay. To switch it back on just hold the Button for about a second.

Comments

author
kghunt (author)2016-09-21

I planned to do something like this but I was going to use a second GPIO to create a watchdog signal like a pulse so the IVR can tell if the Pi is running. This way the power can be removed when the OS actually shuts down and could also be used to reboot a crashed pi.

author
ParisM2 made it! (author)2016-09-13

I finally made it although I followed a slightly different approach. here is a draft of the circuit http://imgur.com/a/bpWJA and here is my arduino code

int inputPin = 2; //button
int ledPin = 4; //indication led
int relayPin = 5; // relay for 5V supply
int shutdownPin = 6; // connected to pi via a transistor
int powerPin = 7; // detects if pin 37 of Rpi is high

int ras_on = 0; // 0 if pi is off 1 if pi is on
int sensorPwr1 = 1;
int sensor3 = 1;
int i;

void setup() {
// put your setup code here, to run once:
pinMode(inputPin, INPUT_PULLUP);
pinMode(powerPin, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);

pinMode(shutdownPin, OUTPUT);
pinMode(relayPin, OUTPUT);
Serial.begin(9600);
digitalWrite(relayPin, HIGH);
}

void loop() {
// put your main code here, to run repeatedly:
sensorPwr1 = digitalRead(inputPin);

sensor3 = digitalRead(powerPin);
//print out the value of the pushbutton
// Serial.println(sensorPwr1);

if (sensorPwr1 == 1 && ras_on == 0 ) {

ras_on = 1;
digitalWrite(relayPin, LOW);
Serial.println("power on");
sensorPwr1 = 0;
for (int i = 0; i <= 60; i++) {
digitalWrite(ledPin, LOW);
delay(200);
digitalWrite(ledPin, HIGH);
delay(800);
}
}
sensor3 = digitalRead(powerPin);
if (sensorPwr1 == 1 && ras_on == 1 ) {

digitalWrite(shutdownPin, HIGH);
delay(500);
digitalWrite(shutdownPin, LOW);

digitalWrite(ledPin, LOW);

ras_on = 0;
Serial.println("power off");
for (int i = 0; i <= 80; i++) {
digitalWrite(ledPin, LOW);
delay(200);
digitalWrite(ledPin, HIGH);
delay(200);
}
digitalWrite(relayPin, HIGH);
digitalWrite(ledPin, LOW);

}
sensor3 = digitalRead(powerPin);
if (sensor3 == 1 && ras_on == 1 ) {

digitalWrite(ledPin, LOW);

ras_on = 0;
Serial.println("power off");
for (int i = 0; i <= 80; i++) {
digitalWrite(ledPin, LOW);
delay(200);
digitalWrite(ledPin, HIGH);
delay(200);
}
digitalWrite(relayPin, HIGH);
digitalWrite(ledPin, LOW);
}

}

I still need to manage the reboots and adjust the timers better! but so far it works!

wm8c9fFr.jpg
author
ParisM2 (author)2016-09-06

How can I upload the hex file to the attiny?I tried avrdude but it doesn't seem to work? Has anyone rewritten the program in arduino IDE instead of cpp?

author
AidanHegg (author)2016-01-13

Couldn't you just shut down via the terminal?

author
MrLeeh (author)AidanHegg2016-01-13

Yes you can. But sometimes you don' t have one. E.g. when using as mediabox.

author
AlexTroy (author)2015-09-17

Hello!

please upload a binary hex file.

author
MrLeeh (author)AlexTroy2015-09-18

I just uploaded a hex file for attiny85 at 1MHz. I also provided a Makefile for compiling and uploading.

author
AlexTroy (author)MrLeeh2015-09-18

Sencs!

makefile dont downloadable as a php in this engine.

author
MrLeeh (author)AlexTroy2015-09-18

The content of the Makefile is:

--------------------------------------------------

F_CPU = 1000000

MCU = attiny85

PORT = /dev/cu.SLAB_USBtoUART

PROGRAMMER = stk500v2

all: main.hex

main.hex: main.elf

avr-objcopy -j .text -j .data -O ihex main.elf main.hex

main.elf: main.o

avr-g++ main.o -o main.elf

main.o: main.cpp

avr-g++ -g -mmcu=$(MCU) -DF_CPU=$(F_CPU) -O3 -c main.cpp -o main.o

upload: main.elf

avrdude -P$(PORT) -c$(PROGRAMMER) -p$(MCU) -U flash:w:main.hex

clean:

rm main.o main.elf

author
NamitS1 (author)2015-08-26

very thanx guys great work

author
rpotts2 (author)2015-06-27

So, I'm assuming you're using a DC SSR? Any particular brand, or just look for as many amps as possible? I got a few stereos and even a Krueg just begging to be dismantled.

author
MrLeeh (author)rpotts22015-06-28

I actually don' t use a SSR for this. Just a simple print relais. I wanted a small size so I used a Maluska FRS1B-S, 24V-, 1A. That is actually enough as the Raspberry only takes a maximum of 500mA. But an SSR is definetly an option too. Greetings

author
rpotts2 (author)2015-06-26

This is AWESOME! I've been wanting to do something like this for a while and since I'm building an HTPC with my Pi2 model, this should be an excellent mod.

author
josip.marusic.79 (author)2015-04-01

Hi, first ty for this code, but i have one question. I noticed since i put this code at startup in my rasp pie model 1 b that it runs much slower then before. Can it be due to loop that is taking up too much processor power?

author
MrLeeh (author)josip.marusic.792015-04-01

You are right. The while loop draws a lot of processor power. It is better to use the wait_for_edge() function of the gpio package. So the whole script becomes even smaller:

#!/usr/bin/python
# Import the modules to send commands to the system and access GPIO pins
import RPi.GPIO as gpio
import os
#Set pin numbering to board numbering
gpio.setmode(gpio.BCM)
#Set up pin 17 as an input
gpio.setup(17, gpio.IN)
# Set up an interrupt to look for pressed button
gpio.wait_for_edge(17, gpio.FALLING)
# Shutdown
os.system('shutdown now -h')

I' ve already been using this modified script a while but missed to update this Instructable. I will modify the original version asap. Thanks for the Feedback.

author
dpeach (author)2015-03-20

If I am not concerned about actually removing power from the board, but I want to send a shutdown signal when a power button is pressed over the GPIO pins, do I even need the circuit? It seems (in my very limited knowledge) that the Python script monitoring the GPIO pins could start the shutdown script and then I could pull the power manually.

This particular unit that I am working on is going to be used in Kiosk mode to display a certain web page. Basically a digital sign. There will be no interface available to the user (though I have SSH control through another machine). I want to make it easy for them to flip a switch and shut this down. Power can be cycled if it needs to be booted again.

Thanks for any input as to whether I can just run your Pythoun script (or a modified form) that senses when to start the shutdown/halt command when the switch is applied.

author
MrLeeh (author)dpeach2015-03-21

If you just want to send a shutdown signal to the Raspberry you don' t need the circuit. You can just use a pullup resistor to +3.3V and a switch to GND. As you said the Python script will initiate the shutdown and then you can pull the power.

author
dpeach (author)MrLeeh2015-03-21

Thank you! I had figured that was true based on some more stuff I read later today. I plan to build the switch this weekend. I will try to report back what I learned.

author
dpeach (author)dpeach2015-03-22

Everything works exactly as I wanted. Thank you! I have prototyped everything and will wait until I get my screen in this week to see how that affects my connectivity to the GPIO pins.

author
MrLeeh (author)dpeach2015-03-22

Great. So maybe I' ll find you later on Instructables with your project :)

author
eddieddieddie (author)2014-12-06

This project looks great - but what happens if you shutdown the Pi from the OS (instead of pressing the button). Will the circuit detect that and power off as the Pi itself powers off?

author
MrLeeh (author)eddieddieddie2014-12-07

No the circuit won' t detect a shutdown initiated from the OS. To add this feature you need to add an additional signal from the Pi to indicate whether the system is on or off. Actually this could be implemented in the Python Shutdown script.

author
dkocic1 (author)2014-12-02

How do you connect to raspberry pi gpio, i can't figure out.

Tnx

author
MrLeeh (author)dkocic12014-12-03

What exactly do you mean? For the shutdown signal I use GPIO Pin 7. But you are free to use any other GPIO. Just have to change it in the Python Script.

If you mean the typ of the connection wires. I use jumper wires female/male for this.

author
harkrue (author)2014-11-23

There is a difference between your wiring schematics and your listing for the Attiny.

According to your code the shutdown switching transistor (Q2) has to be connected to PIN 7 (PB2) and not to PIN3 (PB4). After that change it works great. Thank you for publishing your work. Helped me a lot!

author
MrLeeh (author)harkrue2014-11-23

Thanks for your feedback. I fixed the error in the code so that it' s fitting to the schematic.

author
SaiN2 (author)2014-09-10

Hello, I really love your guide but I can't view the schematic in eagle because of a start tag error. Anyone else having this problem? Also can you please add a higher resolution picture?

author
MrLeeh (author)SaiN22014-09-10

I just added a PDF containing the schmematic.

author
MrLeeh (author)SaiN22014-09-10

Hello, thanks for your comment. As described in the article I made the schematic with DesignSpark PCB from RS, not with Eagle. You can download DesignSpark for free here. Anyway I will try to provide a higher resolution picture of the schematic asap.

author

Nice, this is super useful for a lot of projects!