forked from Sh4d/LPD8806
-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathLPD8806.py
executable file
·148 lines (115 loc) · 4.79 KB
/
LPD8806.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
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env python
from color import Color, ColorHSV
"""
LPD8806.py: Raspberry Pi library for LPD8806 based RGB light strips
Initial code from: https://github.com/Sh4d/LPD8806
Provides the ability to drive a LPD8806 based strand of RGB leds from the
Raspberry Pi
Colors are provided as RGB and converted internally to the strip's 7 bit
values.
Wiring:
Pi MOSI -> Strand DI
Pi SCLK -> Strand CI
Most strips use around 10W per meter (for ~32 LEDs/m) or 2A at 5V.
The Raspberry Pi cannot even come close to this so a larger power supply is required, however, due to voltage loss along long runs you will need to put in a new power supply at least every 5 meters. Technically you can power the Raspberry Pi through the GPIO pins and use the same supply as the strips, but I would recommend just using the USB power as it's a much safer option.
Also, while it *should* work without it to be safe you should add a level converter between the Raspberry Pi and the strip's data lines. This will also help you have longer runs.
Example:
>> import LPD8806
>> led = LPD8806.LEDStrip()
>> led.fill(255, 0, 0)
"""
#Not all LPD8806 strands are created equal.
#Some, like Adafruit's use GRB order and the other common order is GRB
#Library defaults to GRB but you can call strand.setChannelOrder(ChannelOrder)
#to set the order your strands use
class ChannelOrder:
RGB = [0,1,2] #Probably not used, here for clarity
GRB = [1,0,2] #Strands from Adafruit and some others (default)
BRG = [1,2,0] #Strands from many other manufacturers
class LEDStrip:
def __init__(self, leds, dev="/dev/spidev0.0"):
#Variables:
# leds -- strand size
# dev -- spi device
self.c_order = ChannelOrder.GRB
self.dev = dev
self.spi = file(self.dev, "wb")
self.leds = leds
self.lastIndex = self.leds - 1
self.gamma = bytearray(256)
self.buffer = [0 for x in range(self.leds + 1)]
self.masterBrightness = 1.0
for led in range(self.leds):
self.buffer[led] = bytearray(3)
for i in range(256):
# Color calculations from
# http://learn.adafruit.com/light-painting-with-raspberry-pi
self.gamma[i] = 0x80 | int(
pow(float(i) / 255.0, 2.5) * 127.0 + 0.5
)
#Allows for easily using LED strands with different channel orders
def setChannelOrder(self, order):
self.c_order = order
#Set the master brightness for the LEDs 0.0 - 1.0
def setMasterBrightness(self, bright):
if(bright > 1.0 or bright < 0.0):
raise ValueError('Brightness must be between 0.0 and 1.0')
self.masterBrightness = bright
#Push new data to strand
def update(self):
for x in range(self.leds):
self.spi.write(self.buffer[x])
self.spi.flush()
self.spi.write(bytearray(b'\x00\x00\x00')) #zero fill the last to prevent stray colors at the end
self.spi.write(bytearray(b'\x00'))
self.spi.flush()
#Fill the strand (or a subset) with a single color using a Color object
def fill(self, color, start=0, end=0):
if start < 0:
start = 0
if end == 0 or end > self.lastIndex:
end = self.lastIndex
for led in range(start, end + 1): #since 0-index include end in range
self.__set_internal(led, color)
#Fill the strand (or a subset) with a single color using RGB values
def fillRGB(self, r, g, b, start=0, end=0):
self.fill(Color(r, g, b), start, end)
#Fill the strand (or a subset) with a single color using HSV values
def fillHSV(self, h, s, v, start=0, end=0):
self.fill(ColorHSV(h, s, v).get_color_rgb(), start, end)
#Fill the strand (or a subset) with a single color using a Hue value.
#Saturation and Value components of HSV are set to max.
def fillHue(self, hue, start=0, end=0):
self.fill(ColorHSV(hue).get_color_rgb(), start, end)
def fillOff(self, start=0, end=0):
self.fillRGB(0, 0, 0, start, end)
#internal use only. sets pixel color
def __set_internal(self, pixel, color):
if(pixel < 0 or pixel > self.lastIndex):
return; #don't go out of bounds
self.buffer[pixel][self.c_order[0]] = self.gamma[int(color.r * self.masterBrightness)]
self.buffer[pixel][self.c_order[1]] = self.gamma[int(color.g * self.masterBrightness)]
self.buffer[pixel][self.c_order[2]] = self.gamma[int(color.b * self.masterBrightness)]
#Set single pixel to Color value
def set(self, pixel, color):
self.__set_internal(pixel, color)
#Set single pixel to RGB value
def setRGB(self, pixel, r, g, b):
color = Color(r, g, b)
self.set(pixel, color)
#Set single pixel to HSV value
def setHSV(self, pixel, h, s, v):
self.set(pixel, ColorHSV(h, s, v).get_color_rgb())
#Set single pixel to Hue value.
#Saturation and Value components of HSV are set to max.
def setHue(self, pixel, hue):
self.set(pixel, ColorHSV(hue).get_color_rgb())
#turns off the desired pixel
def setOff(self, pixel):
self.setRGB(pixel, 0, 0, 0)
#Turn all LEDs off.
def all_off(self):
self.fillOff()
self.update()
self.fillOff()
self.update()