diff --git a/adafruit_pypixelbuf.py b/adafruit_pypixelbuf.py index fc6fd25..f36aded 100644 --- a/adafruit_pypixelbuf.py +++ b/adafruit_pypixelbuf.py @@ -227,31 +227,39 @@ def _parse_color(self, value): 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 self._has_white and r == g and g == b: + + if self._dotstar_mode: + w = 1.0 + else: + if len(value) < 3 or len(value) > 4: + raise ValueError( + "Expected tuple of length {}, got {}".format(self._bpp, len(value)) + ) + if len(value) == self._bpp: + if self._bpp == 3: + r, g, b = value + else: + r, g, b, w = value + elif len(value) == 3: + r, g, b = value + if self._dotstar_mode: + w = 1.0 + + if self._bpp == 4: + if self._dotstar_mode: + # 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 + # same as math.ceil(brightness * 31) & 0b00011111 + # Idea from https://www.codeproject.com/Tips/700780/Fast-floor-ceiling-functions + w = (32 - int(32 - w * 31) & 0b00011111) | DOTSTAR_LED_START + elif self._has_white and r == g and g == b: + # If all components are the same and we have a white pixel then use it + # instead of the individual components. w = r r = 0 g = 0 b = 0 - elif self._dotstar_mode: - w = 1.0 - elif len(value) == self._bpp: - if self._bpp == 3: - r, g, b = value - else: - r, g, b, w = value - elif len(value) == 3 and self._dotstar_mode: - r, g, b = value - w = 1.0 - - if self._bpp == 4 and self._dotstar_mode: - # 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 - # same as math.ceil(brightness * 31) & 0b00011111 - # Idea from https://www.codeproject.com/Tips/700780/Fast-floor-ceiling-functions - w = (32 - int(32 - w * 31) & 0b00011111) | DOTSTAR_LED_START return (r, g, b, w) diff --git a/examples/pypixelbuf_simpletest.py b/examples/pypixelbuf_simpletest.py index fe0d08a..2fe22e1 100644 --- a/examples/pypixelbuf_simpletest.py +++ b/examples/pypixelbuf_simpletest.py @@ -4,12 +4,18 @@ class TestBuf(adafruit_pypixelbuf.PixelBuf): called = False - def _transmit(self, buffer): + @property + def n(self): + return len(self) + + def _transmit(self, buffer): # pylint: disable=unused-argument self.called = True -buf = TestBuf(20, "RGB", 1.0, auto_write=True) +buf = TestBuf(20, "RGBW", 1.0, auto_write=True) buf[0] = (1, 2, 3) +buf[1] = (1, 2, 3, 4) +buf[2] = (2, 2, 2) print(buf[0]) print(buf[0:2])