@@ -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,9 @@ 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 https://cpldcpu.wordpress.com/2016/12/13/sk9822-a-clone-of-the-apa102/
100
+ self .end_header_size = (n // 16 ) + 4
95
101
if n % 16 != 0 :
96
102
self .end_header_size += 1
97
103
self ._buf = bytearray (n * 4 + START_HEADER_SIZE + self .end_header_size )
@@ -103,10 +109,11 @@ def __init__(self, clock, data, n, *, brightness=1.0, auto_write=True, pixel_ord
103
109
# Mark the beginnings of each pixel.
104
110
for i in range (START_HEADER_SIZE , self .end_header_index , 4 ):
105
111
self ._buf [i ] = 0xff
106
- # 0xff bytes at the end.
112
+ # 0x00 bytes at the end.
107
113
for i in range (self .end_header_index , len (self ._buf )):
108
- self ._buf [i ] = 0xff
114
+ self ._buf [i ] = 0x00
109
115
self ._brightness = 1.0
116
+ self ._sk9822 = SK9822
110
117
# Set auto_write to False temporarily so brightness setter does _not_
111
118
# call show() while in __init__.
112
119
self .auto_write = False
@@ -157,7 +164,7 @@ def _set_item(self, index, value):
157
164
if isinstance (value , int ):
158
165
rgb = (value >> 16 , (value >> 8 ) & 0xff , value & 0xff )
159
166
160
- if len (value ) == 4 :
167
+ if len (rgb ) == 4 :
161
168
brightness = value [3 ]
162
169
# Ignore value[3] below.
163
170
else :
@@ -218,6 +225,11 @@ def brightness(self):
218
225
@brightness .setter
219
226
def brightness (self , brightness ):
220
227
self ._brightness = min (max (brightness , 0.0 ), 1.0 )
228
+ if self ._sk9822 :
229
+ brightness_byte = (32 - int (32 - brightness * 31 ) & 0b00011111 ) | LED_START
230
+ for i in range (0 , self ._n * 4 , 4 ):
231
+ self ._buf [i + START_HEADER_SIZE ] = brightness_byte
232
+
221
233
if self .auto_write :
222
234
self .show ()
223
235
@@ -247,7 +259,8 @@ def show(self):
247
259
it may be done asynchronously."""
248
260
# Create a second output buffer if we need to compute brightness
249
261
buf = self ._buf
250
- if self .brightness < 1.0 :
262
+
263
+ if not self ._sk9822 and self .brightness < 1.0 :
251
264
buf = bytearray (self ._buf )
252
265
# Four empty bytes to start.
253
266
for i in range (START_HEADER_SIZE ):
@@ -256,7 +269,7 @@ def show(self):
256
269
buf [i ] = self ._buf [i ] if i % 4 == 0 else int (self ._buf [i ] * self ._brightness )
257
270
# Four 0xff bytes at the end.
258
271
for i in range (self .end_header_index , len (buf )):
259
- buf [i ] = 0xff
272
+ buf [i ] = 0x00
260
273
261
274
if self ._spi :
262
275
self ._spi .write (buf )
0 commit comments