Skip to content

Commit 21310b2

Browse files
committed
Add support for pixelbuf
1 parent 694fdec commit 21310b2

File tree

7 files changed

+92
-137
lines changed

7 files changed

+92
-137
lines changed

README.rst

+1-45
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ It should be a float. For example, (0xFF,0,0, 1.0) is the brightest red possible
2626

2727
.. note:: The int hex API represents the brightness of the white pixel when
2828
present by setting the RGB channels to identical values. For example, full
29-
white is 0xffffff but is actually (0xff, 0xff, 0xff) in the tuple syntax.
29+
white is 0xffffff but is actually (0xff, 0xff, 0xff) in the tuple syntax.
3030

3131
Dependencies
3232
=============
@@ -78,50 +78,6 @@ This example demonstrates the library with the single built-in DotStar on the
7878
pixels = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
7979
pixels[0] = (10, 0, 0)
8080
81-
82-
This example demonstrates the library with the DotStar Feather Wing and bounces Blinka.
83-
84-
`Feather M4 Express <https://www.adafruit.com/product/3857>`_ and
85-
`DotStar FeatherWing <https://www.adafruit.com/product/3449>`_.
86-
87-
.. code-block:: python
88-
89-
import board
90-
import adafruit_dotstar
91-
import time
92-
93-
94-
import adafruit_dotstar
95-
dotstar = adafruit_dotstar.DotStar(board.D13, board.D11, 72,
96-
pixel_order=adafruit_dotstar.BGR,
97-
brightness=0.3, auto_write=False)
98-
99-
blinka = (
100-
(0, 0x0f0716, 0x504069, 0x482e63, 0, 0),
101-
(0, 0x3d1446, 0x502b74, 0x622f8c, 0, 0),
102-
(0, 0x2e021b, 0x2e021b, 0x2e021b, 0, 0),
103-
(0, 0, 0x2e021b, 0x2e021b, 0, 0),
104-
(0, 0x591755, 0x912892, 0x3f205c, 0x282828, 0x301844),
105-
(0x65206b, 0x932281, 0x6e318f, 0x6d2b7e, 0x7e2686, 0x8c2c8f),
106-
(0x7c2d8c, 0xa21c81, 0x6b308e, 0x74257b, 0x7b2482, 0x742f8d),
107-
(0x23051a, 0x5c0f45, 0x81227b, 0x551a5b, 0x691b5d, 0x4d0c39),
108-
)
109-
offset = 0
110-
direction = 1
111-
while True:
112-
dotstar.fill(0)
113-
for y, row in enumerate(blinka):
114-
for x, value in enumerate(row):
115-
n = x * 12 + (y + offset)
116-
dotstar[n] = row[x]
117-
dotstar.show()
118-
time.sleep(0.1)
119-
offset += direction
120-
if offset > 4 or offset < 0:
121-
direction = -direction
122-
offset += direction
123-
124-
12581
Contributing
12682
============
12783

adafruit_dotstar.py

+70-60
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,32 @@
2929
3030
* Author(s): Damien P. George, Limor Fried, Scott Shawcroft & Roy Hooper
3131
"""
32+
33+
# pylint: disable=ungrouped-imports
34+
import sys
3235
import busio
3336
import digitalio
34-
try:
35-
import _pixelbuf
36-
except ImportError:
37+
38+
if sys.implementation.version[0] < 5:
3739
import adafruit_pypixelbuf as _pixelbuf
40+
else:
41+
try:
42+
import _pixelbuf
43+
except ImportError:
44+
import adafruit_pypixelbuf as _pixelbuf
3845

3946
__version__ = "0.0.0-auto.0"
4047
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_DotStar.git"
4148

4249
START_HEADER_SIZE = 4
4350

44-
RBG = 'PRBG'
45-
RGB = 'PRGB'
46-
GRB = 'PGRB'
47-
GBR = 'PGBR'
48-
BRG = 'PBRG'
49-
BGR = 'PBGR'
50-
BGR = 'PBGR'
51+
RBG = "PRBG"
52+
RGB = "PRGB"
53+
GRB = "PGRB"
54+
GBR = "PGBR"
55+
BRG = "PBRG"
56+
BGR = "PBGR"
57+
BGR = "PBGR"
5158

5259

5360
class DotStar(_pixelbuf.PixelBuf):
@@ -81,6 +88,22 @@ class DotStar(_pixelbuf.PixelBuf):
8188
with adafruit_dotstar.DotStar(APA102_SCK, APA102_MOSI, 1) as pixels:
8289
pixels[0] = RED
8390
time.sleep(2)
91+
92+
.. py:method:: DotStar.show()
93+
94+
Shows the new colors on the dotstars themselves if they haven't already
95+
been autowritten.
96+
97+
The colors may or may not be showing after this function returns because
98+
it may be done asynchronously.
99+
100+
.. py:method:: DotStar.fill(color)
101+
102+
Colors all dotstars the given ***color***.
103+
104+
.. py:attribute:: brightness
105+
106+
Overall brightness of the dotstar (0 to 1.0)
84107
"""
85108

