/ adafruit_pixie.py
adafruit_pixie.py
1 # The MIT License (MIT) 2 # 3 # Copyright (c) 2016 Damien P. George (original Neopixel object) 4 # Copyright (c) 2018 Ladyada 5 # 6 # Permission is hereby granted, free of charge, to any person obtaining a copy 7 # of this software and associated documentation files (the "Software"), to deal 8 # in the Software without restriction, including without limitation the rights 9 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 # copies of the Software, and to permit persons to whom the Software is 11 # furnished to do so, subject to the following conditions: 12 # 13 # The above copyright notice and this permission notice shall be included in 14 # all copies or substantial portions of the Software. 15 # 16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 # THE SOFTWARE. 23 24 """ 25 `adafruit_pixie` - Pixie LED driver 26 ==================================================== 27 * Author(s): Damien P. George, Limor Fried, Kattni Rembor 28 """ 29 30 import time 31 import math 32 33 __version__ = "0.0.0-auto.0" 34 __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Pixie.git" 35 36 37 class Pixie: 38 """ 39 PIxie LEDs. 40 41 :param uart: The UART object. 42 :param int n: The number of Pixies in the chain. 43 :param float brightness: Brightness of the pixels between 0.0 and 1.0. 44 :param bool auto_write: True if the Pixies should immediately change when 45 set. If False, `show` must be called explicitly. 46 47 Example for two Pixie LEDs chained: 48 49 .. code_block::python 50 51 import time 52 import board 53 import busio 54 import adafruit_pixie 55 56 uart = busio.UART(board.TX, rx=None, baudrate=115200) 57 pixies = adafruit_pixie.Pixie(uart, 2, brightness=0.5) 58 59 while True: 60 pixies.fill((255, 0, 0)) 61 time.sleep(1) 62 pixies[0] = (0, 255, 0) 63 pixies[1] = (0, 0, 255) 64 time.sleep(1) 65 """ 66 67 def __init__(self, uart, n, *, brightness=1.0, auto_write=True): 68 self._uart = uart 69 self._n = n 70 self._buf = bytearray(self._n * 3) 71 # Set auto_write to False temporarily so brightness setter does _not_ 72 # call show() while in __init__. 73 self.auto_write = False 74 self._brightness = brightness 75 self.auto_write = auto_write 76 77 def _set_item(self, index, value): 78 if index < 0: 79 index += len(self) 80 if index >= self._n or index < 0: 81 raise IndexError 82 offset = index * 3 83 r = 0 84 g = 0 85 b = 0 86 if isinstance(value, int): 87 r = value >> 16 88 g = (value >> 8) & 0xFF 89 b = value & 0xFF 90 elif len(value) == 3: 91 r, g, b = value 92 self._buf[offset + 0] = r 93 self._buf[offset + 1] = g 94 self._buf[offset + 2] = b 95 96 def __setitem__(self, index, val): 97 if isinstance(index, slice): 98 start, stop, step = index.indices(len(self._buf) // 3) 99 length = stop - start 100 if step != 0: 101 length = math.ceil(length / step) 102 if len(val) != length: 103 raise ValueError("Slice and input sequence size do not match.") 104 for val_i, in_i in enumerate(range(start, stop, step)): 105 self._set_item(in_i, val[val_i]) 106 else: 107 self._set_item(index, val) 108 109 if self.auto_write: 110 self.show() 111 112 def __len__(self): 113 return len(self._buf) // 3 114 115 @property 116 def brightness(self): 117 """Overall brightness of the pixel""" 118 return self._brightness 119 120 @brightness.setter 121 def brightness(self, brightness): 122 self._brightness = min(max(brightness, 0.0), 1.0) 123 if self.auto_write: 124 self.show() 125 126 def fill(self, color): 127 """Colors all pixels the given ***color***.""" 128 auto_write = self.auto_write 129 self.auto_write = False 130 for i in range(self._n): 131 self[i] = color 132 if auto_write: 133 self.show() 134 self.auto_write = auto_write 135 136 def show(self): 137 """ 138 Shows the new colors on the pixels themselves if they haven't already 139 been autowritten. 140 """ 141 self._uart.write(bytes([int(i * self.brightness) for i in self._buf])) 142 time.sleep(0.005)