36
36
__version__ = "0.0.0-auto.0"
37
37
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_DotStar.git"
38
38
39
+ START_HEADER_SIZE = 4
40
+
41
+ # Pixel color order constants
42
+ RGB = (0 , 1 , 2 )
43
+ RBG = (0 , 2 , 1 )
44
+ GRB = (1 , 0 , 2 )
45
+ GBR = (1 , 2 , 0 )
46
+ BRG = (2 , 0 , 1 )
47
+ BGR = (2 , 1 , 0 )
48
+
49
+
39
50
class DotStar :
40
51
"""
41
52
A sequence of dotstars.
@@ -46,6 +57,9 @@ class DotStar:
46
57
:param float brightness: Brightness of the pixels between 0.0 and 1.0
47
58
:param bool auto_write: True if the dotstars should immediately change when
48
59
set. If False, `show` must be called explicitly.
60
+ :param tuple pixel_order: Set the pixel order on the strip - different
61
+ strips implement this differently. If you send red, and it looks blue
62
+ or green on the strip, modify this! It should be one of the values above
49
63
50
64
51
65
Example for Gemma M0:
@@ -63,7 +77,7 @@ class DotStar:
63
77
time.sleep(2)
64
78
"""
65
79
66
- def __init__ (self , clock , data , n , * , brightness = 1.0 , auto_write = True ):
80
+ def __init__ (self , clock , data , n , * , brightness = 1.0 , auto_write = True , pixel_order = BGR ):
67
81
self ._spi = None
68
82
try :
69
83
self ._spi = busio .SPI (clock , MOSI = data )
@@ -77,19 +91,18 @@ def __init__(self, clock, data, n, *, brightness=1.0, auto_write=True):
77
91
self .cpin .direction = digitalio .Direction .OUTPUT
78
92
self .cpin .value = False
79
93
self ._n = n
80
- self .start_header_size = 4
81
94
# Supply one extra clock cycle for each two pixels in the strip.
82
95
self .end_header_size = n // 16
83
96
if n % 16 != 0 :
84
97
self .end_header_size += 1
85
- self ._buf = bytearray (n * 4 + self . start_header_size + self .end_header_size )
98
+ self ._buf = bytearray (n * 4 + START_HEADER_SIZE + self .end_header_size )
86
99
self .end_header_index = len (self ._buf ) - self .end_header_size
87
-
100
+ self . pixel_order = pixel_order
88
101
# Four empty bytes to start.
89
- for i in range (self . start_header_size ):
102
+ for i in range (START_HEADER_SIZE ):
90
103
self ._buf [i ] = 0x00
91
104
# Mark the beginnings of each pixel.
92
- for i in range (self . start_header_size , self .end_header_index , 4 ):
105
+ for i in range (START_HEADER_SIZE , self .end_header_index , 4 ):
93
106
self ._buf [i ] = 0xff
94
107
# 0xff bytes at the end.
95
108
for i in range (self .end_header_index , len (self ._buf )):
@@ -104,7 +117,7 @@ def __init__(self, clock, data, n, *, brightness=1.0, auto_write=True):
104
117
def deinit (self ):
105
118
"""Blank out the DotStars and release the resources."""
106
119
self .auto_write = False
107
- for i in range (self . start_header_size , self .end_header_index ):
120
+ for i in range (START_HEADER_SIZE , self .end_header_index ):
108
121
if i % 4 != 0 :
109
122
self ._buf [i ] = 0
110
123
self .show ()
@@ -124,24 +137,19 @@ def __repr__(self):
124
137
return "[" + ", " .join ([str (x ) for x in self ]) + "]"
125
138
126
139
def _set_item (self , index , value ):
127
- offset = index * 4 + self .start_header_size
128
- r = 0
129
- g = 0
130
- b = 0
140
+ offset = index * 4 + START_HEADER_SIZE
141
+ rgb = value
131
142
if isinstance (value , int ):
132
- r = value >> 16
133
- g = (value >> 8 ) & 0xff
134
- b = value & 0xff
135
- else :
136
- r , g , b = value
143
+ rgb = (value >> 16 , (value >> 8 ) & 0xff , value & 0xff )
144
+
137
145
# Each pixel starts with 0xFF, then red/green/blue. Although the data
138
146
# sheet suggests using a global brightness in the first byte, we don't
139
147
# do that because it causes further issues with persistence of vision
140
148
# projects.
141
149
self ._buf [offset ] = 0xff # redundant; should already be set
142
- self ._buf [offset + 1 ] = b
143
- self ._buf [offset + 2 ] = g
144
- self ._buf [offset + 3 ] = r
150
+ self ._buf [offset + 1 ] = rgb [ self . pixel_order [ 0 ]]
151
+ self ._buf [offset + 2 ] = rgb [ self . pixel_order [ 1 ]]
152
+ self ._buf [offset + 3 ] = rgb [ self . pixel_order [ 2 ]]
145
153
146
154
def __setitem__ (self , index , val ):
147
155
if isinstance (index , slice ):
@@ -164,14 +172,14 @@ def __getitem__(self, index):
164
172
out = []
165
173
for in_i in range (* index .indices (self ._n )):
166
174
out .append (
167
- tuple (self ._buf [in_i * 4 + (3 - i ) + self . start_header_size ] for i in range (3 )))
175
+ tuple (self ._buf [in_i * 4 + (3 - i ) + START_HEADER_SIZE ] for i in range (3 )))
168
176
return out
169
177
if index < 0 :
170
178
index += len (self )
171
179
if index >= self ._n or index < 0 :
172
180
raise IndexError
173
181
offset = index * 4
174
- return tuple (self ._buf [offset + (3 - i ) + self . start_header_size ]
182
+ return tuple (self ._buf [offset + (3 - i ) + START_HEADER_SIZE ]
175
183
for i in range (3 ))
176
184
177
185
def __len__ (self ):
@@ -217,10 +225,10 @@ def show(self):
217
225
if self .brightness < 1.0 :
218
226
buf = bytearray (self ._buf )
219
227
# Four empty bytes to start.
220
- for i in range (self . start_header_size ):
228
+ for i in range (START_HEADER_SIZE ):
221
229
buf [i ] = 0x00
222
- for i in range (self . start_header_size , self .end_header_index ):
223
- buf [i ] = self ._buf [i ] if i % 4 == 0 else int (self ._buf [i ] * self ._brightness )
230
+ for i in range (START_HEADER_SIZE , self .end_header_index ):
231
+ buf [i ] = self ._buf [i ] if i % 4 == 0 else int (self ._buf [i ] * self ._brightness )
224
232
# Four 0xff bytes at the end.
225
233
for i in range (self .end_header_index , len (buf )):
226
234
buf [i ] = 0xff
0 commit comments