86109
def __init__(
@@ -107,56 +130,25 @@ def __init__(
107130
self.dpin.direction = digitalio.Direction.OUTPUT
108131
self.cpin.direction = digitalio.Direction.OUTPUT
109132
self.cpin.value = False
110-
self.n = n
111133

112134
# Supply one extra clock cycle for each two pixels in the strip.
113-
end_header_size = n // 16
135+
trailer_size = n // 16
114136
if n % 16 != 0:
115-
end_header_size += 1
116-
bufsize = 4 * n + START_HEADER_SIZE + end_header_size
117-
end_header_index = bufsize - end_header_size
118-
self.pixel_order = pixel_order
119-
120-
self._buf = bytearray(bufsize)
121-
self._rawbuf = bytearray(bufsize)
122-
123-
# Four empty bytes to start.
124-
for i in range(START_HEADER_SIZE):
125-
self._rawbuf[i] = 0x00
126-
# 0xff bytes at the end.
127-
for i in range(end_header_index, bufsize):
128-
self._rawbuf[i] = 0xff
129-
# Mark the beginnings of each pixel.
130-
for i in range(START_HEADER_SIZE, end_header_index, 4):
131-
self._rawbuf[i] = 0xff
132-
self._buf[:] = self._rawbuf[:]
133-
134-
super(DotStar, self).__init__(n, self._buf, byteorder=pixel_order,
135-
rawbuf=self._rawbuf, offset=START_HEADER_SIZE,
136-
brightness=brightness, auto_write=auto_write)
137-
138-
def show(self):
139-
"""Shows the new colors on the pixels themselves if they haven't already
140-
been autowritten.
141-
142-
The colors may or may not be showing after this method returns because
143-
it may be done asynchronously.
144-
145-
This method is called automatically if auto_write is set to True.
146-
"""
147-
if self._spi:
148-
self._spi.write(self._buf)
149-
else:
150-
self.ds_writebytes()
151-
152-
def _ds_writebytes(self):
153-
for b in self.buf:
154-
for _ in range(8):
155-
self.dpin.value = (b & 0x80)
156-
self.cpin.value = True
157-
self.cpin.value = False
158-
b = b << 1
159-
self.cpin.value = False
137+
trailer_size += 1
138+
139+
# Four empty bytes for the header.
140+
header = bytearray(START_HEADER_SIZE)
141+
# 0xff bytes for the trailer.
142+
trailer = bytearray(b"\xff") * trailer_size
143+
144+
super().__init__(
145+
n,
146+
byteorder=pixel_order,
147+
brightness=brightness,
148+
auto_write=auto_write,
149+
header=header,
150+
trailer=trailer,
151+
)
160152

161153
def deinit(self):
162154
"""Blank out the DotStars and release the resources."""
@@ -177,6 +169,24 @@ def __exit__(self, exception_type, exception_value, traceback):
177169
def __repr__(self):
178170
return "[" + ", ".join([str(x) for x in self]) + "]"
179171

180-
def fill(self, color):
181-
"""Colors all pixels the given ***color***."""
182-
_pixelbuf.fill(self, color)
172+
@property
173+
def n(self):
174+
"""
175+
The number of dotstars in the chain (read-only)
176+
"""
177+
return len(self)
178+
179+
def _transmit(self, buffer):
180+
if self._spi:
181+
self._spi.write(buffer)
182+
else:
183+
self._ds_writebytes(buffer)
184+
185+
def _ds_writebytes(self, buffer):
186+
for b in buffer:
187+
for _ in range(8):
188+
self.dpin.value = b & 0x80
189+
self.cpin.value = True
190+
self.cpin.value = False
191+
b = b << 1
192+
self.cpin.value = False

docs/conf.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"sphinx.ext.viewcode",
1717
]
1818

19-
autodoc_mock_imports = ["pypixelbuf"]
19+
# autodoc_mock_imports = ["digitalio", "busio"]
2020

2121
intersphinx_mapping = {
2222
"python": ("https://docs.python.org/3.4", None),

examples/dotstar_image_pov.py

+11-23
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
board.MOSI,
2626
NUMPIXELS,
2727
auto_write=False,
28-
brightness=0.25,
28+
brightness=1.0,
2929
pixel_order=ORDER,
3030
)
3131

@@ -42,41 +42,29 @@
4242

4343
# Calculate gamma correction table, makes mid-range colors look 'right':
4444
GAMMA = bytearray(256)
45+
brightness = 0.25
4546
for i in range(256):
46-
# Notice we access DOTS.brightness directly here...the gamma table will
47-
# handle any brightness-scaling, so we can set the object brightness back
48-
# to max and it won't need to perform brightness scaling on every write.
49-
GAMMA[i] = int(pow(float(i) / 255.0, 2.7) * DOTS.brightness * 255.0 + 0.5)
50-
DOTS.brightness = 1.0
47+
GAMMA[i] = int(pow(float(i) / 255.0, 2.7) * brightness * 255.0 + 0.5)
5148

52-
# Allocate list of bytearrays, one for each column of image.
53-
# Each pixel REQUIRES 4 bytes (0xFF, B, G, R).
49+
# Allocate list of lists, one for each column of image.
5450
print("Allocating...")
5551
COLUMN = [0 for x in range(WIDTH)]
5652
for x in range(WIDTH):
57-
COLUMN[x] = bytearray(HEIGHT * 4)
53+
COLUMN[x] = [[0, 0, 0, 0] for _ in range(HEIGHT)]
5854

59-
# Convert entire RGB image into column-wise bytearray list.
60-
# The dotstar_image_paint.py example uses the library's 'setter' operation
61-
# for each pixel to do any R/G/B reordering. Because we're preparing data
62-
# directly for the strip, there's a reference to 'ORDER' here to rearrange
63-
# the color bytes as needed.
55+
# Convert entire RGB image into columnxrow 2D list.
6456
print("Converting...")
6557
for x in range(WIDTH): # For each column of image
6658
for y in range(HEIGHT): # For each pixel in column
6759
value = PIXELS[x, y] # Read RGB pixel in image
68-
y4 = y * 4 # Position in raw buffer
69-
COLUMN[x][y4] = 0xFF # Pixel start marker
70-
y4 += 1 # Pixel color data start
71-
COLUMN[x][y4 + ORDER[0]] = GAMMA[value[0]] # Gamma-corrected R
72-
COLUMN[x][y4 + ORDER[1]] = GAMMA[value[1]] # Gamma-corrected G
73-
COLUMN[x][y4 + ORDER[2]] = GAMMA[value[2]] # Gamma-corrected B
60+
COLUMN[x][y][0] = GAMMA[value[0]] # Gamma-corrected R
61+
COLUMN[x][y][1] = GAMMA[value[1]] # Gamma-corrected G
62+
COLUMN[x][y][2] = GAMMA[value[2]] # Gamma-corrected B
63+
COLUMN[x][y][3] = 1.0 # Brightness
7464

7565
print("Displaying...")
7666
while True: # Loop forever
7767

78-
# pylint: disable=protected-access
79-
# (Really shouldn't access _buf directly, but needed for fastest POV)
8068
for x in range(WIDTH): # For each column of image...
81-
DOTS._buf[4 : 4 + HEIGHT * 4] = COLUMN[x] # Copy column to DotStar buffer
69+
DOTS[0 : DOTS.n] = COLUMN[x] # Copy column to DotStar buffer
8270
DOTS.show() # Send data to strip

examples/dotstar_simpletest.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515

1616
# HELPERS
17-
# a random color 0 -> 224
17+
# a random color 0 -> 192
1818
def random_color():
1919
return random.randrange(0, 7) * 32
2020

requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
Adafruit-Blinka
22
adafruit-circuitpython-busdevice
3-
adafruit-circuitpython-pypixelbuf
3+
adafruit-circuitpython-pypixelbuf>=2.0.0

setup.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,13 @@
2828
# The project's main homepage.
2929
url="https://github.com/adafruit/Adafruit_CircuitPython_DotStar",
3030
# Author details
31-
author='Adafruit Industries',
32-
author_email='[email protected]',
33-
34-
install_requires=['Adafruit-Blinka', 'adafruit-circuitpython-busdevice',
35-
'adafruit-circuitpython-pypixelbuf'],
36-
31+
author="Adafruit Industries",
32+
author_email="[email protected]",
33+
install_requires=[
34+
"Adafruit-Blinka",
35+
"adafruit-circuitpython-busdevice",
36+
"adafruit-circuitpython-pypixelbuf>=2.0.0",
37+
],
3738
# Choose your license
3839
license="MIT",
3940
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers

0 commit comments

Comments
 (0)