Skip to content

Commit 266da29

Browse files
committed
Add SK9822 support
1 parent fe9109e commit 266da29

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

adafruit_dotstar.py

+21-7
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ class DotStar:
5959
:param tuple pixel_order: Set the pixel order on the strip - different
6060
strips implement this differently. If you send red, and it looks blue
6161
or green on the strip, modify this! It should be one of the values above
62-
62+
:param bool sk9822: True if using SK9822 LEDs which have constant current brightness
63+
control. If set, global brightness will always use on-strip control instead
64+
of local scaling. Using the 4th tuple value brightness control will overwrite
65+
this on a per-pixel level
6366
6467
Example for Gemma M0:
6568
@@ -76,7 +79,8 @@ class DotStar:
7679
time.sleep(2)
7780
"""
7881

79-
def __init__(self, clock, data, n, *, brightness=1.0, auto_write=True, pixel_order=BGR):
82+
def __init__(self, clock, data, n, *, brightness=1.0,
83+
auto_write=True, pixel_order=BGR, sk9822=False):
8084
self._spi = None
8185
try:
8286
self._spi = busio.SPI(clock, MOSI=data)
@@ -91,7 +95,10 @@ def __init__(self, clock, data, n, *, brightness=1.0, auto_write=True, pixel_ord
9195
self.cpin.value = False
9296
self._n = n
9397
# Supply one extra clock cycle for each two pixels in the strip.
94-
self.end_header_size = n // 16
98+
# plus an extra 32 bits for SK9822 compatibility
99+
# uses unified APA102 / SK9822 protocol from
100+
# https://cpldcpu.wordpress.com/2016/12/13/sk9822-a-clone-of-the-apa102/
101+
self.end_header_size = (n // 16) + 4
95102
if n % 16 != 0:
96103
self.end_header_size += 1
97104
self._buf = bytearray(n * 4 + START_HEADER_SIZE + self.end_header_size)
@@ -103,10 +110,11 @@ def __init__(self, clock, data, n, *, brightness=1.0, auto_write=True, pixel_ord
103110
# Mark the beginnings of each pixel.
104111
for i in range(START_HEADER_SIZE, self.end_header_index, 4):
105112
self._buf[i] = 0xff
106-
# 0xff bytes at the end.
113+
# 0x00 bytes at the end.
107114
for i in range(self.end_header_index, len(self._buf)):
108-
self._buf[i] = 0xff
115+
self._buf[i] = 0x00
109116
self._brightness = 1.0
117+
self._sk9822 = sk9822
110118
# Set auto_write to False temporarily so brightness setter does _not_
111119
# call show() while in __init__.
112120
self.auto_write = False
@@ -218,6 +226,11 @@ def brightness(self):
218226
@brightness.setter
219227
def brightness(self, brightness):
220228
self._brightness = min(max(brightness, 0.0), 1.0)
229+
if self._sk9822:
230+
brightness_byte = (32 - int(32 - brightness * 31) & 0b00011111) | LED_START
231+
for i in range(0, self._n * 4, 4):
232+
self._buf[i + START_HEADER_SIZE] = brightness_byte
233+
221234
if self.auto_write:
222235
self.show()
223236

@@ -247,7 +260,8 @@ def show(self):
247260
it may be done asynchronously."""
248261
# Create a second output buffer if we need to compute brightness
249262
buf = self._buf
250-
if self.brightness < 1.0:
263+
264+
if not self._sk9822 and self.brightness < 1.0:
251265
buf = bytearray(self._buf)
252266
# Four empty bytes to start.
253267
for i in range(START_HEADER_SIZE):
@@ -256,7 +270,7 @@ def show(self):
256270
buf[i] = self._buf[i] if i % 4 == 0 else int(self._buf[i] * self._brightness)
257271
# Four 0xff bytes at the end.
258272
for i in range(self.end_header_index, len(buf)):
259-
buf[i] = 0xff
273+
buf[i] = 0x00
260274

261275
if self._spi:
262276
self._spi.write(buf)

0 commit comments

Comments
 (0)