diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 354c761..50866b2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,6 +28,7 @@ repos: hooks: - id: pylint_examples name: pylint (examples code) + require_serial: true description: Run pylint rules on "examples/*.py" files entry: /usr/bin/env bash -c args: ['([[ ! -d "examples" ]] || for example in $(find . -path "./examples/*.py"); do pylint --disable=missing-docstring,invalid-name $example; done)'] diff --git a/README.rst b/README.rst index 0fd4124..4994569 100644 --- a/README.rst +++ b/README.rst @@ -23,6 +23,7 @@ This driver supports the following hardware: * `Pimoroni 17x7 Scroll pHAT HD `_ * `Pimoroni 28x3 (r,g,b) Led Shim `_ * `Pimoroni Keybow 2040 with 4x4 matrix of RGB LEDs `_ +* `Pimoroni 5x5 RGB Matrix Breakout `_ Dependencies diff --git a/adafruit_is31fl3731/keybow2040.py b/adafruit_is31fl3731/keybow2040.py index d8946a9..58677aa 100644 --- a/adafruit_is31fl3731/keybow2040.py +++ b/adafruit_is31fl3731/keybow2040.py @@ -3,7 +3,7 @@ # SPDX-License-Identifier: MIT """ -`adafruit_is31fl3731.charlie_bonnet` +`adafruit_is31fl3731.keybow2040` ==================================================== CircuitPython driver for the IS31FL3731 charlieplex IC. diff --git a/adafruit_is31fl3731/rgbmatrix5x5.py b/adafruit_is31fl3731/rgbmatrix5x5.py new file mode 100644 index 0000000..916c9a7 --- /dev/null +++ b/adafruit_is31fl3731/rgbmatrix5x5.py @@ -0,0 +1,93 @@ +# SPDX-FileCopyrightText: Tony DiCola 2017 for Adafruit Industries +# SPDX-FileCopyrightText: Melissa LeBlanc-Williams 2021 for Adafruit Industries +# SPDX-FileCopyrightText: David Glaude 2021 +# SPDX-FileCopyrightText: James Carr 2021 + +# +# SPDX-License-Identifier: MIT + +""" +`adafruit_is31fl3731.rgbmatrix5x5` +==================================================== + +CircuitPython driver for the IS31FL3731 charlieplex IC. + + +* Author(s): Tony DiCola, Melissa LeBlanc-Williams, David Glaude, James Carr + +Implementation Notes +-------------------- + +**Hardware:** + +* `5x5 RGB Matrix Breakout + `_ + + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://github.com/adafruit/circuitpython/releases + +""" + +# imports +from . import IS31FL3731 + + +class RGBmatrix5x5(IS31FL3731): + """Supports the Pimoroni RGBmatrix5x5 with 5x5 matrix of RGB LEDs """ + + width = 25 + height = 3 + + def pixelrgb(self, x, y, r, g, b, blink=None, frame=None): + # pylint: disable=too-many-arguments + """ + Blink or brightness for x, y-pixel + + :param x: horizontal pixel position + :param y: vertical pixel position + :param r: red brightness value 0->255 + :param g: green brightness value 0->255 + :param b: blue brightness value 0->255 + :param blink: True to blink + :param frame: the frame to set the pixel + """ + x += y * 5 + + super().pixel(x, 0, r, blink, frame) + super().pixel(x, 1, g, blink, frame) + super().pixel(x, 2, b, blink, frame) + + @staticmethod + def pixel_addr(x, y): + lookup = [ + (118, 69, 85), + (117, 68, 101), + (116, 84, 100), + (115, 83, 99), + (114, 82, 98), + (132, 19, 35), + (133, 20, 36), + (134, 21, 37), + (112, 80, 96), + (113, 81, 97), + (131, 18, 34), + (130, 17, 50), + (129, 33, 49), + (128, 32, 48), + (127, 47, 63), + (125, 28, 44), + (124, 27, 43), + (123, 26, 42), + (122, 25, 58), + (121, 41, 57), + (126, 29, 45), + (15, 95, 111), + (8, 89, 105), + (9, 90, 106), + (10, 91, 107), + ] + + return lookup[x][y] diff --git a/docs/api.rst b/docs/api.rst index 6a34fc9..95e7dea 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -10,11 +10,20 @@ .. automodule:: adafruit_is31fl3731.charlie_wing :members: +.. automodule:: adafruit_is31fl3731.keybow2040 + :members: + +.. automodule:: adafruit_is31fl3731.led_shim + :members: + .. automodule:: adafruit_is31fl3731.matrix :members: -.. automodule:: adafruit_is31fl3731.scroll_phat_hd +.. automodule:: adafruit_is31fl3731.matrix_11x7 :members: -.. automodule:: adafruit_is31fl3731.led_shim +.. automodule:: adafruit_is31fl3731.rgbmatrix5x5 + :members: + +.. automodule:: adafruit_is31fl3731.scroll_phat_hd :members: diff --git a/docs/examples.rst b/docs/examples.rst index 6c51f3d..e14b4b8 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -47,11 +47,17 @@ libraries. CircuitPython does not support PIL/pillow (python imaging library)! :caption: examples/is31fl3731_pillow_numbers.py :linenos: -Led Shim Example ----------------- +Colorful Examples +----------------- -Example that work on the RGB Led Shim. +Example that works on the RGB Led Shim. .. literalinclude:: ../examples/is31fl3731_ledshim_rainbow.py :caption: examples/is31fl3731_ledshim_rainbow.py :linenos: + +Example that works on the RGB Matrix 5x5. + +.. literalinclude:: ../examples/is31fl3731_rgbmatrix5x5_rainbow.py + :caption: examples/is31fl3731_rgbmatrix5x5_rainbow.py + :linenos: diff --git a/examples/is31fl3731_keybow_2040_rainbow.py b/examples/is31fl3731_keybow_2040_rainbow.py index 92088a1..098ce37 100644 --- a/examples/is31fl3731_keybow_2040_rainbow.py +++ b/examples/is31fl3731_keybow_2040_rainbow.py @@ -19,7 +19,7 @@ import math import board -import adafruit_is31fl3731 +from adafruit_is31fl3731.keybow2040 import Keybow2040 as Display # pylint: disable=inconsistent-return-statements # pylint: disable=too-many-return-statements @@ -64,7 +64,7 @@ def hsv_to_rgb(hue, sat, val): i2c = board.I2C() # Set up 4x4 RGB matrix of Keybow 2040 -display = adafruit_is31fl3731.Keybow2040(i2c) +display = Display(i2c) step = 0 diff --git a/examples/is31fl3731_pillow_animated_gif.py b/examples/is31fl3731_pillow_animated_gif.py index e33f626..9d22cd8 100644 --- a/examples/is31fl3731_pillow_animated_gif.py +++ b/examples/is31fl3731_pillow_animated_gif.py @@ -57,13 +57,10 @@ loops = 1 # IS31FL3731 only supports 0-7 -if loops > 7: - loops = 7 +loops = min(loops, 7) # Get the frame count (maximum 8 frames) -frame_count = image.n_frames -if frame_count > 8: - frame_count = 8 +frame_count = min(image.n_frames, 8) # Load each frame of the gif onto the Matrix for frame in range(frame_count): diff --git a/examples/is31fl3731_rgbmatrix5x5_rainbow.py b/examples/is31fl3731_rgbmatrix5x5_rainbow.py new file mode 100644 index 0000000..d6b2442 --- /dev/null +++ b/examples/is31fl3731_rgbmatrix5x5_rainbow.py @@ -0,0 +1,134 @@ +# SPDX-FileCopyrightText: 2021 Sandy Macdonald, David Glaude, James Carr +# SPDX-License-Identifier: MIT + +""" +Example to display a rainbow animation on the 5x5 RGB Matrix Breakout. + +Usage: +Rename this file code.py and pop it on your Raspberry Pico's +CIRCUITPY drive. + +This example is for use on the Pico Explorer Base or other board that use the same SDA/SCL pin. + +Author(s): Sandy Macdonald, David Glaude, James Carr +""" + +import time +import math +import busio +import board + +from adafruit_is31fl3731.rgbmatrix5x5 import RGBmatrix5x5 as Display + + +def hsv_to_rgb(hue, sat, val): + # pylint: disable=too-many-return-statements + """ + Convert HSV colour to RGB + + :param hue: hue; 0.0-1.0 + :param sat: saturation; 0.0-1.0 + :param val: value; 0.0-1.0 + """ + + if sat == 0.0: + return val, val, val + + i = int(hue * 6.0) + + p = val * (1.0 - sat) + f = (hue * 6.0) - i + q = val * (1.0 - sat * f) + t = val * (1.0 - sat * (1.0 - f)) + + i %= 6 + + if i == 0: + return val, t, p + if i == 1: + return q, val, p + if i == 2: + return p, val, t + if i == 3: + return p, q, val + if i == 4: + return t, p, val + if i == 5: + return val, p, q + + # Will never reach here but it keeps pylint happier + return val, val, val + + +# Create the I2C bus on a Pico Explorer Base +i2c = busio.I2C(board.GP5, board.GP4) + +# Set up 5x5 RGB matrix Breakout +display = Display(i2c) + + +def test_pixels(r, g, b): + # Draw each row from left to right, top to bottom + for y in range(0, 5): + for x in range(0, 5): + display.fill(0) # Clear display + display.pixelrgb(x, y, r, g, b) + time.sleep(0.05) + + +def test_rows(r, g, b): + # Draw full rows from top to bottom + for y in range(0, 5): + display.fill(0) # Clear display + for x in range(0, 5): + display.pixelrgb(x, y, r, g, b) + time.sleep(0.2) + + +def test_columns(r, g, b): + # Draw full columns from left to right + for x in range(0, 5): + display.fill(0) # Clear display + for y in range(0, 5): + display.pixelrgb(x, y, r, g, b) + time.sleep(0.2) + + +def test_rainbow_sweep(): + step = 0 + + for _ in range(100): + for y in range(0, 5): + for x in range(0, 5): + pixel_hue = (x + y + (step / 20)) / 8 + pixel_hue = pixel_hue - int(pixel_hue) + pixel_hue += 0 + pixel_hue = pixel_hue - math.floor(pixel_hue) + + rgb = hsv_to_rgb(pixel_hue, 1, 1) + + display.pixelrgb( + x, y, int(rgb[0] * 255), int(rgb[1] * 255), int(rgb[2] * 255) + ) + + time.sleep(0.01) + step += 3 + + +while True: + test_pixels(64, 0, 0) # RED + test_pixels(0, 64, 0) # GREEN + test_pixels(0, 0, 64) # BLUE + test_pixels(64, 64, 64) # WHITE + + test_rows(64, 0, 0) # RED + test_rows(0, 64, 0) # GREEN + test_rows(0, 0, 64) # BLUE + test_rows(64, 64, 64) # WHITE + + test_columns(64, 0, 0) # RED + test_columns(0, 64, 0) # GREEN + test_columns(0, 0, 64) # BLUE + test_columns(64, 64, 64) # WHITE + + test_rainbow_sweep()