Skip to content

Commit 8434217

Browse files
committed
Add PixelSubStrip class to simplify working with multiple segments
The existing API is unchanged. A PixelSubStrip handles a subset of the pixels in a PixelStrip and can be created like so: strip = PixelStrip(...) strip1 = strip.createPixelSubStrip(0, num=10) # controls first 10 pixels strip2 = strip.createPixelSubStrip(10, num=10) # controls next 10 pixels Signed-off-by: David Greaves <[email protected]>
1 parent 29a99c0 commit 8434217

File tree

1 file changed

+106
-43
lines changed

1 file changed

+106
-43
lines changed

library/rpi_ws281x/rpi_ws281x.py

+106-43
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,15 @@ def __init__(self, num, pin, freq_hz=800000, dma=10, invert=False,
105105
# Grab the led data array.
106106
self._led_data = _LED_Data(self._channel, num)
107107

108+
# Create a PixelSubStrip and delegate these methods to it
109+
self.main_strip = self.PixelSubStrip(self, 0, num=num)
110+
self.setPixelColor = self.main_strip.setPixelColor
111+
self.setPixelColorRGB = self.main_strip.setPixelColorRGB
112+
self.setBrightness = self.main_strip.setBrightness
113+
self.getBrightness = self.main_strip.getBrightness
114+
self.getPixels = self.main_strip.getPixels
115+
self.getPixelColor = self.main_strip.getPixelColor
116+
108117
# Substitute for __del__, traps an exit condition and cleans up properly
109118
atexit.register(self._cleanup)
110119

@@ -137,55 +146,109 @@ def show(self):
137146
str_resp = ws.ws2811_get_return_t_str(resp)
138147
raise RuntimeError('ws2811_render failed with code {0} ({1})'.format(resp, str_resp))
139148

140-
def setPixelColor(self, n, color):
141-
"""Set LED at position n to the provided 24-bit color value (in RGB order).
142-
"""
143-
self._led_data[n] = color
144-
145-
def setPixelColorRGB(self, n, red, green, blue, white=0):
146-
"""Set LED at position n to the provided red, green, and blue color.
147-
Each color component should be a value from 0 to 255 (where 0 is the
148-
lowest intensity and 255 is the highest intensity).
149-
"""
150-
self.setPixelColor(n, Color(red, green, blue, white))
151-
152-
def getBrightness(self):
153-
return ws.ws2811_channel_t_brightness_get(self._channel)
154-
155-
def setBrightness(self, brightness):
156-
"""Scale each LED in the buffer by the provided brightness. A brightness
157-
of 0 is the darkest and 255 is the brightest.
158-
"""
159-
ws.ws2811_channel_t_brightness_set(self._channel, brightness)
160-
161-
def getPixels(self):
162-
"""Return an object which allows access to the LED display data as if
163-
it were a sequence of 24-bit RGB values.
164-
"""
165-
return self._led_data
166-
167149
def numPixels(self):
168150
"""Return the number of pixels in the display."""
169151
return ws.ws2811_channel_t_count_get(self._channel)
170152

171-
def getPixelColor(self, n):
172-
"""Get the 24-bit RGB color value for the LED at position n."""
173-
return self._led_data[n]
153+
def createPixelSubStrip(self, first, last=None, num=None):
154+
"""Create a PixelSubStrip starting with pixel `first`
155+
Either specify the `num` of pixels or the `last` pixel.
156+
157+
All the methods of a PixelSubStrip are available on PixelStrip
158+
objects.
174159
175-
def getPixelColorRGB(self, n):
176-
c = lambda: None
177-
setattr(c, 'r', self._led_data[n] >> 16 & 0xff)
178-
setattr(c, 'g', self._led_data[n] >> 8 & 0xff)
179-
setattr(c, 'b', self._led_data[n] & 0xff)
180-
return c
160+
Note: PixelSubStrips are not prevented from overlappping
161+
"""
162+
if last:
163+
if last > self.numPixels():
164+
raise self.InvalidStrip(f"Too many pixels ({last})."
165+
f"Strip only has {self.numPixels()}.")
166+
return self.PixelSubStrip(self, first, last=last)
167+
if num:
168+
if first + num > self.numPixels():
169+
raise self.InvalidStrip(f"Too many pixels ({first + num})."
170+
f"Strip only has {self.numPixels()}.")
171+
return self.PixelSubStrip(self, first, num=num)
172+
raise self.InvalidStrip("Need num or last to create a PixelSubStrip")
173+
174+
class InvalidStrip(Exception):
175+
pass
181176

182-
def getPixelColorRGBW(self, n):
183-
c = lambda: None
184-
setattr(c, 'w', self._led_data[n] >> 24 & 0xff)
185-
setattr(c, 'r', self._led_data[n] >> 16 & 0xff)
186-
setattr(c, 'g', self._led_data[n] >> 8 & 0xff)
187-
setattr(c, 'b', self._led_data[n] & 0xff)
188-
return c
177+
class PixelSubStrip:
178+
"""A PixelSubStrip handles a subset of the pixels in a PixelStrip
179+
180+
strip = PixelStrip(...)
181+
strip1 = strip.createPixelSubStrip(0, num=10) # controls first 10 pixels
182+
strip2 = strip.createPixelSubStrip(10, num=10) # controls next 10 pixels
183+
"""
184+
def __init__(self, strip, first, last=None, num=None):
185+
self.strip = strip
186+
self.first = first
187+
if last:
188+
self.last = last
189+
self.num = last - first
190+
elif num:
191+
self.last = first + num
192+
self.num = num
193+
else:
194+
raise self.InvalidStrip("Must specify number or last pixel to "
195+
"create a PixelSubStrip")
196+
197+
def setPixelColor(self, n, color):
198+
"""Set LED at position n to the provided 24-bit color value (in RGB order).
199+
"""
200+
self.strip._led_data[self.first + n] = color
201+
202+
def setPixelColorRGB(self, n, red, green, blue, white=0):
203+
"""Set LED at position n to the provided red, green, and blue color.
204+
Each color component should be a value from 0 to 255 (where 0 is the
205+
lowest intensity and 255 is the highest intensity).
206+
"""
207+
# No translation to n - do that in the called method
208+
self.setPixelColor(n, Color(red, green, blue, white))
209+
210+
def getBrightness(self):
211+
return ws.ws2811_channel_t_brightness_get(self.strip._channel)
212+
213+
def setBrightness(self, brightness):
214+
"""Scale each LED in the buffer by the provided brightness. A brightness
215+
of 0 is the darkest and 255 is the brightest.
216+
217+
This method affects all pixels in all PixelSubStrips.
218+
"""
219+
ws.ws2811_channel_t_brightness_set(self.strip._channel, brightness)
220+
221+
def getPixels(self):
222+
"""Return an object which allows access to the LED display data as if
223+
it were a sequence of 24-bit RGB values.
224+
"""
225+
return self.strip._led_data
226+
227+
def getPixelColor(self, n):
228+
"""Get the 24-bit RGB color value for the LED at position n."""
229+
return self.strip._led_data[self.first + n]
230+
231+
def getPixelColorRGB(self, n):
232+
c = lambda: None
233+
setattr(c, 'r', self.strip._led_data[self.first + n] >> 16 & 0xff)
234+
setattr(c, 'g', self.strip._led_data[self.first + n] >> 8 & 0xff)
235+
setattr(c, 'b', self.strip._led_data[self.first + n] & 0xff)
236+
return c
237+
238+
def numPixels(self):
239+
"""Return the number of pixels in the strip."""
240+
return self.num
241+
242+
def getPixelColorRGBW(self, n):
243+
c = lambda: None
244+
setattr(c, 'w', self.strip._led_data[self.first + n] >> 24 & 0xff)
245+
setattr(c, 'r', self.strip._led_data[self.first + n] >> 16 & 0xff)
246+
setattr(c, 'g', self.strip._led_data[self.first + n] >> 8 & 0xff)
247+
setattr(c, 'b', self.strip._led_data[self.first + n] & 0xff)
248+
return c
249+
250+
def show(self):
251+
self.strip.show()
189252

190253
# Shim for back-compatibility
191254
class Adafruit_NeoPixel(PixelStrip):

0 commit comments

Comments
 (0)