4

I want to add a on/off switch to my pi 2 to correctly shut the pi down

This is the switch I want to add:

Edit: moved from a link to be included below: A Single Pole Snap action chrome-like switch with a plate bearing the words "On" (on a Red background) and "Off" (on a black background) with wires going off out of the picture

This guy in a Raspberry Pi kik group made this code for me

http://pastebin.com/WTeR39d8

Edit - reproduced below:

#!/usr/bin/python3

import RPi.GPIO as g
from time import sleep
from subprocess import Popen

g.setmode(g.BCM)
g.setup(26,g.IN)

def p26_callback(channel):
  command = ['/usr/bin/sudo','poweroff']
  Popen(command)
  g.remove_event_detect(channel) # we've done it once, stop watching
  return

g.add_event_detect(26, g.FALLING, callback=p26_callback)

try:
    sleep(30)
finally:
    g.cleanup()

but he didn't explain how to wire it up. Also I have no idea how to add the code to the pi.

I'm running kali. I haven't tried to wire the switch or put the code in the pi because I do not know how to.

3 Answers 3

4

I just finished building a power-off circuit yesterday, although mine uses a momentary switch.

Here is the python code (with attribution embedded):

#!/bin/python
#This script was authored by AndrewH7 and belongs to him (www.instructables.com/member/AndrewH7)
#You have permission to modify and use this script only for your own personal usage
#You do not have permission to redistribute this script as your own work
#Use this script at your own risk

import RPi.GPIO as GPIO
import os

gpio_pin_number=YOUR_CHOSEN_GPIO_NUMBER_HERE
#Replace YOUR_CHOSEN_GPIO_NUMBER_HERE with the GPIO pin number you wish to use
#Make sure you know which rapsberry pi revision you are using first
#The line should look something like this e.g. "gpio_pin_number=7"

GPIO.setmode(GPIO.BCM)
#Use BCM pin numbering (i.e. the GPIO number, not pin number)
#WARNING: this will change between Pi versions
#Check yours first and adjust accordingly

GPIO.setup(gpio_pin_number, GPIO.IN, pull_up_down=GPIO.PUD_UP)
#It's very important the pin is an input to avoid short-circuits
#The pull-up resistor means the pin is high by default

try:
    GPIO.wait_for_edge(gpio_pin_number, GPIO.FALLING)
    #Use falling edge detection to see if pin is pulled 
    #low to avoid repeated polling
    os.system("sudo shutdown -h now")
    #Send command to system to shutdown
except:
    pass

GPIO.cleanup()
#Revert all GPIO pins to their normal states (i.e. input = safe)

The really important thing to remember is that you should have two resistors in your circuit, like so: circuit schematic

R1 (a 10k resistor) goes to ground and keeps your chosen GPIO pin from floating, while R2 (a 1k resistor) helps prevent damage to that same pin from the 3.3V source.

4
  • 2
    Welcome to the Raspberry Pi corner of the Stack Exchanges. Good call on using edge-detection rather than polling!
    – SlySven
    Commented Feb 22, 2016 at 18:09
  • @SlySven. Thank you. I spent a lot of time researching code, and AndrewH7's was the most ideal implementation. Obviously I think he did a pretty good job. :)
    – Jerry
    Commented Feb 22, 2016 at 18:31
  • Excuse the noobishness, but what does the "downward facing arrow"-ish symbol on the diagram mean? Commented Feb 9, 2017 at 15:59
  • No worries! It indicates the circuit's ground.
    – Jerry
    Commented Feb 11, 2017 at 14:39
1

The code is designed to:

  • monitor for activity on GPIO pin 26 (by BCM i.e. Broadcomm pin numbering), once it is set up it waits endlessly (in chunks of 30 seconds) and it will detect a "falling"-edge which is what happens to a pin that has a high pull-up and a switch connected between it and ground when the switch that is normally open is activated (pressed!)

  • when such an event happens it runs the /usr/bin/sudo command with the argument poweroff and then stops waiting for any more occurrences of this event.

  • eventually it will be told to terminate (by the poweroff command it happened to initiate!) and it will do any clearup actions it can do before exiting.

So you will need to wire a switch between the GPIO pin that is 26 (physical pin 37 IIRC) and rather than rely on an internal pull-up I'd also connect a 10K Ohm resistor between that GPIO pin and 3.3V. Then you need to get that code to be run as a user with permission to use the GPIO pins - for this the root user is a reasonable choice because you do not want a normal user to interfer with it, and you want it to start when the Pi is booted up and to be running until (it tells the Pi to) shutdown. The easiest way to do that is to paste the entire code into a (text) file and save it as something like gpio_poweroff.py, it will be helpful to mark it as executable with chmod u+x gpio_poweroff.py and place it in /sbin with sudo mv gpio_poweroff.py /sbin. Finally you need it to be run when the Pi is started up, and that varies on something that I do not know about your system. If it was my system I would insert the command to run it: /sbin/gpio_poweroff.py & into the file /etc/rc.local {the & is important, it means let it run in the background, don't wait around (for until that button gets pressed otherwise) for it to finish}. However I am not certain that your system will have such a file - if it does then it should be Ok to use it.

2
  • Looking at the code the sleep(30) instruction is only there to prevent quitting the script at once. It doesn't seem to wait 30 seconds between detections. Event detection is immediate otherwise you'd need to keep the button pressed for 30 seconds. Anyway I'm still confused as I'd have expected an infinite loop.
    – user29510
    Commented Dec 31, 2015 at 23:34
  • Yeah it keeps running a sleep(30) in a loop I thought but now I am not so sure - as for python I hardly know my Asp from my Elbow so I'm not the best to rely on here... I recognise that the event detection is outside of any loop - it wouldn't be much good if you have to hold the button for up to 30 seconds before anything happened.
    – SlySven
    Commented Dec 31, 2015 at 23:43
0

You may add a power off switch to your PI so that it shuts down properly. However there's a reason, not widely advertised though, the designers didn't feature it: if you run the system off a read-only partition, you can safely pull the plug off the PI hence spare one precious pin.

3
  • what? i dont get it
    – laxus
    Commented Jan 2, 2016 at 7:43
  • @laxus On a Raspberry PI the need for a switch and a proper shutdown is due to Linux running non-tweaked and the risk of corrupting the SD card when pulling off the power cable. If you run Linux from a read-only root filesystem, that risk is eliminated: data corruption on the SD card results from pulling off the cable while the system writes to the SD card. No data write, no corruption.
    – user29510
    Commented Jan 2, 2016 at 12:31
  • Actually the corruption can occur in any file-system where pending write data is not flushed before the power is removed - sync is obviously reckoned to help with that, and journalled file-systems can help with the clean-up when things still go wrong. A read-only FS obviously cannot HAVE any data waiting to be written to it when the plug is pulled but having all storage as fixed and unchangable is only useful in some circumstances (e.g. a public information kiosk where nothing the user does is saved).
    – SlySven
    Commented Feb 27, 2016 at 3:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.