9
9
====================================================
10
10
"""
11
11
import struct
12
+ from adafruit_pixelbuf import PixelBuf
12
13
13
14
try :
14
15
from micropython import const
@@ -30,18 +31,21 @@ def const(x):
30
31
_NEOPIXEL_BUF = const (0x04 )
31
32
_NEOPIXEL_SHOW = const (0x05 )
32
33
34
+ # try lower values if IO errors
35
+ _OUTPUT_BUFFER_SIZE = const (24 )
36
+
33
37
# Pixel color order constants
34
- RGB = ( 0 , 1 , 2 )
38
+ RGB = "RGB"
35
39
"""Red Green Blue"""
36
- GRB = ( 1 , 0 , 2 )
40
+ GRB = "GRB"
37
41
"""Green Red Blue"""
38
- RGBW = ( 0 , 1 , 2 , 3 )
42
+ RGBW = "RGBW"
39
43
"""Red Green Blue White"""
40
- GRBW = ( 1 , 0 , 2 , 3 )
44
+ GRBW = "GRBW"
41
45
"""Green Red Blue White"""
42
46
43
47
44
- class NeoPixel :
48
+ class NeoPixel ( PixelBuf ) :
45
49
"""Control NeoPixels connected to a seesaw
46
50
47
51
:param ~adafruit_seesaw.seesaw.Seesaw seesaw: The device
@@ -62,108 +66,40 @@ def __init__(
62
66
bpp = None ,
63
67
brightness = 1.0 ,
64
68
auto_write = True ,
65
- pixel_order = None
69
+ pixel_order = "GRB"
66
70
):
67
- # TODO: brightness not yet implemented.
68
71
self ._seesaw = seesaw
69
72
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
+ )
77
86
78
87
cmd = bytearray ([pin ])
79
88
self ._seesaw .write (_NEOPIXEL_BASE , _NEOPIXEL_PIN , cmd )
80
- cmd = struct .pack (">H" , n * self ._bpp )
89
+ cmd = struct .pack (">H" , n * self .bpp )
81
90
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 )
103
92
104
- def deinit (self ) :
105
- pass
93
+ def _transmit (self , buffer : bytearray ) -> None :
94
+ """Update the pixels even if auto_write is False"""
106
95
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 )
155
101
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"""
169
102
self ._seesaw .write (_NEOPIXEL_BASE , _NEOPIXEL_SHOW )
103
+
104
+ def deinit (self ):
105
+ pass
0 commit comments