Orderly shutdown your RasPi using a hard disk jumper


12 posts
by monete » Wed May 01, 2013 10:04 pm
Tired of having to SSH to your headless Raspberry just to halt it? Did you already corrupted your SD card's content a few times because you didn't turn your pico machine off properly? If you found yourself before in a similar scenario or if you just want to improve the features of your tiny beast a bit more, keep reading this easy recipe.

What we are working on?
This has been tested with a rev. 2 Raspberry Pi, whose GPIO pins numbering differ from the rev. 1 ones, running Raspbian.

What do we need?
You will only need a hard disk pin jumper like one of these.
Image
Image

Note that the large ones are much easier to manipulate

Let's get to work
The final purpose is to have a watchdog which will read permanently the state of the selected GPIO pin to check if it, the watchdog, has to shutdown the machine. But first of all, we will test if everything works as desired by running this script with root privileges (https://github.com/g0to/misc_scripts/bl ... actions.sh)*. The script will check every 60 seconds if GPIO3 reading returns a 0 value (which means that it's connected to ground) and, if so, it'll command the machine to halt.
With the script running, it's time to insert the jumper into GPIO3 and ground, the pins with the red dots in the following image:

Image

Note that you can safely connect the two pins together since GPIO2 and GPIO3 provide a 1k8 pull up resistor.

In less than a minute the computer should shut down orderly and that proves we can go ahead with the automation.

The last step is to add a new line to the system-wide crontab (/etc/crontab) for running the above script every time the machine boots up:

Code: Select all
@reboot        root    /home/user/scripts/gpio_actions.sh

I hope this could be as useful as it has be for me. Please, ask, suggest or correct whatever you think you may.
Cheers!

References:

Tips:
    - You can leave the jumper permanently attached to your GPIO by connecting it to only one pin, GPIO3 for example, and cover with it GPIO3 and the GND pin only when you want to manually turn off your Raspberry Pi. Here is an ilustrative picture where you can see the jumper attached to only one of the pins, ready to use.

    Image
    - You could use the other GPIO provided with a pull up resistor (GPIO2 in rev.2 boards) for other manual configuration purposes like, for example, obtain an IP address inside a LAN using the DHCP protocol (dhclient) for a RasPi initially configured with static network parameters. Useful for a headless machine that you move from LAN to LAN without previous network settings adjustments.

* EDIT: See below's paulv approach for a more efficient way of getting GPIO's pin status using interruptions. Here, my new approach using interruptions.
Last edited by monete on Thu Jun 06, 2013 5:26 pm, edited 4 times in total.
User avatar
Posts: 33
Joined: Wed Oct 10, 2012 1:54 pm
by FM81 » Thu May 02, 2013 12:50 pm
Hi at all!
You can also use some C-related stuff like:
Code: Select all
/*
* bpoweroff.c:
* Poweroff by button pressed
*/

#include <wiringPi.h>
#include <stdio.h>

int main (void)
{
  int pin_switch = 9; // GPIO1 original layout - GPIO3 on REV 2
  int del = 250;

  if (wiringPiSetup() == -1) return 1;

  pinMode(pin_switch, INPUT);

  for (;;){
    if (digitalRead (pin_switch) == 0) system("poweroff");
    delay(del);
  }

  return 0 ;
}
It needs wiringPi, but you can use a timeout in range about one second (for example 250ms), and it did not waste much CPU-power ...
see also here http://raspberrycenter.de/comment/3424#comment-3424 (sorry, in german) and all included links. Primary idea cames from member "Wal" of the other forum; I've only made some little changes for my needs.

Greetings, FM_81
Posts: 180
Joined: Wed Apr 17, 2013 4:33 pm
by paulv » Fri May 24, 2013 9:55 am
There is yet another method to do this without polling and sleep(ing).
Look at the following topic at the post from Fri May 24, 2013 3:52:
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=63&t=18677&p=355974#p355974
Posts: 90
Joined: Tue Jan 15, 2013 12:10 pm
by monete » Thu May 30, 2013 9:07 am
paulv wrote:There is yet another method to do this without polling and sleep(ing).
Look at the following topic at the post from Fri May 24, 2013 3:52:
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=63&t=18677&p=355974#p355974


Works like a charm! The approach using interruptions is more efficient that my polling method, so it won the prize to substitute my original solution.

Thanks for your great contribution, paulv ;)

