Implementing a safe shutdown button for Orange Pi Zero

07/05/18

Categories: Computers Tags: Orange Pi

~/contents

This project requires a momentary button. You will also need to solder headers to the GPIO pins.

Orange Pi Zero GPIO Pin Map

There are several OP0 GPIO libraries, but I use nvl1109’s orangepi_zero_gpio library. Clone and setup the library.

git clone https://github.com/nvl1109/orangepi_zero_gpio.git
sudo python install setup.py

Happily, the OP0 has two onboard LEDs. The green LED is in-use, but we can use the red one for testing. Try running the library’s blink LED example script to verify it works.

Below is a shutdown script that utilizes GPIO pins 5 and 6, which are the third row from the top. If you look at the pinout, you’ll see 5 / 6 map to PA 11 / GND. You can test this script by commenting out the subprocess line. When the button is pressed, the LED will blink.

#!/usr/bin/python
from pyA20.gpio import gpio
from pyA20.gpio import port
import time
import subprocess
import sys
import os

if not os.getegid() == 0:
    sys.exit('Script must be run as root')

CMD = "shutdown -h now"
POWER_BUTTON = port.PA11
LED = port.STATUS_LED
initial_button_state = True

gpio.init()
gpio.setcfg(POWER_BUTTON, gpio.INPUT)
gpio.pullup(POWER_BUTTON, gpio.PULLUP)
gpio.setcfg(LED, gpio.OUTPUT)

while True:
    ''' Returns a 1 if open and a 0 if pressed/closed '''
    current_button_state = gpio.input(POWER_BUTTON)

    ''' check if button state has changed '''
    if current_button_state != initial_button_state and not current_button_state:
        gpio.output(LED, 1)
        subprocess.call(CMD, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        initial_button_state = current_button_state

        ''' This resets the button state flag and turns off LED so the button can be pressed again if testing '''
        time.sleep(0.5)
        gpio.output(LED, 0)
        initial_button_state = True

time.sleep(0.1)

After we have a working script we need to make sure it runs automatically on startup. We can do this by editing /etc/rc.local to include the following before the exit line:

nohup /usr/bin/python /home/opi/scripts/power_button.py &

You may find you need to allow permissions on rc.local

sudo chmod +x /etc/rc.local

Reset

I chose this SBC taking for granted I would be able to implement safe shutdown and power buttons so the user would not have to unplug/replug the board. I have since learned these boards don’t have power management. As far as I can tell there is not a mechanism by which we could put the board to sleep and wake it. The schematic reveals a reset option like the one I posted about here.

For reference, however, in Armbian we can put the system to sleep with the following. We just can’t wake it up again.

systemctl suspend