1

I'm working on programming a LED strip lights application that is activated with a momentary push button and if the lights are not turned off by the push button, then they automatically turn off after 30 minutes.

There are automatic timers out there, but this timer only starts after the button is pressed and the button can take it back to a standby state before the 30 minutes have elapsed.

I am good with the Raspberry Pi 3 GPIOs and the relay required, but seeking some guidance on the code

  • First button press: Lights activate. Have the option to move to the second button press or if the button is not pressed a second time, then the side lights will turn off automatically after 30 minutes.

  • Second button press: Lights turn off and python is waiting for the first button press (again).

Below is one version that I been working on but due to working through various attempts I'm sure it requires rework. .

The auto-shutoff is required to ensure they aren’t left on for days at time. :-)

It is possible that I need to pull in another module, but I can’t seem to hack my way into figuring out the shutoff timer or where to place it. Thanks.

import RPi.GPIO as GPIO

from time import sleep

GPIO.setmode(GPIO.BCM)

LEDPin = 26

buttonPin = 5

# Setup the pin the LED is connected to

GPIO.setup(LEDPin, GPIO.OUT)

# Setup the button
GPIO.setup(buttonPin, GPIO.IN, pull_up_down = GPIO.PUD_UP)

buttonPress = True
ledState = False

while (1):

        print("Press it")
        buttonPress = GPIO.input(buttonPin)
        if buttonPress == False and ledState == False:
            GPIO.output(LEDPin, True)
            print("LED ON")
            ledState = True
            sleep(.25)

        elif buttonPress == False and ledState == True:
            GPIO.output(LEDPin, True)
            ledState = False
            sleep(0.25)

        sleep(0.15)
  • Would you mind using GPIOzero? I know how to help you if you'd be willing, and it's significantly easier. – C Malasadas May 3 '17 at 15:16
2

Here is one way of doing this with (my) pigpio.

#!/usr/bin/env python

import time
import pigpio

LEDPin = 26
buttonPin = 5

LEDOn = False
minutesOn = 0

def callback(gpio, level, tick):
   global minutesOn, LEDOn
   if level == 0: # button press
      if LEDOn:
         print("LED off")
         LEDOn = False
         pi.write(LEDPin, 0)
      else:
         print("LED on")
         LEDOn = True
         pi.write(LEDPin, 1)
         minutesOn = 0
   elif level == pigpio.TIMEOUT:
      if LEDOn:
         minutesOn += 1
         print("LED on for {} minutes".format(minutesOn))
         if minutesOn >= 30:
            print("LED off")
            LEDOn = False
            pi.write(LEDPin, 0)

pi = pigpio.pi()
if not pi.connected:
   exit()

# Setup the pin the LED is connected to
pi.set_mode(LEDPin, pigpio.OUTPUT)

# Setup the button
pi.set_mode(buttonPin, pigpio.INPUT)
pi.set_pull_up_down(buttonPin, pigpio.PUD_UP)
pi.set_glitch_filter(buttonPin, 5000) # 5000 micros debounce

pi.set_watchdog(buttonPin, 60000) # watchdog every minute

cb = pi.callback(buttonPin, pigpio.EITHER_EDGE, callback)

while True: # all the work is done in the callback
   time.sleep(1)
  • Thanks. I was able to start pigpio and save the script. I starts fine, thanks! I think it needs a sleep to debounce, because it often starts firing like a machine gun (sorry, that is the best comparison I could think of based on the sound of the relay). – Unbored May 4 '17 at 19:38
  • @Unbored For a mechanical switch add the line pi.set_glitch_filter(buttonPin, 5000) after the pi.set_pull_up_down line. It sets a 5 millisecond debounce. You might need more. See abyz.co.uk/rpi/pigpio/python.html#set_glitch_filter. – joan May 4 '17 at 20:59
  • Will do, thanks. I think there may be a contact issue with the new switch and will try another one in a day or two. I really like the added feature of printing out the per minute count down timer. – Unbored May 4 '17 at 21:24
0

Okay, here's how to do it with GPIOzero:

from gpiozero import LED, Button
import time
# Set your pins
button = Button(5)
led = LED(26)

# Placeholder variable
global ledstatus
ledstatus = False

def toggleled():
    if ledstatus == False:
        led.on()
        ledstatus = True
        global original_time
        original_time = time.is()
        start_timer()
    elif ledstatus == True:
        led.off()

# Checks if 30 seconds has passed
def start_timer(): 
    if time.is() - original_time >= 30:
        led.off()
    else:
        time.sleep(1)
        start_timer()


button.when_pressed = toggleled # This is a function

Please note that this code isn't tested and may contain errors. Please let me know if this is the case, and I'll try to debug it.

  • Thanks. The time.is threw an error when I tried to save the script. I changed it to time.now in both locations and the error went away. When I run the script, the following error is thrown. – Unbored May 4 '17 at 19:32
  • >>> >>> Traceback (most recent call last): File "/usr/lib/python3/dist-packages/gpiozero/pins/rpigpio.py", line 232, in <lambda> callback=lambda channel: self._when_changed(), File "/usr/lib/python3/dist-packages/gpiozero/mixins.py", line 311, in _fire_events self._fire_activated() File "/usr/lib/python3/dist-packages/gpiozero/mixins.py", line 343, in _fire_activated super(HoldMixin, self)._fire_activated() File "/usr/lib/python3/dist-packages/gpiozero/mixins.py", line 289, in _fire_activated self.when_activated() – Unbored May 4 '17 at 19:35
  • File "/home/pi/LED_GPIOzero.py", line 12, in toggleled if ledstatus == False: UnboundLocalError: local variable 'ledstatus' referenced before assignment – Unbored May 4 '17 at 19:35
  • Sorry, forgot to make the variable global. Fixing post. – C Malasadas May 4 '17 at 23:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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