Skip to content

Commit 198f2aa

Browse files
authored
Merge pull request #106 from Neradoc/use-pixelbuf
Use pixelbuf
2 parents dcffa7c + e9bdb78 commit 198f2aa

File tree

3 files changed

+42
-100
lines changed

3 files changed

+42
-100
lines changed

adafruit_seesaw/neopixel.py

Lines changed: 35 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
====================================================
1010
"""
1111
import struct
12+
from adafruit_pixelbuf import PixelBuf
1213

1314
try:
1415
from micropython import const
@@ -30,18 +31,21 @@ def const(x):
3031
_NEOPIXEL_BUF = const(0x04)
3132
_NEOPIXEL_SHOW = const(0x05)
3233

34+
# try lower values if IO errors
35+
_OUTPUT_BUFFER_SIZE = const(24)
36+
3337
# Pixel color order constants
34-
RGB = (0, 1, 2)
38+
RGB = "RGB"
3539
"""Red Green Blue"""
36-
GRB = (1, 0, 2)
40+
GRB = "GRB"
3741
"""Green Red Blue"""
38-
RGBW = (0, 1, 2, 3)
42+
RGBW = "RGBW"
3943
"""Red Green Blue White"""
40-
GRBW = (1, 0, 2, 3)
44+
GRBW = "GRBW"
4145
"""Green Red Blue White"""
4246

4347

44-
class NeoPixel:
48+
class NeoPixel(PixelBuf):
4549
"""Control NeoPixels connected to a seesaw
4650
4751
:param ~adafruit_seesaw.seesaw.Seesaw seesaw: The device
@@ -62,108 +66,40 @@ def __init__(
6266
bpp=None,
6367
brightness=1.0,
6468
auto_write=True,
65-
pixel_order=None
69+
pixel_order="GRB"
6670
):
67-
# TODO: brightness not yet implemented.
6871
self._seesaw = seesaw
6972
self._pin = pin
70-
self.auto_write = auto_write
71-
self._n = n
72-
self._brightness = min(max(brightness, 0.0), 1.0)
73-
self._pixel_order = GRB if pixel_order is None else pixel_order
74-
self._bpp = len(self._pixel_order) if bpp is None else bpp
75-
if self._bpp != len(self._pixel_order):
76-
raise ValueError("Pixel order and bpp value do not agree.")
73+
if not pixel_order:
74+
pixel_order = GRB if bpp == 3 else GRBW
75+
elif isinstance(pixel_order, tuple):
76+
# convert legacy pixel order into PixelBuf pixel order
77+
order_list = ["RGBW"[order] for order in pixel_order]
78+
pixel_order = "".join(order_list)
79+
80+
super().__init__(
81+
size=n,
82+
byteorder=pixel_order,
83+
brightness=brightness,
84+
auto_write=auto_write,
85+
)
7786

7887
cmd = bytearray([pin])
7988
self._seesaw.write(_NEOPIXEL_BASE, _NEOPIXEL_PIN, cmd)
80-
cmd = struct.pack(">H", n * self._bpp)
89+
cmd = struct.pack(">H", n * self.bpp)
8190
self._seesaw.write(_NEOPIXEL_BASE, _NEOPIXEL_BUF_LENGTH, cmd)
82-
self._pre_brightness_color = [None] * n
83-
84-
@property
85-
def brightness(self):
86-
"""Overall brightness of the pixel"""
87-
return self._brightness
88-
89-
@brightness.setter
90-
def brightness(self, brightness):
91-
# pylint: disable=attribute-defined-outside-init
92-
self._brightness = min(max(brightness, 0.0), 1.0)
93-
94-
# Suppress auto_write while updating brightness.
95-
current_auto_write = self.auto_write
96-
self.auto_write = False
97-
for i in range(self._n):
98-
if self._pre_brightness_color[i] is not None:
99-
self[i] = self._pre_brightness_color[i]
100-
if current_auto_write:
101-
self.show()
102-
self.auto_write = current_auto_write
91+
self.output_buffer = bytearray(_OUTPUT_BUFFER_SIZE)
10392

104-
def deinit(self):
105-
pass
93+
def _transmit(self, buffer: bytearray) -> None:
94+
"""Update the pixels even if auto_write is False"""
10695

107-
def __len__(self):
108-
return self._n
109-
110-
def __setitem__(self, key, color):
111-
"""Set one pixel to a new value"""
112-
cmd = bytearray(2 + self._bpp)
113-
struct.pack_into(">H", cmd, 0, key * self._bpp)
114-
if isinstance(color, int):
115-
w = color >> 24
116-
r = (color >> 16) & 0xFF
117-
g = (color >> 8) & 0xFF
118-
b = color & 0xFF
119-
else:
120-
if self._bpp == 3:
121-
r, g, b = color
122-
else:
123-
r, g, b, w = color
124-
125-
self._pre_brightness_color[key] = color
126-
127-
# If all components are the same and we have a white pixel then use it
128-
# instead of the individual components.
129-
if self._bpp == 4 and r == g == b and w == 0:
130-
w = r
131-
r = 0
132-
g = 0
133-
b = 0
134-
135-
if self.brightness < 0.99:
136-
r = int(r * self.brightness)
137-
g = int(g * self.brightness)
138-
b = int(b * self.brightness)
139-
if self._bpp == 4:
140-
w = int(w * self.brightness)
141-
142-
# Store colors in correct slots
143-
cmd[2 + self._pixel_order[0]] = r
144-
cmd[2 + self._pixel_order[1]] = g
145-
cmd[2 + self._pixel_order[2]] = b
146-
if self._bpp == 4:
147-
cmd[2 + self._pixel_order[3]] = w
148-
149-
self._seesaw.write(_NEOPIXEL_BASE, _NEOPIXEL_BUF, cmd)
150-
if self.auto_write:
151-
self.show()
152-
153-
def __getitem__(self, key):
154-
pass
96+
step = _OUTPUT_BUFFER_SIZE - 2
97+
for i in range(0, len(buffer), step):
98+
self.output_buffer[0:2] = struct.pack(">H", i)
99+
self.output_buffer[2:] = buffer[i : i + step]
100+
self._seesaw.write(_NEOPIXEL_BASE, _NEOPIXEL_BUF, self.output_buffer)
155101

156-
def fill(self, color):
157-
"""Set all pixels to the same value"""
158-
# Suppress auto_write while filling.
159-
current_auto_write = self.auto_write
160-
self.auto_write = False
161-
for i in range(self._n):
162-
self[i] = color
163-
if current_auto_write:
164-
self.show()
165-
self.auto_write = current_auto_write
166-
167-
def show(self):
168-
"""Update the pixels even if auto_write is False"""
169102
self._seesaw.write(_NEOPIXEL_BASE, _NEOPIXEL_SHOW)
103+
104+
def deinit(self):
105+
pass

docs/conf.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@
2323
# Uncomment the below if you use native CircuitPython modules such as
2424
# digitalio, micropython and busio. List the modules you use. Without it, the
2525
# autodoc module docs will fail to generate with a warning.
26-
autodoc_mock_imports = ["adafruit_bus_device", "digitalio", "board"]
26+
autodoc_mock_imports = [
27+
"adafruit_bus_device",
28+
"adafruit_pixelbuf",
29+
"board",
30+
"digitalio",
31+
]
2732

2833
autodoc_default_flags = ["special-members", "members"]
2934

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
# SPDX-License-Identifier: Unlicense
44

55
adafruit-circuitpython-busdevice
6+
adafruit-circuitpython-pixelbuf
67
Adafruit-Blinka

0 commit comments

Comments
 (0)