@@ -59,7 +59,10 @@ class DotStar:
59
59
:param tuple pixel_order: Set the pixel order on the strip - different
60
60
strips implement this differently. If you send red, and it looks blue
61
61
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
63
66
64
67
Example for Gemma M0:
65
68
@@ -76,7 +79,8 @@ class DotStar:
76
79
time.sleep(2)
77
80
"""
78
81
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 ):
80
84
self ._spi = None
81
85
try :
82
86
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
91
95
self .cpin .value = False
92
96
self ._n = n
93
97
# 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
95
102
if n % 16 != 0 :
96
103
self .end_header_size += 1
97
104
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
103
110
# Mark the beginnings of each pixel.
104
111
for i in range (START_HEADER_SIZE , self .end_header_index , 4 ):
105
112
self ._buf [i ] = 0xff
106
- # 0xff bytes at the end.
113
+ # 0x00 bytes at the end.
107
114
for i in range (self .end_header_index , len (self ._buf )):
108
- self ._buf [i ] = 0xff
115
+ self ._buf [i ] = 0x00
109
116
self ._brightness = 1.0
117
+ self ._sk9822 = sk9822
110
118
# Set auto_write to False temporarily so brightness setter does _not_
111
119
# call show() while in __init__.
112
120
self .auto_write = False
@@ -218,6 +226,11 @@ def brightness(self):
218
226
@brightness .setter
219
227
def brightness (self , brightness ):
220
228
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
+
221
234
if self .auto_write :
222
235
self .show ()
223
236
@@ -247,7 +260,8 @@ def show(self):
247
260
it may be done asynchronously."""
248
261
# Create a second output buffer if we need to compute brightness
249
262
buf = self ._buf
250
- if self .brightness < 1.0 :
263
+
264
+ if not self ._sk9822 and self .brightness < 1.0 :
251
265
buf = bytearray (self ._buf )
252
266
# Four empty bytes to start.
253
267
for i in range (START_HEADER_SIZE ):
@@ -256,7 +270,7 @@ def show(self):
256
270
buf [i ] = self ._buf [i ] if i % 4 == 0 else int (self ._buf [i ] * self ._brightness )
257
271
# Four 0xff bytes at the end.
258
272
for i in range (self .end_header_index , len (buf )):
259
- buf [i ] = 0xff
273
+ buf [i ] = 0x00
260
274
261
275
if self ._spi :
262
276
self ._spi .write (buf )
0 commit comments