Skip to content

Commit 097a34f

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 The indentation in this commit makes the diff much easier to review. Whitespace only commit follows Signed-off-by: David Greaves <[email protected]>
1 parent 6f144bb commit 097a34f

File tree

2 files changed

+80
-10
lines changed

2 files changed

+80
-10
lines changed

library/rpi_ws281x/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# New canonical package, to support `import rpi_ws281x`
2-
from .rpi_ws281x import PixelStrip, Adafruit_NeoPixel, Color, RGBW, ws
2+
from .rpi_ws281x import PixelStrip, InvalidStrip, Adafruit_NeoPixel, Color, RGBW, ws
33
from _rpi_ws281x import *
44

55
__version__ = '5.0.0'

library/rpi_ws281x/rpi_ws281x.py

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ def __init__(self, num, pin, freq_hz=800000, dma=10, invert=False,
4848
800khz), dma, the DMA channel to use (default 10), invert, a boolean
4949
specifying if the signal line should be inverted (default False), and
5050
channel, the PWM channel to use (defaults to 0).
51+
52+
All the methods of a PixelSubStrip are available on PixelStrip
53+
objects.
5154
"""
5255

5356
if gamma is None:
@@ -89,6 +92,17 @@ def __init__(self, num, pin, freq_hz=800000, dma=10, invert=False,
8992

9093
self.size = num
9194

95+
# Create a PixelSubStrip and delegate these methods to it
96+
self.main_strip = self.PixelSubStrip(self, 0, num=num)
97+
self.setPixelColor = self.main_strip.setPixelColor
98+
self.setPixelColorRGB = self.main_strip.setPixelColorRGB
99+
self.setBrightness = self.main_strip.setBrightness
100+
self.getBrightness = self.main_strip.getBrightness
101+
self.getPixels = self.main_strip.getPixels
102+
self.getPixelColor = self.main_strip.getPixelColor
103+
self.getPixelColorRGB = self.main_strip.getPixelColorRGB
104+
self.getPixelColorRGBW = self.main_strip.getPixelColorRGBW
105+
92106
# Substitute for __del__, traps an exit condition and cleans up properly
93107
atexit.register(self._cleanup)
94108

@@ -126,6 +140,10 @@ def __setitem__(self, pos, value):
126140
def __len__(self):
127141
return ws.ws2811_channel_t_count_get(self._channel)
128142

143+
def numPixels(self):
144+
"""Return the number of pixels in the display."""
145+
return len(self)
146+
129147
def _cleanup(self):
130148
# Clean up memory used by the library when not needed anymore.
131149
if self._leds is not None:
@@ -155,46 +173,98 @@ def show(self):
155173
str_resp = ws.ws2811_get_return_t_str(resp)
156174
raise RuntimeError('ws2811_render failed with code {0} ({1})'.format(resp, str_resp))
157175

176+
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+
strip2[5] will access the 15th pixel
185+
"""
186+
187+
def __init__(self, strip, first, last=None, num=None):
188+
self.strip = strip
189+
if first < 0:
190+
raise InvalidStrip(f"First pixel is negative ({first}).")
191+
if first > len(strip):
192+
raise InvalidStrip(f"First pixel is too big ({first})."
193+
f"Strip only has {len(strip)}.")
194+
self.first = first
195+
if last:
196+
if last < 0:
197+
raise InvalidStrip(f"Last pixel is negative ({last}).")
198+
if last > len(strip):
199+
raise InvalidStrip(f"Too many pixels ({last})."
200+
f"Strip only has {len(strip)}.")
201+
self.last = last
202+
self.num = last - first
203+
elif num:
204+
if num < 0:
205+
raise InvalidStrip(f"number of pixels is negative ({num}).")
206+
if first + num > len(strip):
207+
raise InvalidStrip(f"Too many pixels (last would be {first + num})."
208+
f"Strip only has {len(strip)}.")
209+
self.last = first + num
210+
self.num = num
211+
else:
212+
raise InvalidStrip("Must specify number or last pixel to "
213+
"create a PixelSubStrip")
214+
215+
def __len__(self):
216+
return self.num
217+
158218
def setPixelColor(self, n, color):
159219
"""Set LED at position n to the provided 24-bit color value (in RGB order).
160220
"""
161-
self[n] = color
221+
self.strip[self.first + n] = color
162222

163223
def setPixelColorRGB(self, n, red, green, blue, white=0):
164224
"""Set LED at position n to the provided red, green, and blue color.
165225
Each color component should be a value from 0 to 255 (where 0 is the
166226
lowest intensity and 255 is the highest intensity).
167227
"""
228+
# Translation to n done in setPixelColor
168229
self.setPixelColor(n, Color(red, green, blue, white))
169230

170231
def getBrightness(self):
171-
return ws.ws2811_channel_t_brightness_get(self._channel)
232+
return ws.ws2811_channel_t_brightness_get(self.strip._channel)
172233

173234
def setBrightness(self, brightness):
174235
"""Scale each LED in the buffer by the provided brightness. A brightness
175236
of 0 is the darkest and 255 is the brightest.
237+
238+
This method affects all pixels in all PixelSubStrips.
176239
"""
177-
ws.ws2811_channel_t_brightness_set(self._channel, brightness)
240+
ws.ws2811_channel_t_brightness_set(self.strip._channel, brightness)
178241

179242
def getPixels(self):
180243
"""Return an object which allows access to the LED display data as if
181244
it were a sequence of 24-bit RGB values.
182245
"""
183-
return self[:]
246+
return self.strip[self.first:self.last]
184247

185248
def numPixels(self):
186-
"""Return the number of pixels in the display."""
187-
return len(self)
249+
"""Return the number of pixels in the strip."""
250+
return self.num
188251

189252
def getPixelColor(self, n):
190253
"""Get the 24-bit RGB color value for the LED at position n."""
191-
return self[n]
254+
return self.strip[self.first + n]
192255

193256
def getPixelColorRGB(self, n):
194-
return RGBW(self[n])
257+
return RGBW(self.strip[self.first + n])
195258

196259
def getPixelColorRGBW(self, n):
197-
return RGBW(self[n])
260+
return RGBW(self.strip[self.first + n])
261+
262+
def show(self):
263+
self.strip.show()
264+
265+
266+
class InvalidStrip(Exception):
267+
pass
198268

199269
# Shim for back-compatibility
200270
class Adafruit_NeoPixel(PixelStrip):

0 commit comments

Comments
 (0)