From 474a32578a5df59234e6984ec2359c7d94fbaaed Mon Sep 17 00:00:00 2001 From: sandyjmacdonald Date: Sun, 14 Feb 2021 17:36:49 +0000 Subject: [PATCH 1/5] Adding support for the 4x4 RGB matrix of Keybow 2040. --- adafruit_is31fl3731.py | 61 +++++++++++++++++++++- examples/is31fl3731_keybow_2040_rainbow.py | 59 +++++++++++++++++++++ 2 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 examples/is31fl3731_keybow_2040_rainbow.py diff --git a/adafruit_is31fl3731.py b/adafruit_is31fl3731.py index 0e18b7d..f815b2a 100644 --- a/adafruit_is31fl3731.py +++ b/adafruit_is31fl3731.py @@ -22,6 +22,12 @@ * `Adafruit 15x7 CharliePlex LED Matrix Display FeatherWings `_ +* Pimoroni LED SHIM + _ + +* Pimoroni Keybow 2040 + _ + **Software and Dependencies:** * Adafruit CircuitPython firmware (2.2.0+) for the ESP8622 and M0-based boards: @@ -399,7 +405,7 @@ class LedShim(Matrix): width = 28 height = 3 - def __init__(self, i2c, address=0x75): + def __init__(self, i2c, address=0x74): super().__init__(i2c, address) # pylint: disable-msg=too-many-arguments @@ -476,3 +482,56 @@ def pixel_addr(x, y): if x < 27: return x + 83 return 93 + +class Keybow2040(Matrix): + """Supports the Pimoroni Keybow 2040 with 4x4 matrix of RGB LEDs """ + + width = 16 + height = 3 + + def pixelrgb(self, x, y, r, g, b, blink=None, frame=None): + """ + 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 = x + (4 * y) + + super().pixel(x, 0, r, blink, frame) + super().pixel(x, 1, g, blink, frame) + super().pixel(x, 2, b, blink, frame) + + # pylint: disable=inconsistent-return-statements + # pylint: disable=too-many-return-statements + # pylint: disable=too-many-branches + + @staticmethod + def pixel_addr(x, y): + + lookup = [ + (120, 88, 104), # 0, 0 + (136, 40, 72), # 1, 0 + (112, 80, 96), # 2, 0 + (128, 32, 64), # 3, 0 + (121, 89, 105), # 0, 1 + (137, 41, 73), # 1, 1 + (113, 81, 97), # 2, 1 + (129, 33, 65), # 3, 1 + (122, 90, 106), # 0, 2 + (138, 25, 74), # 1, 2 + (114, 82, 98), # 2, 2 + (130, 17, 66), # 3, 2 + (123, 91, 107), # 0, 3 + (139, 26, 75), # 1, 3 + (115, 83, 99), # 2, 3 + (131, 18, 67) # 3, 3 + ] + + return lookup[x][y] + diff --git a/examples/is31fl3731_keybow_2040_rainbow.py b/examples/is31fl3731_keybow_2040_rainbow.py new file mode 100644 index 0000000..b86b92c --- /dev/null +++ b/examples/is31fl3731_keybow_2040_rainbow.py @@ -0,0 +1,59 @@ +import time +import math +import board +import busio + +import adafruit_is31fl3731 + +i2c = busio.I2C(board.GP5, board.GP4) + +# Set up 4x4 RGB matrix of Keybow 2040 +display = adafruit_is31fl3731.Keybow2040(i2c) + +def hsv_to_rgb(h, s, v): + """ + Convert HSV colour to RGB + + :param h: hue; 0.0-1.0 + :param s: saturation; 0.0-1.0 + :param v: value; 0.0-1.0 + """ + if s == 0.0: + return (v, v, v) + + i = int(h * 6.0) + + f = (h * 6.0) - i + q = v * (1.0 - s * f) + t = v * (1.0 - s * (1.0 - f)) + + i %= 6 + + if i == 0: + return (v, t, p) + if i == 1: + return (q, v, p) + if i == 2: + return (p, v, t) + if i == 3: + return (p, q, v) + if i == 4: + return (t, p, v) + if i == 5: + return (v, p, q) + +i = 0 +while True: + i = i + 1 + for y in range(0, 4): + for x in range(0, 4): + hue = (x + y + (i / 20)) / 8 + hue = hue - int(hue) + hue += 0 + hue = hue - math.floor(hue) + + rgb = hsv_to_rgb(hue, 1, 1) + + display.pixelrgb(x, y, int(rgb[0] * 255), int(rgb[1] * 255), int(rgb[2] * 255)) + + time.sleep(0.01) From 78ec1263a8774c79cdc991f3802531f16fd8c8a3 Mon Sep 17 00:00:00 2001 From: sandyjmacdonald Date: Sun, 14 Feb 2021 17:43:28 +0000 Subject: [PATCH 2/5] Reverting change in LED SHIM I2C address. --- adafruit_is31fl3731.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_is31fl3731.py b/adafruit_is31fl3731.py index f815b2a..5774fe6 100644 --- a/adafruit_is31fl3731.py +++ b/adafruit_is31fl3731.py @@ -405,7 +405,7 @@ class LedShim(Matrix): width = 28 height = 3 - def __init__(self, i2c, address=0x74): + def __init__(self, i2c, address=0x75): super().__init__(i2c, address) # pylint: disable-msg=too-many-arguments From 6e2c196df36da955680e3332dde293e33529b7a4 Mon Sep 17 00:00:00 2001 From: sandyjmacdonald Date: Sun, 14 Feb 2021 17:58:22 +0000 Subject: [PATCH 3/5] Adding license details to example. --- README.rst | 1 + examples/is31fl3731_keybow_2040_rainbow.py | 3 +++ 2 files changed, 4 insertions(+) diff --git a/README.rst b/README.rst index 61fa057..912d2ba 100644 --- a/README.rst +++ b/README.rst @@ -22,6 +22,7 @@ This driver supports the following hardware: * `Adafruit 16x8 CharliePlex LED Matrix Bonnets `_ * `Pimoroni 17x7 Scroll pHAT HD `_ * `Pimoroni 28x3 (r,g,b) Led Shim `_ +* `Pimoroni Keybow 2040 with 4x4 matrix of RGB LEDs `_ Dependencies diff --git a/examples/is31fl3731_keybow_2040_rainbow.py b/examples/is31fl3731_keybow_2040_rainbow.py index b86b92c..74621a9 100644 --- a/examples/is31fl3731_keybow_2040_rainbow.py +++ b/examples/is31fl3731_keybow_2040_rainbow.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 Sandy Macdonald +# SPDX-License-Identifier: MIT + import time import math import board From 40877571aabe5995ddcb5e1bda35ab30522ab19c Mon Sep 17 00:00:00 2001 From: sandyjmacdonald Date: Sun, 14 Feb 2021 20:20:25 +0000 Subject: [PATCH 4/5] Linting and reformatting. --- adafruit_is31fl3731.py | 34 ++++----- examples/is31fl3731_keybow_2040_rainbow.py | 88 +++++++++++++--------- 2 files changed, 71 insertions(+), 51 deletions(-) diff --git a/adafruit_is31fl3731.py b/adafruit_is31fl3731.py index 5774fe6..0243fb3 100644 --- a/adafruit_is31fl3731.py +++ b/adafruit_is31fl3731.py @@ -483,6 +483,7 @@ def pixel_addr(x, y): return x + 83 return 93 + class Keybow2040(Matrix): """Supports the Pimoroni Keybow 2040 with 4x4 matrix of RGB LEDs """ @@ -515,23 +516,22 @@ def pixelrgb(self, x, y, r, g, b, blink=None, frame=None): def pixel_addr(x, y): lookup = [ - (120, 88, 104), # 0, 0 - (136, 40, 72), # 1, 0 - (112, 80, 96), # 2, 0 - (128, 32, 64), # 3, 0 - (121, 89, 105), # 0, 1 - (137, 41, 73), # 1, 1 - (113, 81, 97), # 2, 1 - (129, 33, 65), # 3, 1 - (122, 90, 106), # 0, 2 - (138, 25, 74), # 1, 2 - (114, 82, 98), # 2, 2 - (130, 17, 66), # 3, 2 - (123, 91, 107), # 0, 3 - (139, 26, 75), # 1, 3 - (115, 83, 99), # 2, 3 - (131, 18, 67) # 3, 3 + (120, 88, 104), # 0, 0 + (136, 40, 72), # 1, 0 + (112, 80, 96), # 2, 0 + (128, 32, 64), # 3, 0 + (121, 89, 105), # 0, 1 + (137, 41, 73), # 1, 1 + (113, 81, 97), # 2, 1 + (129, 33, 65), # 3, 1 + (122, 90, 106), # 0, 2 + (138, 25, 74), # 1, 2 + (114, 82, 98), # 2, 2 + (130, 17, 66), # 3, 2 + (123, 91, 107), # 0, 3 + (139, 26, 75), # 1, 3 + (115, 83, 99), # 2, 3 + (131, 18, 67), # 3, 3 ] return lookup[x][y] - diff --git a/examples/is31fl3731_keybow_2040_rainbow.py b/examples/is31fl3731_keybow_2040_rainbow.py index 74621a9..bf2d635 100644 --- a/examples/is31fl3731_keybow_2040_rainbow.py +++ b/examples/is31fl3731_keybow_2040_rainbow.py @@ -1,6 +1,20 @@ # SPDX-FileCopyrightText: 2021 Sandy Macdonald # SPDX-License-Identifier: MIT +""" +Example to display a rainbow animation on the RGB LED keys of the +Keybow 2040. + +Usage: +Rename this file code.py and pop it on your Keybow 2040's +CIRCUITPY drive. + +This example is for use on the Keybow 2040 only, due to the way +that the LEDs are mapped out. + +Author(s): Sandy Macdonald. +""" + import time import math import board @@ -8,55 +22,61 @@ import adafruit_is31fl3731 -i2c = busio.I2C(board.GP5, board.GP4) - -# Set up 4x4 RGB matrix of Keybow 2040 -display = adafruit_is31fl3731.Keybow2040(i2c) -def hsv_to_rgb(h, s, v): +def hsv_to_rgb(hue, sat, val): """ Convert HSV colour to RGB - :param h: hue; 0.0-1.0 - :param s: saturation; 0.0-1.0 - :param v: value; 0.0-1.0 + :param hue: hue; 0.0-1.0 + :param sat: saturation; 0.0-1.0 + :param val: value; 0.0-1.0 """ - if s == 0.0: - return (v, v, v) - - i = int(h * 6.0) + if sat == 0.0: + return (val, val, val) - f = (h * 6.0) - i - q = v * (1.0 - s * f) - t = v * (1.0 - s * (1.0 - f)) + 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 (v, t, p) + return (val, t, p) if i == 1: - return (q, v, p) + return (q, val, p) if i == 2: - return (p, v, t) + return (p, val, t) if i == 3: - return (p, q, v) + return (p, q, val) if i == 4: - return (t, p, v) + return (t, p, val) if i == 5: - return (v, p, q) + return (val, p, q) + + +i2c = busio.I2C(board.GP5, board.GP4) + +# Set up 4x4 RGB matrix of Keybow 2040 +display = adafruit_is31fl3731.Keybow2040(i2c) + +step = 0 -i = 0 while True: - i = i + 1 + step += 1 for y in range(0, 4): - for x in range(0, 4): - hue = (x + y + (i / 20)) / 8 - hue = hue - int(hue) - hue += 0 - hue = hue - math.floor(hue) - - rgb = hsv_to_rgb(hue, 1, 1) - - display.pixelrgb(x, y, int(rgb[0] * 255), int(rgb[1] * 255), int(rgb[2] * 255)) - + for x in range(0, 4): + 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) From 52921514eee0a04ed7e402520e2e7bf927f9f902 Mon Sep 17 00:00:00 2001 From: sandyjmacdonald Date: Sun, 14 Feb 2021 20:35:23 +0000 Subject: [PATCH 5/5] Fixing up linting errors. --- adafruit_is31fl3731.py | 2 ++ examples/is31fl3731_keybow_2040_rainbow.py | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/adafruit_is31fl3731.py b/adafruit_is31fl3731.py index 0243fb3..bc1a1c3 100644 --- a/adafruit_is31fl3731.py +++ b/adafruit_is31fl3731.py @@ -490,6 +490,8 @@ class Keybow2040(Matrix): width = 16 height = 3 + # pylint: disable=too-many-arguments + def pixelrgb(self, x, y, r, g, b, blink=None, frame=None): """ Blink or brightness for x, y-pixel diff --git a/examples/is31fl3731_keybow_2040_rainbow.py b/examples/is31fl3731_keybow_2040_rainbow.py index bf2d635..5042797 100644 --- a/examples/is31fl3731_keybow_2040_rainbow.py +++ b/examples/is31fl3731_keybow_2040_rainbow.py @@ -22,6 +22,10 @@ import adafruit_is31fl3731 +# pylint: disable=inconsistent-return-statements +# pylint: disable=too-many-return-statements +# pylint: disable=invalid-name + def hsv_to_rgb(hue, sat, val): """ @@ -31,6 +35,7 @@ def hsv_to_rgb(hue, sat, val): :param sat: saturation; 0.0-1.0 :param val: value; 0.0-1.0 """ + if sat == 0.0: return (val, val, val)