Skip to content

Commit

Permalink
Merge pull request #70 from adafruit/revert-59-pixelbuf
Browse files Browse the repository at this point in the history
Revert "_pixelbuf support"
  • Loading branch information
tannewt authored Jan 23, 2020
2 parents 68388d0 + 096d079 commit 10db851
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 48 deletions.
169 changes: 123 additions & 46 deletions neopixel.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
#
# Copyright (c) 2016 Damien P. George
# Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
# Copyright (c) 2019 Carter Nelson
# Copyright (c) 2019 Roy Hooper
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
Expand All @@ -27,33 +25,28 @@
`neopixel` - NeoPixel strip driver
====================================================
* Author(s): Damien P. George, Scott Shawcroft, Carter Nelson, Roy Hooper
* Author(s): Damien P. George & Scott Shawcroft
"""

import math

import digitalio
from neopixel_write import neopixel_write
try:
import _pixelbuf
except ImportError:
import adafruit_pypixelbuf as _pixelbuf


__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel.git"


# Pixel color order constants
RGB = 'RGB'
RGB = (0, 1, 2)
"""Red Green Blue"""
GRB = 'GRB'
GRB = (1, 0, 2)
"""Green Red Blue"""
RGBW = 'RGBW'
RGBW = (0, 1, 2, 3)
"""Red Green Blue White"""
GRBW = 'GRBW'
GRBW = (1, 0, 2, 3)
"""Green Red Blue White"""


class NeoPixel(_pixelbuf.PixelBuf):
class NeoPixel:
"""
A sequence of neopixels.
Expand All @@ -64,7 +57,7 @@ class NeoPixel(_pixelbuf.PixelBuf):
brightness
:param bool auto_write: True if the neopixels should immediately change when set. If False,
`show` must be called explicitly.
:param str: Set the pixel color channel order. GRBW is set by default.
:param tuple pixel_order: Set the pixel color channel order. GRBW is set by default.
Example for Circuit Playground Express:
Expand Down Expand Up @@ -94,37 +87,28 @@ class NeoPixel(_pixelbuf.PixelBuf):
pixels[::2] = [RED] * (len(pixels) // 2)
time.sleep(2)
"""
bpp = None
n = 0

def __init__(self, pin, n, *, bpp=3, brightness=1.0, auto_write=True, pixel_order=None):
self.bpp = bpp
self.n = n

if not pixel_order:
pixel_order = GRB if bpp == 3 else GRBW
else:
self.bpp = bpp = len(pixel_order)
if isinstance(pixel_order, tuple):
order_chars = RGBW
order = []
for char_no, order in enumerate(pixel_order):
order[pixel_order] = order_chars[char_no]
pixel_order = ''.join(order)

super().__init__(n, bytearray(self.n * bpp),
brightness=brightness,
rawbuf=bytearray(self.n * bpp),
byteorder=pixel_order,
auto_write=auto_write)

self.pin = digitalio.DigitalInOut(pin)
self.pin.direction = digitalio.Direction.OUTPUT
self.n = n
if pixel_order is None:
self.order = GRBW
self.bpp = bpp
else:
self.order = pixel_order
self.bpp = len(self.order)
self.buf = bytearray(self.n * self.bpp)
# Set auto_write to False temporarily so brightness setter does _not_
# call show() while in __init__.
self.auto_write = False
self.brightness = brightness
self.auto_write = auto_write

def deinit(self):
"""Blank out the NeoPixels and release the pin."""
self.fill(0)
self.show()
for i in range(len(self.buf)):
self.buf[i] = 0
neopixel_write(self.pin, self.buf)
self.pin.deinit()

def __enter__(self):
Expand All @@ -136,6 +120,100 @@ def __exit__(self, exception_type, exception_value, traceback):
def __repr__(self):
return "[" + ", ".join([str(x) for x in self]) + "]"

def _set_item(self, index, value):
if index < 0:
index += len(self)
if index >= self.n or index < 0:
raise IndexError
offset = index * self.bpp
r = 0
g = 0
b = 0
w = 0
if isinstance(value, int):
if value>>24:
raise ValueError("only bits 0->23 valid for integer input")
r = value >> 16
g = (value >> 8) & 0xff
b = value & 0xff
w = 0
# If all components are the same and we have a white pixel then use it
# instead of the individual components.
if self.bpp == 4 and r == g and g == b:
w = r
r = 0
g = 0
b = 0
elif (len(value) == self.bpp) or ((len(value) == 3) and (self.bpp == 4)):
if len(value) == 3:
r, g, b = value
else:
r, g, b, w = value
else:
raise ValueError("Color tuple size does not match pixel_order.")

self.buf[offset + self.order[0]] = r
self.buf[offset + self.order[1]] = g
self.buf[offset + self.order[2]] = b
if self.bpp == 4:
self.buf[offset + self.order[3]] = w

def __setitem__(self, index, val):
if isinstance(index, slice):
start, stop, step = index.indices(len(self.buf) // self.bpp)
length = stop - start
if step != 0:
length = math.ceil(length / step)
if len(val) != length:
raise ValueError("Slice and input sequence size do not match.")
for val_i, in_i in enumerate(range(start, stop, step)):
self._set_item(in_i, val[val_i])
else:
self._set_item(index, val)

if self.auto_write:
self.show()

def __getitem__(self, index):
if isinstance(index, slice):
out = []
for in_i in range(*index.indices(len(self.buf) // self.bpp)):
out.append(tuple(self.buf[in_i * self.bpp + self.order[i]]
for i in range(self.bpp)))
return out
if index < 0:
index += len(self)
if index >= self.n or index < 0:
raise IndexError
offset = index * self.bpp
return tuple(self.buf[offset + self.order[i]]
for i in range(self.bpp))

def __len__(self):
return len(self.buf) // self.bpp

@property
def brightness(self):
"""Overall brightness of the pixel"""
return self._brightness

@brightness.setter
def brightness(self, brightness):
# pylint: disable=attribute-defined-outside-init
self._brightness = min(max(brightness, 0.0), 1.0)
if self.auto_write:
self.show()

def fill(self, color):
"""Colors all pixels the given ***color***."""
auto_write = self.auto_write
self.auto_write = False
for i, _ in enumerate(self):
self[i] = color
if auto_write:
self.show()
self.auto_write = auto_write

def write(self):
""".. deprecated: 1.0.0
Expand All @@ -148,8 +226,7 @@ def show(self):
The colors may or may not be showing after this function returns because
it may be done asynchronously."""
neopixel_write(self.pin, self.buf)

def fill(self, color):
"""Colors all pixels the given ***color***."""
_pixelbuf.fill(self, color)
if self.brightness > 0.99:
neopixel_write(self.pin, self.buf)
else:
neopixel_write(self.pin, bytearray([int(i * self.brightness) for i in self.buf]))
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
Adafruit-Blinka
adafruit-circuitpython-pypixelbuf
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
author='Adafruit Industries & Damien P. George',
author_email='[email protected]',

install_requires=['Adafruit-Blinka', 'adafruit-circuitpython-pypixelbuf'],
install_requires=['Adafruit-Blinka'],

# Choose your license
license='MIT',
Expand Down

0 comments on commit 10db851

Please sign in to comment.