Add support for pixelbuf
This commit is contained in:
parent
694fdecb7e
commit
21310b27f8
7 changed files with 90 additions and 135 deletions
46
README.rst
46
README.rst
|
|
@ -26,7 +26,7 @@ It should be a float. For example, (0xFF,0,0, 1.0) is the brightest red possible
|
|||
|
||||
.. note:: The int hex API represents the brightness of the white pixel when
|
||||
present by setting the RGB channels to identical values. For example, full
|
||||
white is 0xffffff but is actually (0xff, 0xff, 0xff) in the tuple syntax.
|
||||
white is 0xffffff but is actually (0xff, 0xff, 0xff) in the tuple syntax.
|
||||
|
||||
Dependencies
|
||||
=============
|
||||
|
|
@ -78,50 +78,6 @@ This example demonstrates the library with the single built-in DotStar on the
|
|||
pixels = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
|
||||
pixels[0] = (10, 0, 0)
|
||||
|
||||
|
||||
This example demonstrates the library with the DotStar Feather Wing and bounces Blinka.
|
||||
|
||||
`Feather M4 Express <https://www.adafruit.com/product/3857>`_ and
|
||||
`DotStar FeatherWing <https://www.adafruit.com/product/3449>`_.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import board
|
||||
import adafruit_dotstar
|
||||
import time
|
||||
|
||||
|
||||
import adafruit_dotstar
|
||||
dotstar = adafruit_dotstar.DotStar(board.D13, board.D11, 72,
|
||||
pixel_order=adafruit_dotstar.BGR,
|
||||
brightness=0.3, auto_write=False)
|
||||
|
||||
blinka = (
|
||||
(0, 0x0f0716, 0x504069, 0x482e63, 0, 0),
|
||||
(0, 0x3d1446, 0x502b74, 0x622f8c, 0, 0),
|
||||
(0, 0x2e021b, 0x2e021b, 0x2e021b, 0, 0),
|
||||
(0, 0, 0x2e021b, 0x2e021b, 0, 0),
|
||||
(0, 0x591755, 0x912892, 0x3f205c, 0x282828, 0x301844),
|
||||
(0x65206b, 0x932281, 0x6e318f, 0x6d2b7e, 0x7e2686, 0x8c2c8f),
|
||||
(0x7c2d8c, 0xa21c81, 0x6b308e, 0x74257b, 0x7b2482, 0x742f8d),
|
||||
(0x23051a, 0x5c0f45, 0x81227b, 0x551a5b, 0x691b5d, 0x4d0c39),
|
||||
)
|
||||
offset = 0
|
||||
direction = 1
|
||||
while True:
|
||||
dotstar.fill(0)
|
||||
for y, row in enumerate(blinka):
|
||||
for x, value in enumerate(row):
|
||||
n = x * 12 + (y + offset)
|
||||
dotstar[n] = row[x]
|
||||
dotstar.show()
|
||||
time.sleep(0.1)
|
||||
offset += direction
|
||||
if offset > 4 or offset < 0:
|
||||
direction = -direction
|
||||
offset += direction
|
||||
|
||||
|
||||
Contributing
|
||||
============
|
||||
|
||||
|
|
|
|||
|
|
@ -29,25 +29,32 @@
|
|||
|
||||
* Author(s): Damien P. George, Limor Fried, Scott Shawcroft & Roy Hooper
|
||||
"""
|
||||
|
||||
# pylint: disable=ungrouped-imports
|
||||
import sys
|
||||
import busio
|
||||
import digitalio
|
||||
try:
|
||||
import _pixelbuf
|
||||
except ImportError:
|
||||
|
||||
if sys.implementation.version[0] < 5:
|
||||
import adafruit_pypixelbuf as _pixelbuf
|
||||
else:
|
||||
try:
|
||||
import _pixelbuf
|
||||
except ImportError:
|
||||
import adafruit_pypixelbuf as _pixelbuf
|
||||
|
||||
__version__ = "0.0.0-auto.0"
|
||||
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_DotStar.git"
|
||||
|
||||
START_HEADER_SIZE = 4
|
||||
|
||||
RBG = 'PRBG'
|
||||
RGB = 'PRGB'
|
||||
GRB = 'PGRB'
|
||||
GBR = 'PGBR'
|
||||
BRG = 'PBRG'
|
||||
BGR = 'PBGR'
|
||||
BGR = 'PBGR'
|
||||
RBG = "PRBG"
|
||||
RGB = "PRGB"
|
||||
GRB = "PGRB"
|
||||
GBR = "PGBR"
|
||||
BRG = "PBRG"
|
||||
BGR = "PBGR"
|
||||
BGR = "PBGR"
|
||||
|
||||
|
||||
class DotStar(_pixelbuf.PixelBuf):
|
||||
|
|
@ -81,6 +88,22 @@ class DotStar(_pixelbuf.PixelBuf):
|
|||
with adafruit_dotstar.DotStar(APA102_SCK, APA102_MOSI, 1) as pixels:
|
||||
pixels[0] = RED
|
||||
time.sleep(2)
|
||||
|
||||
.. py:method:: DotStar.show()
|
||||
|
||||
Shows the new colors on the dotstars themselves if they haven't already
|
||||
been autowritten.
|
||||
|
||||
The colors may or may not be showing after this function returns because
|
||||
it may be done asynchronously.
|
||||
|
||||
.. py:method:: DotStar.fill(color)
|
||||
|
||||
Colors all dotstars the given ***color***.
|
||||
|
||||
.. py:attribute:: brightness
|
||||
|
||||
Overall brightness of the dotstar (0 to 1.0)
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
|
|
@ -107,56 +130,25 @@ class DotStar(_pixelbuf.PixelBuf):
|
|||
self.dpin.direction = digitalio.Direction.OUTPUT
|
||||
self.cpin.direction = digitalio.Direction.OUTPUT
|
||||
self.cpin.value = False
|
||||
self.n = n
|
||||
|
||||
# Supply one extra clock cycle for each two pixels in the strip.
|
||||
end_header_size = n // 16
|
||||
trailer_size = n // 16
|
||||
if n % 16 != 0:
|
||||
end_header_size += 1
|
||||
bufsize = 4 * n + START_HEADER_SIZE + end_header_size
|
||||
end_header_index = bufsize - end_header_size
|
||||
self.pixel_order = pixel_order
|
||||
trailer_size += 1
|
||||
|
||||
self._buf = bytearray(bufsize)
|
||||
self._rawbuf = bytearray(bufsize)
|
||||
# Four empty bytes for the header.
|
||||
header = bytearray(START_HEADER_SIZE)
|
||||
# 0xff bytes for the trailer.
|
||||
trailer = bytearray(b"\xff") * trailer_size
|
||||
|
||||
# Four empty bytes to start.
|
||||
for i in range(START_HEADER_SIZE):
|
||||
self._rawbuf[i] = 0x00
|
||||
# 0xff bytes at the end.
|
||||
for i in range(end_header_index, bufsize):
|
||||
self._rawbuf[i] = 0xff
|
||||
# Mark the beginnings of each pixel.
|
||||
for i in range(START_HEADER_SIZE, end_header_index, 4):
|
||||
self._rawbuf[i] = 0xff
|
||||
self._buf[:] = self._rawbuf[:]
|
||||
|
||||
super(DotStar, self).__init__(n, self._buf, byteorder=pixel_order,
|
||||
rawbuf=self._rawbuf, offset=START_HEADER_SIZE,
|
||||
brightness=brightness, auto_write=auto_write)
|
||||
|
||||
def show(self):
|
||||
"""Shows the new colors on the pixels themselves if they haven't already
|
||||
been autowritten.
|
||||
|
||||
The colors may or may not be showing after this method returns because
|
||||
it may be done asynchronously.
|
||||
|
||||
This method is called automatically if auto_write is set to True.
|
||||
"""
|
||||
if self._spi:
|
||||
self._spi.write(self._buf)
|
||||
else:
|
||||
self.ds_writebytes()
|
||||
|
||||
def _ds_writebytes(self):
|
||||
for b in self.buf:
|
||||
for _ in range(8):
|
||||
self.dpin.value = (b & 0x80)
|
||||
self.cpin.value = True
|
||||
self.cpin.value = False
|
||||
b = b << 1
|
||||
self.cpin.value = False
|
||||
super().__init__(
|
||||
n,
|
||||
byteorder=pixel_order,
|
||||
brightness=brightness,
|
||||
auto_write=auto_write,
|
||||
header=header,
|
||||
trailer=trailer,
|
||||
)
|
||||
|
||||
def deinit(self):
|
||||
"""Blank out the DotStars and release the resources."""
|
||||
|
|
@ -177,6 +169,24 @@ class DotStar(_pixelbuf.PixelBuf):
|
|||
def __repr__(self):
|
||||
return "[" + ", ".join([str(x) for x in self]) + "]"
|
||||
|
||||
def fill(self, color):
|
||||
"""Colors all pixels the given ***color***."""
|
||||
_pixelbuf.fill(self, color)
|
||||
@property
|
||||
def n(self):
|
||||
"""
|
||||
The number of dotstars in the chain (read-only)
|
||||
"""
|
||||
return len(self)
|
||||
|
||||
def _transmit(self, buffer):
|
||||
if self._spi:
|
||||
self._spi.write(buffer)
|
||||
else:
|
||||
self._ds_writebytes(buffer)
|
||||
|
||||
def _ds_writebytes(self, buffer):
|
||||
for b in buffer:
|
||||
for _ in range(8):
|
||||
self.dpin.value = b & 0x80
|
||||
self.cpin.value = True
|
||||
self.cpin.value = False
|
||||
b = b << 1
|
||||
self.cpin.value = False
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ extensions = [
|
|||
"sphinx.ext.viewcode",
|
||||
]
|
||||
|
||||
autodoc_mock_imports = ["pypixelbuf"]
|
||||
# autodoc_mock_imports = ["digitalio", "busio"]
|
||||
|
||||
intersphinx_mapping = {
|
||||
"python": ("https://docs.python.org/3.4", None),
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ DOTS = dotstar.DotStar(
|
|||
board.MOSI,
|
||||
NUMPIXELS,
|
||||
auto_write=False,
|
||||
brightness=0.25,
|
||||
brightness=1.0,
|
||||
pixel_order=ORDER,
|
||||
)
|
||||
|
||||
|
|
@ -42,41 +42,29 @@ if HEIGHT > NUMPIXELS:
|
|||
|
||||
# Calculate gamma correction table, makes mid-range colors look 'right':
|
||||
GAMMA = bytearray(256)
|
||||
brightness = 0.25
|
||||
for i in range(256):
|
||||
# Notice we access DOTS.brightness directly here...the gamma table will
|
||||
# handle any brightness-scaling, so we can set the object brightness back
|
||||
# to max and it won't need to perform brightness scaling on every write.
|
||||
GAMMA[i] = int(pow(float(i) / 255.0, 2.7) * DOTS.brightness * 255.0 + 0.5)
|
||||
DOTS.brightness = 1.0
|
||||
GAMMA[i] = int(pow(float(i) / 255.0, 2.7) * brightness * 255.0 + 0.5)
|
||||
|
||||
# Allocate list of bytearrays, one for each column of image.
|
||||
# Each pixel REQUIRES 4 bytes (0xFF, B, G, R).
|
||||
# Allocate list of lists, one for each column of image.
|
||||
print("Allocating...")
|
||||
COLUMN = [0 for x in range(WIDTH)]
|
||||
for x in range(WIDTH):
|
||||
COLUMN[x] = bytearray(HEIGHT * 4)
|
||||
COLUMN[x] = [[0, 0, 0, 0] for _ in range(HEIGHT)]
|
||||
|
||||
# Convert entire RGB image into column-wise bytearray list.
|
||||
# The dotstar_image_paint.py example uses the library's 'setter' operation
|
||||
# for each pixel to do any R/G/B reordering. Because we're preparing data
|
||||
# directly for the strip, there's a reference to 'ORDER' here to rearrange
|
||||
# the color bytes as needed.
|
||||
# Convert entire RGB image into columnxrow 2D list.
|
||||
print("Converting...")
|
||||
for x in range(WIDTH): # For each column of image
|
||||
for y in range(HEIGHT): # For each pixel in column
|
||||
value = PIXELS[x, y] # Read RGB pixel in image
|
||||
y4 = y * 4 # Position in raw buffer
|
||||
COLUMN[x][y4] = 0xFF # Pixel start marker
|
||||
y4 += 1 # Pixel color data start
|
||||
COLUMN[x][y4 + ORDER[0]] = GAMMA[value[0]] # Gamma-corrected R
|
||||
COLUMN[x][y4 + ORDER[1]] = GAMMA[value[1]] # Gamma-corrected G
|
||||
COLUMN[x][y4 + ORDER[2]] = GAMMA[value[2]] # Gamma-corrected B
|
||||
COLUMN[x][y][0] = GAMMA[value[0]] # Gamma-corrected R
|
||||
COLUMN[x][y][1] = GAMMA[value[1]] # Gamma-corrected G
|
||||
COLUMN[x][y][2] = GAMMA[value[2]] # Gamma-corrected B
|
||||
COLUMN[x][y][3] = 1.0 # Brightness
|
||||
|
||||
print("Displaying...")
|
||||
while True: # Loop forever
|
||||
|
||||
# pylint: disable=protected-access
|
||||
# (Really shouldn't access _buf directly, but needed for fastest POV)
|
||||
for x in range(WIDTH): # For each column of image...
|
||||
DOTS._buf[4 : 4 + HEIGHT * 4] = COLUMN[x] # Copy column to DotStar buffer
|
||||
DOTS[0 : DOTS.n] = COLUMN[x] # Copy column to DotStar buffer
|
||||
DOTS.show() # Send data to strip
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ dots = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2)
|
|||
|
||||
|
||||
# HELPERS
|
||||
# a random color 0 -> 224
|
||||
# a random color 0 -> 192
|
||||
def random_color():
|
||||
return random.randrange(0, 7) * 32
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
Adafruit-Blinka
|
||||
adafruit-circuitpython-busdevice
|
||||
adafruit-circuitpython-pypixelbuf
|
||||
adafruit-circuitpython-pypixelbuf>=2.0.0
|
||||
|
|
|
|||
13
setup.py
13
setup.py
|
|
@ -28,12 +28,13 @@ setup(
|
|||
# The project's main homepage.
|
||||
url="https://github.com/adafruit/Adafruit_CircuitPython_DotStar",
|
||||
# Author details
|
||||
author='Adafruit Industries',
|
||||
author_email='circuitpython@adafruit.com',
|
||||
|
||||
install_requires=['Adafruit-Blinka', 'adafruit-circuitpython-busdevice',
|
||||
'adafruit-circuitpython-pypixelbuf'],
|
||||
|
||||
author="Adafruit Industries",
|
||||
author_email="circuitpython@adafruit.com",
|
||||
install_requires=[
|
||||
"Adafruit-Blinka",
|
||||
"adafruit-circuitpython-busdevice",
|
||||
"adafruit-circuitpython-pypixelbuf>=2.0.0",
|
||||
],
|
||||
# Choose your license
|
||||
license="MIT",
|
||||
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
||||
|
|
|
|||
Loading…
Reference in a new issue