paulv
Posts: 558
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Halt-Restart with 1 Button

Sun Mar 20, 2016 2:20 pm

If you're looking for a real one button start/stop with power shutoff, you need to go here instead.viewtopic.php?f=91&t=129357

There have been several attempts published here and on the web to provide a simple method to halt the Pi with a button to get it ready for power removal.
Similarly, there have been several solutions suggested for restarting the Pi again from a halted state.

I have not seen any simple ones that combine the two. One button to put the Pi in a halt state, and the same button to re-start it again.
Here is such a solution.
Halt-Reset-Switch.png
Halt-Reset-Switch.png (22.85 KiB) Viewed 8650 times
The schematic is simple. The P6 connector is used to wake the Pi up, and a small Python script is used to put it to sleep. The Python script listens to a GPIO input pin to start the shutdown to halt sequence.

Update:
Dom has provided an alternative to the P6 solution, have a look here:
viewtopic.php?f=29&t=24682&p=1139735#p1139735

The trick is to use one button to do both. This is where R2 and C1 come into play. The P6-1 pin needs to be high for the Pi to run. Bringing it low (<0.5V) without any precautions will send the Pi to sleep - immediately. Warning! Without a proper shutdown! The circuit will prevent that from happening accidentally.

When you power-up the Pi, it will start to boot normally and at the end of the boot sequence, the Python script is activated by cron. To install the script, do the following:

Code: Select all

crontab -e
Go to the end of the file and add the following:

Code: Select all

@reboot sudo /usr/bin/python /home/pi/halt-and-reset.py
After a reboot, the python script is now active and is waiting for an interrupt that will be coming from the input pin.
A quick pulse from the button (< 0.5 second) is already enough to trigger the halt sequence, but not enough to drain C1 to get the run pin below .5V. The script shuts the Pi down and puts it in the Halt state. It still consumes power though. My Model(1) B still pulls about 70mA.
You can now safely remove the power from the Pi.

If you want to restart it from the halt state instead, a press of about 2 Sec. duration or more is enough to drain C2 and to re-start the Pi as soon as you release the button. The Pi will now go through an abbreviated power-up sequence.

The following Python script can be used to execute the halt state request and properly "Halt" the RPi so it can be restarted again with a next button press.

Code: Select all

nano halt-and-reset.py
Copy and paste this into the open editor:

Code: Select all

#!/usr/bin/env python
#-------------------------------------------------------------------------------
# Name:        halt-and-reset.py
# Purpose:     Together with a pushbutton and a little circuit attached to J6,
#              it is possible to use one button to halt the Pi, and restart it.
#
# Author:      paulv
#
# Created:     20-03-2016
# Copyright:
# Licence:     <your licence>
#-------------------------------------------------------------------------------

import RPi.GPIO as GPIO
import subprocess

DEBUG = False

GPIO.setmode(GPIO.BCM) # use GPIO numbering
GPIO.setwarnings(False)

BUTTON = 28 # GPIO-28 is P5-3 or any other standard pin
GPIO.setup(BUTTON, GPIO.IN, pull_up_down=GPIO.PUD_UP) # pulled-up just in case the circuit is not connected.

def main():

    while True:
        # set an interrupt on a falling edge and wait for it to happen
        GPIO.wait_for_edge(BUTTON, GPIO.FALLING)

        if DEBUG:
            print "Button press detected", GPIO.input(BUTTON)
        else:
            print "Stop requested, Halting the RPi now!"
            subprocess.call(['halt'], shell=True, \
                stdout=subprocess.PIPE, stderr=subprocess.PIPE)

if __name__ == '__main__':
    main()
You'll notice that I used a rather unusual GPIO pin, namely GPIO-28 which is pin-3 from the "unstuffed" P5 connector. The reason is that I still use several Model (1) B's and I can keep P1 free.

It should be fairly simple to mount a push button to the housing of a Pi box.
Adding the two resistors, and the capacitor should not be too difficult as well. The required connections to 3V3(P5-2), GND(P5-7) and the GPIO pin(P5-3) can all be made to the P5 connector. The only other connection must be made to J6-1, which is the pin (or rather the hole) closest to the edge of the PCB.

You now have a permanent way to halt and restart the Pi, especially handy when it is running headless.

Enjoy!
Last edited by paulv on Wed Mar 29, 2017 6:43 am, edited 1 time in total.

paulv
Posts: 558
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: Halt-Restart with 1 Button

Wed Apr 27, 2016 2:10 pm

Rather than installing the daemon the now old-fashioned way through cron, here is the now modern version using systemd.

Create a service file:

Code: Select all

sudo nano /etc/systemd/system/halt-and-reset.service
Copy and past the following into the open editor:

Code: Select all

# halt-and-reset service file, start a daemon on startup
# file: /etc/systemd/system/halt-and-reset.service
#
[Unit]
Description=Start halt-and-reset daemon

[Service]
RemainAfterExit=true
ExecStart=/usr/bin/python /home/pi/halt-and-reset.py

[Install]
WantedBy=multi-user.target
Note that like with the init.d scripts and cron before, you should always use the full path to the executable's and the target files.
Because there is no "before" or "after" specified, systemd will pick the time and place in the boot process. In this case, we don't care.
You now need to enable the service at boot:

Code: Select all

sudo systemctl enable halt-and-reset.service
The text after Description= gets displayed on the console and as an entry in the /var/log/syslog file :
Apr 27 15:45:10 raspi-tst systemd[1]: Starting Start halt-and-reset daemon...
Apr 27 15:45:10 raspi-tst systemd[1]: Started Start halt-and-reset daemon.
The status can be queried by:

Code: Select all

sudo systemctl status halt-and-reset.service
Which will produce :
● halt-and-reset.service - Start halt-and-reset daemon
Loaded: loaded (/etc/systemd/system/halt-and-reset.service; enabled)
Active: active (running) since Wed 2016-04-27 15:45:08 CEST; 1min 33s ago
Main PID: 297 (python)
CGroup: /system.slice/halt-and-reset.service
└─297 /usr/bin/python /home/pi/halt-and-reset.py

Apr 27 15:45:08 raspi-tst systemd[1]: Started Start halt-and-reset daemon.
Although the simple start through cron is easier and quicker to setup, it does not allow any control or status reporting.

My vote goes to systemd!

Enjoy!

mike17855
Posts: 2
Joined: Fri Feb 24, 2017 7:41 pm

Re: Halt-Restart with 1 Button

Sun Feb 26, 2017 2:53 am

Is this still valid for the pi3?

paulv
Posts: 558
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: Halt-Restart with 1 Button

Sun Feb 26, 2017 7:03 am

Hi Mike,

I have not tried it recently with the latest OS version, but there is no reason why not.
Give it a try!

Andrea
Posts: 15
Joined: Wed Jan 11, 2012 5:55 pm
Contact: Website

Re: Halt-Restart with 1 Button

Sat May 20, 2017 8:16 am

Sorry for adding a question to a rather old post.
I'd like to know if it's possible to use "classic" P1 connector and another GPIO for the purpose. I mean I prefer to get 3v3, GND and GPIO from there instead of soldering something on P5. I already have P6 (reset) soldered but I'd like to avoid to add another connector due to my fairly imprecise soldering skills.
Are there any drawbacks for it ?

Regards
Ben

paulv
Posts: 558
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: Halt-Restart with 1 Button

Sat May 20, 2017 10:39 am

Hi Ben, you can use just about any free GPIO pin, although I recommend to stay away from the special ones.
Just give it a try, you won't cause any problems, as long as you don't short pins together while soldering.

Return to “Automation, sensing and robotics”