/ adafruit_rgbled.py
adafruit_rgbled.py
  1  # The MIT License (MIT)
  2  #
  3  # Copyright (c) 2019 Brent Rubell for Adafruit Industries
  4  #
  5  # Permission is hereby granted, free of charge, to any person obtaining a copy
  6  # of this software and associated documentation files (the "Software"), to deal
  7  # in the Software without restriction, including without limitation the rights
  8  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9  # copies of the Software, and to permit persons to whom the Software is
 10  # furnished to do so, subject to the following conditions:
 11  #
 12  # The above copyright notice and this permission notice shall be included in
 13  # all copies or substantial portions of the Software.
 14  #
 15  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18  # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 20  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 21  # THE SOFTWARE.
 22  """
 23  `adafruit_rgbled`
 24  ================================================================================
 25  
 26  CircuitPython driver for RGB LEDs
 27  
 28  * Author(s): Brent Rubell
 29  
 30  Implementation Notes
 31  --------------------
 32  
 33  **Software and Dependencies:**
 34  
 35  * Adafruit CircuitPython firmware for the supported boards:
 36    https://github.com/adafruit/circuitpython/releases
 37  
 38  * Adafruit's SimpleIO library: https://github.com/adafruit/Adafruit_CircuitPython_SimpleIO
 39  """
 40  from pulseio import PWMOut
 41  from simpleio import map_range
 42  
 43  __version__ = "0.0.0-auto.0"
 44  __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_RGBLED.git"
 45  
 46  
 47  class RGBLED:
 48      """
 49      Creates a RGBLED object given three physical pins or PWMOut objects.
 50  
 51      :param red_pin: The physical pin connected to a red LED anode.
 52      :type ~microcontroller.Pin: Microcontroller's red_pin.
 53      :type pulseio.PWMOut: PWMOut object associated with red_pin.
 54      :type PWMChannel: PCA9685 PWM channel associated with red_pin.
 55      :param green_pin: The physical pin connected to a green LED anode.
 56      :type ~microcontroller.Pin: Microcontroller's green_pin.
 57      :type pulseio.PWMOut: PWMOut object associated with green_pin.
 58      :type PWMChannel: PCA9685 PWM channel associated with green_pin.
 59      :param blue_pin: The physical pin connected to a blue LED anode.
 60      :type ~microcontroller.Pin: Microcontroller's blue_pin.
 61      :type pulseio.PWMOut: PWMOut object associated with blue_pin.
 62      :type PWMChannel: PCA9685 PWM channel associated with blue_pin.
 63      :param bool invert_pwm: False if the RGB LED is common cathode,
 64          true if the RGB LED is common anode.
 65  
 66      Example for setting a RGB LED using a RGB Tuple (Red, Green, Blue):
 67  
 68      .. code-block:: python
 69  
 70          import board
 71          import adafruit_rgbled
 72  
 73          RED_LED = board.D5
 74          GREEN_LED = board.D6
 75          BLUE_LED = board.D7
 76  
 77          # Create a RGB LED object
 78          led = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED)
 79          led.color = (255, 0, 0)
 80  
 81      Example for setting a RGB LED using a 24-bit integer (hex syntax):
 82  
 83      .. code-block:: python
 84  
 85          import board
 86          import adafruit_rgbled
 87  
 88          RED_LED = board.D5
 89          GREEN_LED = board.D6
 90          BLUE_LED = board.D7
 91  
 92          # Create a RGB LED object
 93          led = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED)
 94          led.color = 0x100000
 95  
 96      Example for setting a RGB LED using a ContextManager:
 97  
 98      .. code-block:: python
 99  
100          import board
101          import adafruit_rgbled
102          with adafruit_rgbled.RGBLED(board.D5, board.D6, board.D7) as rgb_led:
103              rgb_led.color = (255, 0, 0)
104  
105      Example for setting a common-anode RGB LED using a ContextManager:
106  
107      .. code-block:: python
108  
109          import board
110          import adafruit_rgbled
111          with adafruit_rgbled.RGBLED(board.D5, board.D6, board.D7, invert_pwm=True) as rgb_led:
112              rgb_led.color = (0, 255, 0)
113  
114      """
115  
116      def __init__(self, red_pin, green_pin, blue_pin, invert_pwm=False):
117          self._rgb_led_pins = [red_pin, green_pin, blue_pin]
118          for i in range(len(self._rgb_led_pins)):
119              if hasattr(self._rgb_led_pins[i], "frequency"):
120                  self._rgb_led_pins[i].duty_cycle = 0
121              elif str(type(self._rgb_led_pins[i])) == "<class 'Pin'>":
122                  self._rgb_led_pins[i] = PWMOut(self._rgb_led_pins[i])
123                  self._rgb_led_pins[i].duty_cycle = 0
124              else:
125                  raise TypeError("Must provide a pin, PWMOut, or PWMChannel.")
126          self._invert_pwm = invert_pwm
127          self._current_color = (0, 0, 0)
128          self.color = self._current_color
129  
130      def __enter__(self):
131          return self
132  
133      def __exit__(self, exception_type, exception_value, traceback):
134          self.deinit()
135  
136      def deinit(self):
137          """Turn the LEDs off, deinit pwmout and release hardware resources."""
138          for pin in self._rgb_led_pins:
139              pin.deinit()  # pylint: disable=no-member
140          self._current_color = (0, 0, 0)
141  
142      @property
143      def color(self):
144          """Returns the RGB LED's current color."""
145          return self._current_color
146  
147      @color.setter
148      def color(self, value):
149          """Sets the RGB LED to a desired color.
150          :param type value: RGB LED desired value - can be a RGB tuple or a 24-bit integer.
151          """
152          self._current_color = value
153          if isinstance(value, tuple):
154              for i in range(0, 3):
155                  color = int(map_range(value[i], 0, 255, 0, 65535))
156                  if self._invert_pwm:
157                      color -= 65535
158                  self._rgb_led_pins[i].duty_cycle = abs(color)
159          elif isinstance(value, int):
160              if value >> 24:
161                  raise ValueError("Only bits 0->23 valid for integer input")
162              r = value >> 16
163              g = (value >> 8) & 0xFF
164              b = value & 0xFF
165              rgb = [r, g, b]
166              for color in range(0, 3):
167                  rgb[color] = int(map_range(rgb[color], 0, 255, 0, 65535))
168                  if self._invert_pwm:
169                      rgb[color] -= 65535
170                  self._rgb_led_pins[color].duty_cycle = abs(rgb[color])
171          else:
172              raise ValueError("Color must be a tuple or 24-bit integer value.")