Skip to content

Commit 10db851

Browse files
authored
Merge pull request #70 from adafruit/revert-59-pixelbuf
Revert "_pixelbuf support"
2 parents 68388d0 + 096d079 commit 10db851

File tree

3 files changed

+124
-48
lines changed

3 files changed

+124
-48
lines changed

neopixel.py

+123-46
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
#
33
# Copyright (c) 2016 Damien P. George
44
# Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
5-
# Copyright (c) 2019 Carter Nelson
6-
# Copyright (c) 2019 Roy Hooper
75
#
86
# Permission is hereby granted, free of charge, to any person obtaining a copy
97
# of this software and associated documentation files (the "Software"), to deal
@@ -27,33 +25,28 @@
2725
`neopixel` - NeoPixel strip driver
2826
====================================================
2927
30-
* Author(s): Damien P. George, Scott Shawcroft, Carter Nelson, Roy Hooper
28+
* Author(s): Damien P. George & Scott Shawcroft
3129
"""
3230

31+
import math
32+
3333
import digitalio
3434
from neopixel_write import neopixel_write
35-
try:
36-
import _pixelbuf
37-
except ImportError:
38-
import adafruit_pypixelbuf as _pixelbuf
39-
4035

4136
__version__ = "0.0.0-auto.0"
4237
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel.git"
4338

44-
4539
# Pixel color order constants
46-
RGB = 'RGB'
40+
RGB = (0, 1, 2)
4741
"""Red Green Blue"""
48-
GRB = 'GRB'
42+
GRB = (1, 0, 2)
4943
"""Green Red Blue"""
50-
RGBW = 'RGBW'
44+
RGBW = (0, 1, 2, 3)
5145
"""Red Green Blue White"""
52-
GRBW = 'GRBW'
46+
GRBW = (1, 0, 2, 3)
5347
"""Green Red Blue White"""
5448

55-
56-
class NeoPixel(_pixelbuf.PixelBuf):
49+
class NeoPixel:
5750
"""
5851
A sequence of neopixels.
5952
@@ -64,7 +57,7 @@ class NeoPixel(_pixelbuf.PixelBuf):
6457
brightness
6558
:param bool auto_write: True if the neopixels should immediately change when set. If False,
6659
`show` must be called explicitly.
67-
:param str: Set the pixel color channel order. GRBW is set by default.
60+
:param tuple pixel_order: Set the pixel color channel order. GRBW is set by default.
6861
6962
Example for Circuit Playground Express:
7063
@@ -94,37 +87,28 @@ class NeoPixel(_pixelbuf.PixelBuf):
9487
pixels[::2] = [RED] * (len(pixels) // 2)
9588
time.sleep(2)
9689
"""
97-
bpp = None
98-
n = 0
99-
10090
def __init__(self, pin, n, *, bpp=3, brightness=1.0, auto_write=True, pixel_order=None):
101-
self.bpp = bpp
102-
self.n = n
103-
104-
if not pixel_order:
105-
pixel_order = GRB if bpp == 3 else GRBW
106-
else:
107-
self.bpp = bpp = len(pixel_order)
108-
if isinstance(pixel_order, tuple):
109-
order_chars = RGBW
110-
order = []
111-
for char_no, order in enumerate(pixel_order):
112-
order[pixel_order] = order_chars[char_no]
113-
pixel_order = ''.join(order)
114-
115-
super().__init__(n, bytearray(self.n * bpp),
116-
brightness=brightness,
117-
rawbuf=bytearray(self.n * bpp),
118-
byteorder=pixel_order,
119-
auto_write=auto_write)
120-
12191
self.pin = digitalio.DigitalInOut(pin)
12292
self.pin.direction = digitalio.Direction.OUTPUT
93+
self.n = n
94+
if pixel_order is None:
95+
self.order = GRBW
96+
self.bpp = bpp
97+
else:
98+
self.order = pixel_order
99+
self.bpp = len(self.order)
100+
self.buf = bytearray(self.n * self.bpp)
101+
# Set auto_write to False temporarily so brightness setter does _not_
102+
# call show() while in __init__.
103+
self.auto_write = False
104+
self.brightness = brightness
105+
self.auto_write = auto_write
123106

124107
def deinit(self):
125108
"""Blank out the NeoPixels and release the pin."""
126-
self.fill(0)
127-
self.show()
109+
for i in range(len(self.buf)):
110+
self.buf[i] = 0
111+
neopixel_write(self.pin, self.buf)
128112
self.pin.deinit()
129113

130114
def __enter__(self):
@@ -136,6 +120,100 @@ def __exit__(self, exception_type, exception_value, traceback):
136120
def __repr__(self):
137121
return "[" + ", ".join([str(x) for x in self]) + "]"
138122

123+
def _set_item(self, index, value):
124+
if index < 0:
125+
index += len(self)
126+
if index >= self.n or index < 0:
127+
raise IndexError
128+
offset = index * self.bpp
129+
r = 0
130+
g = 0
131+
b = 0
132+
w = 0
133+
if isinstance(value, int):
134+
if value>>24:
135+
raise ValueError("only bits 0->23 valid for integer input")
136+
r = value >> 16
137+
g = (value >> 8) & 0xff
138+
b = value & 0xff
139+
w = 0
140+
# If all components are the same and we have a white pixel then use it
141+
# instead of the individual components.
142+
if self.bpp == 4 and r == g and g == b:
143+
w = r
144+
r = 0
145+
g = 0
146+
b = 0
147+
elif (len(value) == self.bpp) or ((len(value) == 3) and (self.bpp == 4)):
148+
if len(value) == 3:
149+
r, g, b = value
150+
else:
151+
r, g, b, w = value
152+
else:
153+
raise ValueError("Color tuple size does not match pixel_order.")
154+
155+
self.buf[offset + self.order[0]] = r
156+
self.buf[offset + self.order[1]] = g
157+
self.buf[offset + self.order[2]] = b
158+
if self.bpp == 4:
159+
self.buf[offset + self.order[3]] = w
160+
161+
def __setitem__(self, index, val):
162+
if isinstance(index, slice):
163+
start, stop, step = index.indices(len(self.buf) // self.bpp)
164+
length = stop - start
165+
if step != 0:
166+
length = math.ceil(length / step)
167+
if len(val) != length:
168+
raise ValueError("Slice and input sequence size do not match.")
169+
for val_i, in_i in enumerate(range(start, stop, step)):
170+
self._set_item(in_i, val[val_i])
171+
else:
172+
self._set_item(index, val)
173+
174+
if self.auto_write:
175+
self.show()
176+
177+
def __getitem__(self, index):
178+
if isinstance(index, slice):
179+
out = []
180+
for in_i in range(*index.indices(len(self.buf) // self.bpp)):
181+
out.append(tuple(self.buf[in_i * self.bpp + self.order[i]]
182+
for i in range(self.bpp)))
183+
return out
184+
if index < 0:
185+
index += len(self)
186+
if index >= self.n or index < 0:
187+
raise IndexError
188+
offset = index * self.bpp
189+
return tuple(self.buf[offset + self.order[i]]
190+
for i in range(self.bpp))
191+
192+
def __len__(self):
193+
return len(self.buf) // self.bpp
194+
195+
@property
196+
def brightness(self):
197+
"""Overall brightness of the pixel"""
198+
return self._brightness
199+
200+
@brightness.setter
201+
def brightness(self, brightness):
202+
# pylint: disable=attribute-defined-outside-init
203+
self._brightness = min(max(brightness, 0.0), 1.0)
204+
if self.auto_write:
205+
self.show()
206+
207+
def fill(self, color):
208+
"""Colors all pixels the given ***color***."""
209+
auto_write = self.auto_write
210+
self.auto_write = False
211+
for i, _ in enumerate(self):
212+
self[i] = color
213+
if auto_write:
214+
self.show()
215+
self.auto_write = auto_write
216+
139217
def write(self):
140218
""".. deprecated: 1.0.0
141219
@@ -148,8 +226,7 @@ def show(self):
148226
149227
The colors may or may not be showing after this function returns because
150228
it may be done asynchronously."""
151-
neopixel_write(self.pin, self.buf)
152-
153-
def fill(self, color):
154-
"""Colors all pixels the given ***color***."""
155-
_pixelbuf.fill(self, color)
229+
if self.brightness > 0.99:
230+
neopixel_write(self.pin, self.buf)
231+
else:
232+
neopixel_write(self.pin, bytearray([int(i * self.brightness) for i in self.buf]))

requirements.txt

-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
Adafruit-Blinka
2-
adafruit-circuitpython-pypixelbuf

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
author='Adafruit Industries & Damien P. George',
3535
author_email='[email protected]',
3636

37-
install_requires=['Adafruit-Blinka', 'adafruit-circuitpython-pypixelbuf'],
37+
install_requires=['Adafruit-Blinka'],
3838

3939
# Choose your license
4040
license='MIT',

0 commit comments

Comments
 (0)