NOTE: Those of you who decide to use this last script, don't forget to change the GPIO pin number to the one you are actually using. For example, I'm still using GPIO 3.
User avatar
Posts: 33
Joined: Wed Oct 10, 2012 1:54 pm
by brijesh4u » Wed Jul 17, 2013 6:43 am
hello Paulv and Monete,

Thanks for such an easy solution for shutdown, its very helpful and easy to understand.
its working perfectly but i realized after the shutdown if you put the jumper back again, the PI boots back up again.
Is this approach is fine for the startup and shutdown raspberry pi or we should use this only for the shutdown.

Thanks
Brij.....
Posts: 1
Joined: Wed Jul 17, 2013 6:34 am
by paulv » Wed Jul 17, 2013 9:08 am
It can be used for both. Shutdown (is actually sleep mode) and wake-up.

If you want to get a bit more elaborate, look at my other post : viewtopic.php?f=37&t=48455&p=379280#p379280
Posts: 90
Joined: Tue Jan 15, 2013 12:10 pm
by FM81 » Wed Jul 17, 2013 9:51 am
Other idea:
If one cannot use GPIO3 (may be, this one is always in use, or what ever).
Shutdown and reset with same button; uses 2 GPIO's, in example 4 & 17:
RPi-Reset-2.JPG
RPi-Reset-2.JPG (30.68 KiB) Viewed 9352 times
If LED on "shutdown", otherwise "reset".

MfG, FM_81

PS: the init-script:
Code: Select all
#! /bin/sh
### BEGIN INIT INFO
# Provides:          gpio4+17
# Required-Start:
# Required-Stop:
# Should-Start:      glibc
# Default-Start:     S
# Default-Stop:
# Short-Description: Special usage of GPIO04 and GPIO17
# Description:       Define GPIO04 as output
#                    and set it to high-level as early as possible
#                    Watch button on GPIO17 via IRQ-polling
#                    for shutdown (binary '/usr/sbin/shutkey')
### END INIT INFO

. /lib/lsb/init-functions

case "$1" in
  start|"")
   echo "4" > /sys/class/gpio/export
   echo "out" > /sys/class/gpio/gpio4/direction
   echo "1" > /sys/class/gpio/gpio4/value
   log_daemon_msg "From now watching shutdown-button" "shutkey"
   /usr/sbin/shutkey -g 17
   log_end_msg $?
   ;;
  *)
   echo "Error: argument '$1' not supported" >&2
   exit 3
   ;;
esac

:
For shutkey-program look here: http://www.helbing.nu/projekte/raspberr ... n-key.html
But every python-script will do the same ...
Last edited by FM81 on Wed Jul 17, 2013 10:04 am, edited 1 time in total.
A: What does the command 'cat /dev/urandom', can you tell me please?
B: Yeah, that's very simple: It feeds your cat with radioactive material!
Posts: 180
Joined: Wed Apr 17, 2013 4:33 pm
by monete » Wed Jul 17, 2013 9:58 am
Good observation, brijesh4u! I didn't try it before (pulling the jumper with the Raspberry in sleep mode).
Since I unplug my RasPi AC adapter just after I shut it down I can't see a direct application for this "back to life" feature, but it sure can be used by someone who wants to operate the power up/down of its RasPi just using the jumper. Just taking in care that leaving the AC adapter always plugged can cost you a little bit of extra energy consumtion.

Thanks for your input, brijesh4u!
User avatar
Posts: 33
Joined: Wed Oct 10, 2012 1:54 pm
by Gerrelt » Thu Sep 05, 2013 4:57 pm
So, if I understand correctly, instead of a jumper, I could wire in a momentary switch?

And is there a way to connect an LED to some of the pins to see if the Raspberry is shutdown? I cannot see the raspberry in my situation.
my Raspberry Pi page: http://raspberry.gerrelt.nl
User avatar
Posts: 214
Joined: Sat Nov 10, 2012 9:01 am
by monete » Thu Sep 05, 2013 5:18 pm
Gerrelt wrote:So, if I understand correctly, instead of a jumper, I could wire in a momentary switch?

That's it, Gerrelt. Just something to close the circuit when needed.

Gerrelt wrote:And is there a way to connect an LED to some of the pins to see if the Raspberry is shutdown? I cannot see the raspberry in my situation.


