RPi GPIO: Adding switches and lights

Goal:

Create a pair of LED’s and push buttons on my RPi which can run scripts. ?One will shut down the Pi (updated here), the other will rsync a directory to a USB. Also I will read the status of a UPS. This may/will become more complicated since the UPS doesn’t have any useful interface (requiring an Arduino to:

  • Watch the UPS battery voltage and tell the RPi to power down.
  • Monitor whether mains power is applied.
  • Once mains is re-powered, restart the RPi after a UPS shut down using the hardware reset pins on the Pi.)
Instructions:
  1. As in these RPi ubuntu instructions I installed python.. I removed sudo from the last command to make the command output happy
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install python-pip
pip install RPi.GPIO
  1. Initially I set up a breadboard as in this youtube video (using the linked files)
    from time import sleep
    import RPi.GPIO as GPIO
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(12, GPIO.OUT)
    while 1:
     GPIO.output(12, False)
     sleep(1)
     GPIO.output(12, True)
     sleep(1)

  2. I can run the script using
    sudo python "/home/ubuntu/gpio/blink.py"

    Note that the sleep function – time.sleep(0.01) – is important to use in each loop as to give the CPU time for other processes.

  3. Once I confirmed that worked (sweet), I moved onto more a more complicated script. This will shut down the Pi if one of the buttons is held down. It uses interrupts so sleep isn’t required in the script.
    #!/usr/bin/env python
    
    import time
    import RPi.GPIO as GPIO
    import subprocess
    import os
    
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(12, GPIO.OUT) #Power LED
    GPIO.setup(11, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) #Power button
    GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) #used to keep CPU usage low
    
    shutdownCommand = "shutdown -h now"
    
    def stop_callback(channel): #shutdown sequence
        GPIO.output(12, 1) #flash LED
        time.sleep(1)
        if GPIO.input(11) == 1:
          time.sleep(1)
          if GPIO.input(11) == 1:
            GPIO.output(12, 0)
            time.sleep(.1)
            GPIO.output(12, 1)
            time.sleep(.1)
            GPIO.output(12, 0)
            time.sleep(.1)
            GPIO.output(12, 1)
            time.sleep(.1)
            GPIO.output(12, 0)
            process = subprocess.Popen(shutdownCommand.split(), stdout=subprocess.PIPE)
            output = process.communicate()[0]
            GPIO.cleanup()
          else:
            GPIO.output(12, 0)
        else:
          GPIO.output(12, 0)
    
    GPIO.add_event_detect(11, GPIO.RISING, callback=stop_callback, bouncetime=300)
    
    try:
        GPIO.output(12, 0) # Light LED
        GPIO.wait_for_edge(18, GPIO.FALLING)
    
    except KeyboardInterrupt:
        GPIO.cleanup() # clean up GPIO on CTRL+C exit
    GPIO.cleanup() # clean up GPIO on normal exit
  4. I want my python script to run at boot in the background. Since it is triggered by interrupts, it won’t use too much CPU (I think). The script will go in /usr/local/sbin. To run at boot I added this line to /etc/rc.local
    python "/usr/sbin/powerscript.py" &

    Oddly the system hung while booting a couple times, then script worked perfectly. I’m wondering if this may have something to do with the problem? :/ Or it could just be the ubuntu distribution hasn’t been optimised for RPi3 yet – the reason I’m currently thinking since this RPI3 ubuntu distribution isn’t on the main download thing yet :/ Hopefully this isn’t replicated on my RPi2

  5. Now to rsync a USB drive with GPIO control and indication.

1 thought on “RPi GPIO: Adding switches and lights”

Leave a Reply

Your email address will not be published. Required fields are marked *