-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathadafruit_rgbled.py
179 lines (143 loc) · 5.8 KB
/
adafruit_rgbled.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries
#
# SPDX-License-Identifier: MIT
# pylint: disable=raise-missing-from
"""
`adafruit_rgbled`
================================================================================
CircuitPython driver for RGB LEDs
* Author(s): Brent Rubell
Implementation Notes
--------------------
**Software and Dependencies:**
* Adafruit CircuitPython firmware for the supported boards:
https://github.com/adafruit/circuitpython/releases
"""
try:
from typing import Union, Optional, Type
from types import TracebackType
from microcontroller import Pin
from adafruit_pca9685 import PWMChannel
from circuitpython_typing.led import ColorBasedColorUnion
except ImportError:
pass
from pwmio import PWMOut
__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_RGBLED.git"
class RGBLED:
"""
Create an RGBLED object given three physical pins or PWMOut objects.
Example for setting an RGB LED using an RGB Tuple (Red, Green, Blue):
.. code-block:: python
import board
import adafruit_rgbled
RED_LED = board.D5
GREEN_LED = board.D6
BLUE_LED = board.D7
# Create a RGB LED object
led = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED)
led.color = (255, 0, 0)
Example for setting an RGB LED using a 24-bit integer (hex syntax):
.. code-block:: python
import board
import adafruit_rgbled
RED_LED = board.D5
GREEN_LED = board.D6
BLUE_LED = board.D7
# Create an RGB LED object
led = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED)
led.color = 0x100000
Example for setting an RGB LED using a ContextManager:
.. code-block:: python
import board
import adafruit_rgbled
with adafruit_rgbled.RGBLED(board.D5, board.D6, board.D7) as rgb_led:
rgb_led.color = (255, 0, 0)
Example for setting a common-anode RGB LED using a ContextManager:
.. code-block:: python
import board
import adafruit_rgbled
with adafruit_rgbled.RGBLED(board.D5, board.D6, board.D7, invert_pwm=True) as rgb_led:
rgb_led.color = (0, 255, 0)
:param Union["microcontroller.Pin", PWMOut, "PWMChannel"] red_pin:
The connection to the red LED.
:param Union["microcontroller.Pin", PWMOut, "PWMChannel"] green_pin:
The connection to the green LED.
:param Union["microcontroller.Pin", PWMOut, "PWMChannel"] blue_pin:
The connection to the blue LED.
:param bool invert_pwm: False if the RGB LED is common cathode,
True if the RGB LED is common anode. Defaults to False.
"""
def __init__(
self,
red_pin: Union[Pin, PWMOut, "PWMChannel"],
green_pin: Union[Pin, PWMOut, "PWMChannel"],
blue_pin: Union[Pin, PWMOut, "PWMChannel"],
invert_pwm: bool = False,
) -> None:
self._rgb_led_pins = [red_pin, green_pin, blue_pin]
for pin, _ in enumerate(self._rgb_led_pins):
try:
pin_type = str(type(self._rgb_led_pins[pin]))
if pin_type.startswith("<class '") and pin_type.endswith("Pin'>"):
self._rgb_led_pins[pin] = PWMOut(self._rgb_led_pins[pin])
self._rgb_led_pins[pin].duty_cycle = 0
except AttributeError:
raise TypeError("Pins must be of type Pin, PWMOut or PWMChannel")
self._invert_pwm = invert_pwm
self._current_color = (0, 0, 0)
self.color = self._current_color
def __enter__(self) -> "RGBLED":
return self
def __exit__(
self,
exception_type: Optional[Type[type]],
exception_value: Optional[BaseException],
traceback: Optional[TracebackType],
) -> None:
self.deinit()
def deinit(self) -> None:
"""Turn the LEDs off, deinit pwmout and release hardware resources."""
for pin in self._rgb_led_pins:
pin.deinit() # pylint: disable=no-member
self._current_color = (0, 0, 0)
@property
def color(self) -> ColorBasedColorUnion:
"""
Sets the RGB LED to a desired color.
:param ColorBasedColorUnion value: RGB LED desired value - can be a RGB
tuple of values 0 - 255 or a 24-bit integer. e.g. (255, 64, 35) and 0xff4023
are equivalent.
:returns Union[int, Tuple[int, int, int]]: The current LED color setting.
:raises ValueError: If the input is an int > 0xffffff or is a tuple that does not
contain 3 integers of 0 - 255.
:raises TypeError: If the input is not an integer or a tuple.
"""
return self._current_color
@color.setter
def color(self, value: ColorBasedColorUnion):
if isinstance(value, int):
try:
# Check that integer is <= 0xffffff and create an iterable.
rgb = value.to_bytes(3, "big", signed=False)
except OverflowError:
raise ValueError("Only bits 0->23 valid for integer input")
elif isinstance(value, tuple):
try:
rgb = bytes(value) # Check that tuple has integers of 0 - 255.
if len(rgb) != 3:
raise ValueError
except (ValueError, TypeError):
raise ValueError(
"Only a tuple of 3 integers of 0 - 255 for tuple input."
)
else:
raise TypeError(
"Color must be a tuple of 3 integers or 24-bit integer value."
)
for color, intensity in enumerate(rgb):
# Take advantage of bool truthiness.
self._rgb_led_pins[color].duty_cycle = abs(
intensity * 257 - 65535 * self._invert_pwm
)
self._current_color = value