/
LED_LPD8806.py
237 lines (217 loc) · 8.38 KB
/
LED_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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Python SPI for LPD8806 driven LED strip:
# JGronowski
# First Uploaded: 2015-12-30
# Last Updated: 2016-01-17
#
# Code inspired by:
# ----------------
# github path:
# Adafruit-Raspberry-Pi-Python-Code/Adafruit_LEDpixels/Adafruit_LEDpixels.py
# and the article:
# http://mooresclouddev.markpesce.com/2012/10/18/about-lpd8806-based-rgb-led-strips/
#
# LPD8806 Hardware Examples:
# -----------------
# Digital RGB LED Weatherproof Strip - LPD8806 x 48 LED:
# https://www.adafruit.com/products/1948
# Digital RGB LED Weatherproof Strip - LPD8806 32 LED:
# https://www.adafruit.com/products/306
#
# Usage Notes:
# -----------
# The LPD8806 can be run from a SPI bus using just the SI (data in) and
# SCK (clock) pins. Keep in mind that the LPD8806 cannot share the SPI bus
# with other devices, because of the likelihood of data collisions. True
# SPI devices on the bus will pay attention to the CS (chip select) pin
# signal should not get confused by communication intended for the LED
# strip. The LPD8806 has no device id and will respond to all data on SI.
# The LPD8806 expects three bytes for each LED on the strip--one byte for
# each color component (RGB) of each LED. The first byte corresponds to
# the brightness of the Green light in the first LED. The second byte is Red,
# and the third byte is Blue. The first bit (MSB) of each byte indicates
# whether the subsequent 7 bits should be shifted on to the next LPD8806
# or be held for the current LPD8806. Consiquently, I am using
# 0x00, 0x00, 0x00 to prep the LED strip for new color data. Color data
# ranges from 0x80 0x80 0x80 (all colors off for 1 RGB LED) to
# 0xFF 0xFF 0xFF (all colors full on making 1 RGB LED turn white).
#
# Hardware Setup:
# --------------
# WARNING: Be sure to use logic-level translation on SI (P9_18) and SCK (P9_22),
# because the LPD8806 appears to have an internal pull-up to 5V on both pins!
# The 5 meter LED strip that I got from Adafruit came with double power and
# ground connections (one set is part of the header and one set is loose).
# Connect the extra power and GND pins from the LED strip to a barrel jack.
# https://www.adafruit.com/products/369
# The barrel jack can be used to power the LED strip and the BBB.
# Before plugging the power supply in, use some additional wire to
# connect the strip's terminal to the BBB P9 header pins as above as
# described in the below connection list, and optionally connect the DC5V+ pin
# to the BBB P9_5 pin or P9_6 pin which will supply 5V power to the BBB (these
# are VDD_5V). A 5V 10A power supply from Adafruit is used for the 5 meter strip.
# https://www.adafruit.com/products/658
# A 5V 2A power supply might be good enough for just 1 meter. Be careful
# not to brown out the BBB by turning too many LED's white (all RGB on)
# at the same time if the power supply cannot provide enough current.
#
# BBB pin connections:
# -------------------
# P9_1 (GND) = Power supply GND
# P9_2 (GND) = GND on LPD8806 LED strip
# P9_17 (CS) = N/A (a SPI pin not used by LPD8806)
# P9_18 (SI) = DAT on LDP8806 LED strip (yellow) <-- Remember to use logic-level translation! BBB is 3V, LPD8806 is 5V.
# P9_21 (SO) = N/A (a SPI pin not used by LPD8806)
# P9_22 (SCK) = CLK on the LDP*806 LED strip (green) <-- Remember to use logic-level translation!
#
from Adafruit_BBIO.SPI import SPI
#import Adafruit_BBIO.GPIO as GPIO
import time # useful for wait delay statements
global pixels
class LED_LPD8806(object):
# Constructor
def __init__(self):
self.spi = SPI(0,0) #/dev/spidev1.0 (be sure to run Python with su if 'no permission'
self.spi.msh=1000000 #SPI clock set to 1MHz (slowed from 10MHz for better stability across setups)
self.spi.bpw = 8 # bits per word
self.spi.threewire = False # not half-duplex
self.spi.lsbfirst = False # we want MSB first
self.spi.mode = 0 # options are modes 0 through 3
self.spi.cshigh = False # we want chip select to be active low
self.spi.open(0,0) # make it so
time.sleep(0.05)
def setup(self, led_pixels, debug=False):
if (debug):
print "Initializing LED strip"
global pixels
pixels = [[0x80 for x in range(3)] for y in range(led_pixels)]
for i in range(led_pixels):
pixels[i]=[0x00, 0x00, 0x00]
# Define LED functions:
# --------------------
# Update pixel display with a given delay time between pixel updates:
def writestrip(self, delay):
if (delay < 0):
delay = 0
for i in range(len(pixels)):
self.spi.writebytes([0x00, 0x00, 0x00]) #prepare write
for i in range(len(pixels)):
self.spi.writebytes(pixels[i]) #write colors to pixels
time.sleep(delay)
# Turn off all LEDs:
def clearstrip(self):
global pixels
for i in range(len(pixels)):
self.spi.writebytes([0x00, 0x00, 0x00]) #prepare write
for i in range(len(pixels)):
pixels[i] = [0x80, 0x80, 0x80]
self.writestrip(0)
# Set an individual pixel to a specific color (to display later):
def setpixelcolor(self, n, g, r, b):
global pixels
if (n >= len(pixels)):
return
if (n < 0):
return
if (g > 0xFF):
g = 0xFF
if (g < 0x80):
g = 0x80
if (r > 0xFF):
r = 0xFF
if (r < 0x80):
r = 0x80
if (b > 0xFF):
b = 0xFF
if (b < 0x80):
b = 0x80
pixels[n] = [g, r, b]
# Update display with warmer colors (more red light) by a specified amount with a delay between pixels
def warmstrip(self, warmth, delay):
global pixels
if (delay < 0):
delay = 0
for n in range(len(pixels)):
if((pixels[n][1] + warmth) < 0x80):
pixels[n][1] = 0x80
elif((pixels[n][2] + warmth) > 0xFF):
pixels[n][1] = 0xFF
else:
pixels[n][1] = pixels[n][1]+warmth
self.writestrip(delay)
# Update display with cooler colors (more blue) by a specified amount with a delay between each pixel
def coolstrip(self, coolfactor, delay):
global pixels
if (delay < 0):
delay = 0
for n in range(len(pixels)):
if((pixels[n][2] + coolfactor) < 0x80):
pixels[n][2] = 0x80
elif((pixels[n][2] + coolfactor) > 0xFF):
pixels[n][2] = 0xFF
else:
pixels[n][2] = pixels[n][2]+coolfactor
self.writestrip(delay)
# Update display with greener colors by a specified amount with a set delay between each pixel
def greenstrip(self, lushness, delay):
global pixels
if (delay < 0):
delay = 0
for n in range(len(pixels)):
if((pixels[n][0] + lushness) < 0x80):
pixels[n][0] = 0x80
else:
pixels[n][0] = pixels[n][0]+lushness
self.writestrip(delay)
# Update display with brighter (whiter) light by specified amount with a set delay between pixel updates
def brightenstrip(self, brightness, delay):
global pixels
if (delay < 0):
delay = 0
for n in range(len(pixels)):
if((pixels[n][0] + brightness) < 0x80):
pixels[n][0] = 0x80
elif((pixels[n][0] + brightness) > 0xFF):
pixels[n][0] = 0xFF
else:
pixels[n][0] = pixels[n][0]+brightness
if((pixels[n][1] + brightness) < 0x80):
pixels[n][1] = 0x80
elif((pixels[n][1] + brightness) > 0xFF):
pixels[n][1] = 0xFF
else:
pixels[n][1] = pixels[n][1]+brightness
if((pixels[n][2] + brightness) < 0x80):
pixels[n][2] = 0x80
elif((pixels[n][2] + brightness) > 0xFF):
pixels[n][2] = 0xFF
else:
pixels[n][2] = pixels[n][2]+brightness
self.writestrip(delay)
# Darken display (less light) by specified amount with a set delay between pixel updates
def dimstrip(self, dimness, delay):
global pixels
if (delay < 0):
delay = 0
for n in range(len(pixels)):
if((pixels[n][0] - dimness) < 0x80):
pixels[n][0] = 0x80
elif((pixels[n][0] - dimness) > 0xFF):
pixels[n][0] = 0xFF
else:
pixels[n][0] = pixels[n][0]-dimness
if((pixels[n][1] - dimness) < 0x80):
pixels[n][1] = 0x80
elif((pixels[n][1] - dimness) > 0xFF):
pixels[n][1] = 0xFF
else:
pixels[n][1] = pixels[n][1]-dimness
if((pixels[n][2] - dimness) < 0x80):
pixels[n][2] = 0x80
elif((pixels[n][2] - dimness) > 0xFF):
pixels[n][2] = 0xFF
else:
pixels[n][2] = pixels[n][2]-dimness
self.writestrip(delay)
#spi.close() # done