Skip to content

Expose individual brightness modification in stock dotstar library #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
May 14, 2018
33 changes: 28 additions & 5 deletions adafruit_dotstar.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_DotStar.git"

START_HEADER_SIZE = 4
LED_START = 0b11100000 # Three "1" bits, followed by 5 brightness bits

# Pixel color order constants
RGB = (0, 1, 2)
Expand Down Expand Up @@ -137,16 +138,38 @@ def __repr__(self):
return "[" + ", ".join([str(x) for x in self]) + "]"

def _set_item(self, index, value):
"""
value can be one of three things:
a (r,g,b) list/tuple
a (r,g,b, brightness) list/tuple
a single, longer int that contains RGB values, like 0xFFFFFF
brightness, if specified should be a float 0-1

Set a pixel value. You can set per-pixel brightness here, if it's not passed it
will use the max value for pixel brightness value, which is a good default.

Important notes about the per-pixel brightness - it's accomplished by
PWMing the entire output of the LED, and that PWM is at a much
slower clock than the rest of the LEDs. This can cause problems in
Persistence of Vision Applications
"""

offset = index * 4 + START_HEADER_SIZE
rgb = value
if isinstance(value, int):
rgb = (value >> 16, (value >> 8) & 0xff, value & 0xff)

# Each pixel starts with 0xFF, then red/green/blue. Although the data
# sheet suggests using a global brightness in the first byte, we don't
# do that because it causes further issues with persistence of vision
# projects.
self._buf[offset] = 0xff # redundant; should already be set
if len(value) == 4:
brightness = value[-1]
rgb = value[:3]
else:
brightness = 1

# LED startframe is three "1" bits, followed by 5 brightness bits
# then 8 bits for each of R, G, and B. The order of those 3 are configurable and
# vary based on hardware
brightness_byte = math.ceil(brightness * 31) & 0b00011111
self._buf[offset] = brightness_byte | LED_START
self._buf[offset + 1] = rgb[self.pixel_order[0]]
self._buf[offset + 2] = rgb[self.pixel_order[1]]
self._buf[offset + 3] = rgb[self.pixel_order[2]]
Expand Down