As its name indicates, the GPIO (General-purpose input/output) can be used for a wide range of purposes. This one you are talking about included. You have 5v and 3.3v pins and ground pins to play with, just choose.

Please, be careful and ask before doing if you are not sure about your next step. Fried berries are not tasty ;)
User avatar
Posts: 33
Joined: Wed Oct 10, 2012 1:54 pm
by Collie714 » Tue Mar 25, 2014 5:32 pm
Gerrelt wrote:So, if I understand correctly, instead of a jumper, I could wire in a momentary switch?

And is there a way to connect an LED to some of the pins to see if the Raspberry is shutdown? I cannot see the raspberry in my situation.


This is my version of the code, with two LEDs one is faded when the Pi has power and fully lit when the python script is online, the other LED turns on when the button is pressed and goes off when the system has halted.
Code: Select all
import os
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM) #sets GPIO mode to GPIO pins "GPIO.setmode(GPIO.BOARD) " will set it to pin numbers
GPIO.setwarnings(False) # turns off notifications of GPIO pins already in use - for putty script/manual execution of script
GPIO.setup(24,GPIO.IN, pull_up_down=GPIO.PUD_UP) #connected to Button 1 and to Gnd
GPIO.setup(3, GPIO.OUT) # connected to 0V from LED (red) 5V connected 100Ohm resistor connected to +5v (also works with 3.3v
GPIO.setup(2, GPIO.OUT) # connected to 100Ohm resistor connected to +5V LED (green) connected to 0V
GPIO.output(2, GPIO.HIGH) # Turns on LED
GPIO.output(3, GPIO.HIGH) # Turns on internal pullup resistor --> turns off LED
os.system("sudo service minidlna force-reload") #using the pi as a DLNA server this refreshes contents
while True: #loop
    GPIO.wait_for_edge(24, GPIO.FALLING) # detects button press
    print "Button Pressed"
    GPIO.output(3, GPIO.LOW) # Turns on LED (red)
    os.system("sudo shutdown -h -P now") # shuts down Pi
 
 
    GPIO.wait_for_edge(24, GPIO.RISING) # detects button lift (not exactly necessary except for testing)
    print "Button Released"
 
GPIO.cleanup() # resets the GPIO pins (again not exactly necessary except for testing)
GPIO.output(2, GPIO.LOW) # turns off the LED (green)



I edited rc.local with
Code: Select all
sudo nano /etc/rc.local

and added
Code: Select all
sudo python ShutDownDLNA.py
The python script was saved as 'ShutDownDLNA.py' by the way

I also added a batch script on my PC to shutdown the Pi remotely using putty
Code: Select all
c:\putty\putty.exe -ssh pi@192.168.1.240 -pw raspberry -m c:\putty\ShutdownDLNA.txt

and the txt file contained the command
Code: Select all
sudo python /home/pi/ShutdownDNLANow.py

This script was pretty much a cutdown version that didnt wait on button presses
Code: Select all
import os
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM) #sets GPIO mode to GPIO pins "GPIO.setmode(GPIO.BOARD) " will set it to pin numbers
GPIO.setwarnings(False) # turns off notifications of GPIO pins already in use - for putty script/manual execution of script
GPIO.setup(24,GPIO.IN, pull_up_down=GPIO.PUD_UP) #connected to Button 1 and to Gnd
GPIO.setup(3, GPIO.OUT) # connected to 0V from LED (red) 5V connected 100Ohm resistor connected to +5v (also works with 3.3v
GPIO.setup(2, GPIO.OUT) # connected to 100Ohm resistor connected to +5V LED (green) connected to 0V
GPIO.output(2, GPIO.HIGH) # Turns on LED
GPIO.output(3, GPIO.HIGH) # Turns on internal pullup resistor --> turns off LED

while True :
    GPIO.output(3, GPIO.LOW)
    os.system("sudo shutdown -h -P now")
GPIO.cleanup()
GPIO.output(2,GPIO.LOW)


And finally I soldered on a two pin header to P6 on the Pi's board and connected that to another button - essentially a reset/boot from halt switch.
Posts: 9
Joined: Thu Nov 22, 2012 2:07 pm
by themagni » Fri Apr 18, 2014 9:16 pm
Forgive me for asking this question, but I don't know where to put that GPIO script so that it will run and keep watching the port.

Where should I put it, and how should I call it?

Thank you.
User avatar
Posts: 7
Joined: Fri Apr 18, 2014 9:04 pm