pyledriver/blinkenLights.py

99 lines
2.4 KiB
Python
Raw Normal View History

2017-06-11 18:45:23 -04:00
'''
Controls an LED using a GPIO pin
'''
2016-12-30 02:51:56 -05:00
import RPi.GPIO as GPIO
import time, logging
from threading import Event
from exceptionThreading import ExceptionThread
2016-12-30 02:51:56 -05:00
from itertools import chain
logger = logging.getLogger(__name__)
class Blinkenlights(ExceptionThread):
2016-12-30 02:51:56 -05:00
def __init__(self, pin, cyclePeriod=2):
self._stopper = Event()
2017-06-17 14:26:29 -04:00
self._blink = Event()
self._linear = Event()
2017-06-17 14:26:29 -04:00
# number of pwm adjustments madeper duty cycle, note stepsize is in half
# because we spend first half of period decreasing duty cycle and the
# second half increasing (between 0 and 100)
self._steps = 40
2017-06-18 15:00:01 -04:00
self._stepsize = int(100/(self._steps/2))
2016-12-30 02:51:56 -05:00
self._pin = pin
self.setCyclePeriod(cyclePeriod) #cyclePeriod is length of one blink cycle in seconds
GPIO.setup(pin, GPIO.OUT)
pwm = GPIO.PWM(self._pin, 60)
def linearLoop():
for dc in chain(range(100, -1, -self._stepsize), range(0, 101, self._stepsize)):
t = (self._linear.is_set(), self._blink.is_set())
if t == (True, True):
pwm.ChangeDutyCycle(dc)
time.sleep(self._sleeptime)
else:
return t
return (True, True)
2016-12-30 02:51:56 -05:00
def blinkLights():
pwm.start(0)
while not self._stopper.isSet():
2017-06-11 18:45:23 -04:00
if self._blink.is_set():
linearSet, blinkSet = linearLoop()
if not blinkSet:
continue
elif not linearSet:
2017-06-18 15:00:01 -04:00
t = self._sleeptime*self._steps/2
pwm.ChangeDutyCycle(100)
self._linear.wait(timeout=t)
if self._linear.is_set() or not self._blink.is_set():
continue
pwm.ChangeDutyCycle(0)
self._linear.wait(timeout=t)
2016-12-30 02:51:56 -05:00
else:
pwm.ChangeDutyCycle(100)
2017-06-17 14:44:29 -04:00
self._blink.wait()
2016-12-30 02:51:56 -05:00
pwm.stop() # required to avoid core dumps when process terminates
super().__init__(target=blinkLights, daemon=True)
def start(self):
ExceptionThread.start(self)
2016-12-30 02:51:56 -05:00
logger.debug('Starting LED on pin %s', self._pin)
def stop(self):
2017-06-10 01:52:06 -04:00
if self.is_alive():
self._stopper.set()
2017-06-17 14:44:29 -04:00
self._blink.set()
self._linear.set()
2017-06-10 01:52:06 -04:00
logger.debug('Stopping LED on pin %s', self._pin)
def setCyclePeriod(self, cyclePeriod):
self._sleeptime = cyclePeriod/self._steps
def setLinear(self, toggle):
if toggle:
self._linear.set()
else:
self._linear.clear()
2017-06-08 02:15:50 -04:00
def setBlink(self, toggle):
2017-06-11 18:45:23 -04:00
if toggle:
self._blink.set()
# unblock the _linear Event if threads are waiting on it
if not self._linear.is_set():
self._linear.set()
self._linear.clear()
2017-06-11 18:45:23 -04:00
else:
self._blink.clear()
2017-06-08 02:15:50 -04:00
2016-12-30 02:51:56 -05:00
def __del__(self):
self.stop()