-
Notifications
You must be signed in to change notification settings - Fork 0
/
ledoutput.py
137 lines (114 loc) · 3.41 KB
/
ledoutput.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# ledoutput.py
#
# coordinates LED output
import threading
import time
import RPi.GPIO as GPIO
import messagequeue
allLedClasses = []
configuredLedOutputs = []
STOPMSG='<!>STOP<!>'
def _compilePattern(patternStr):
pattern = []
for l in patternStr.split('\n'):
line = l.strip()
if line.startswith('On'):
pattern.append(True)
elif line.startswith('Off'):
pattern.append(False)
elif line.startswith('Wait'):
pattern.append(float(line[4:]))
else:
# ignore
pass
return pattern
defaultPattern = _compilePattern("""
On
Wait 1
Off
""")
suffixPatterns = {
'-': _compilePattern("""
On
Wait 2.2
Off"""),
'+': _compilePattern("""
On
Wait 0.5
Off
Wait 0.5
On
Wait 0.5
Off""")
}
def addLedOutput(outputInstance):
configuredLedOutputs.append(outputInstance)
class Leds74HC595:
def __init__(self, SER, SRCLK, RCLK, chrs):
"""
Use LEDs driven by a 74HC595-style shift register.
Assumes that OE and SRCLR are handled externally.
:param SER: pin number of the serial input pin (SER)
:param SRCLK: pin number of the shift register clock pin (SRCLK)
:param RCLK: pin number of the storate register clock pin (RCLK)
:param chrs: Action characters to map to the LEDs, LSB first. Length of this defines the number
of shifts before the storage is triggered.
"""
self.SER = SER
self.SRCLK = SRCLK
self.RCLK = RCLK
self.chrs = chrs[::-1] # reverse, because MSB needs to be pushed first
def setup(self):
"""Configure GPIO pins."""
for pin in (self.SER, self.SRCLK, self.RCLK):
GPIO.setup(pin, GPIO.OUT)
GPIO.output(pin, GPIO.LOW)
self.state = {}
for c in self.chrs:
self.state[c] = False
def output(self, chrs, on):
# update state
for c in chrs:
if c in self.state.keys():
self.state[c] = on
# now push to shift register
for c in self.chrs:
GPIO.output(self.SER, self.state[c])
GPIO.output(self.SRCLK, GPIO.HIGH)
GPIO.output(self.SRCLK, GPIO.LOW)
# commit
GPIO.output(self.RCLK, GPIO.HIGH)
GPIO.output(self.RCLK, GPIO.LOW)
def _ledOutputThread():
print "Starting 'LED output loop."
msg = messagequeue.leds.receive()
while msg != STOPMSG:
pattern = defaultPattern
suffix = msg[-1]
if suffix in suffixPatterns.keys():
pattern = suffixPatterns[suffix]
newMsg = None
for step in pattern:
if type(step) == bool:
for i in configuredLedOutputs:
i.output(msg, step)
else:
newMsg = messagequeue.leds.waitForMessage(step)
if newMsg != None:
break
if newMsg != None:
for i in configuredLedOutputs:
i.output(msg, False)
msg = newMsg
else:
msg = messagequeue.leds.receive()
def setup():
if len(configuredLedOutputs) > 0:
GPIO.setmode(GPIO.BOARD)
for i in configuredLedOutputs:
i.setup()
ledthread = threading.Thread(target=_ledOutputThread)
ledthread.start()
def stop():
messagequeue.leds.send(STOPMSG)
allLedClasses.append(Leds74HC595)