Repository: adafruit/Adafruit_CircuitPython_IS31FL3731 (language: python)

Issue:
Split library into package and adapt examples+doc
This is a response to #27 .

I have split the best I could the various driver, updated all the example and tested the one I could (mostly Scroll pHAT HD and LedShim).

The sub-driver for those two being done by me, I adapted the copyright now that it is in a separate file, for the other it is a copy of the original comment and copyright.

The move to __init__.py and cleaning done there is visible in the git history, but copy of the file to make sub-driver mean loosing the git history on those. Maybe there is a way to inherit this history???

I tested the other MCU example on the Scoll pHAT HD, but not on Blinka.

Exemples and README should be up to date.

There is one thing I would like to discuss, it's the fact that one piece of hardware is priviledged, and the other inherit from that one and modify the x, y and formula to write pixels. So Matrix is imported differently than all the other. I would prefer to have a super class that has no implementation and make each sub-driver specify things.
Swapping order of R and G LEDs, using board defined pins.
The final hardware swaps the order of the red and green LED elements, so this PR reflects that. I've also updated the rainbow example to use `board.I2C()` when setting up the I2C bus as there are board definitions for the Pimoroni RP2040 boards in CircuitPython now!
Add Pimoroni 11x7 LED Matrix Breakout
Hello. I've added support for the [Pimoroni 11x7 LED Matrix Breakout](https://shop.pimoroni.com/products/11x7-led-matrix-breakout). Copied the algorithm for mapping pixels from [their repository](https://github.com/pimoroni/matrix11x7-python/blob/master/library/matrix11x7/__init__.py) and added a new class. Hopefully it's of some use to someone! :-)



Discussion / hints:

Fix patch:
diff --git a/README.rst b/README.rst
index 912d2ba..0fd4124 100644
--- a/README.rst
+++ b/README.rst
@@ -67,11 +67,11 @@ Matrix:
 
 .. code:: python
 
-    import adafruit_is31fl3731
+    from adafruit_is31fl3731.matrix import Matrix
     import board
     import busio
     with busio.I2C(board.SCL, board.SDA) as i2c:
-        display = adafruit_is31fl3731.Matrix(i2c)
+        display = Matrix(i2c)
         display.fill(127)
 
 
@@ -79,11 +79,11 @@ Charlie Wing:
 
 .. code:: python
 
-    import adafruit_is31fl3731
+    from adafruit_is31fl3731.charlie_wing import CharlieWing
     import board
     import busio
     with busio.I2C(board.SCL, board.SDA) as i2c:
-        display = adafruit_is31fl3731.CharlieWing(i2c)
+        display = CharlieWing(i2c)
         display.fill(127)
 
         # Turn off pixel 4,4, change its brightness and turn it back on
diff --git a/adafruit_is31fl3731.py b/adafruit_is31fl3731/__init__.py
similarity index 68%
rename from adafruit_is31fl3731.py
rename to adafruit_is31fl3731/__init__.py
index bc1a1c3..2d65f4e 100644
--- a/adafruit_is31fl3731.py
+++ b/adafruit_is31fl3731/__init__.py
@@ -8,8 +8,9 @@
 
 CircuitPython driver for the IS31FL3731 charlieplex IC.
 
+Base library.
 
-* Author(s): Tony DiCola, Melissa LeBlanc-Williams
+* Author(s): Tony DiCola, Melissa LeBlanc-Williams, David Glaude
 
 Implementation Notes
 --------------------
@@ -22,16 +23,29 @@
 * `Adafruit 15x7 CharliePlex LED Matrix Display FeatherWings
   <https://www.adafruit.com/product/2965>`_
 
-* Pimoroni LED SHIM
-  <https://shop.pimoroni.com/products/led-shim>_
+* `Adafruit 16x8 CharliePlex LED Matrix Bonnets
+  <https://www.adafruit.com/product/4127>`_
 
-* Pimoroni Keybow 2040
-  <https://shop.pimoroni.com/products/keybow-2040>_
+* `Pimoroni 17x7 Scroll pHAT HD
+  <https://www.adafruit.com/product/3473>`_
+
+* `Pimoroni 28x3 (r,g,b) Led Shim
+  <https://www.adafruit.com/product/3831>`_
+
+* `Pimoroni LED SHIM
+  <https://shop.pimoroni.com/products/led-shim>`_
+
+* `Pimoroni Keybow 2040
+  <https://shop.pimoroni.com/products/keybow-2040>`_
+
+* `Pimoroni 11x7 LED Matrix Breakout
+  <https://shop.pimoroni.com/products/11x7-led-matrix-breakout>`_
 
 **Software and Dependencies:**
 
-* Adafruit CircuitPython firmware (2.2.0+) for the ESP8622 and M0-based boards:
+* Adafruit CircuitPython firmware for the supported boards:
   https://github.com/adafruit/circuitpython/releases
+
 """
 
 # imports
@@ -66,9 +80,10 @@
 _COLOR_OFFSET = const(0x24)
 
 
-class Matrix:
+class IS31FL3731:
     """
-    The Matrix class support the main function for driving the 16x9 matrix Display
+    The IS31FL3731 is an abstract class contain the main function related to this chip.
+    Each board needs to define width, height and pixel_addr.
 
     :param ~adafruit_bus_device.i2c_device i2c_device: the connected i2c bus i2c_device
     :param address: the device address; defaults to 0x74
@@ -283,6 +298,7 @@ def fill(self, color=None, blink=None, frame=None):
             for col in range(18):
                 self._register(frame, _BLINK_OFFSET + col, data)
 
+    # This function must be replaced for each board
     @staticmethod
     def pixel_addr(x, y):
         """Calulate the offset into the device array for x,y pixel"""
@@ -348,192 +364,3 @@ def image(self, img, blink=None, frame=None):
         for x in range(self.width):  # yes this double loop is slow,
             for y in range(self.height):  #  but these displays are small!
                 self.pixel(x, y, pixels[(x, y)], blink=blink, frame=frame)
-
-
-class CharlieWing(Matrix):
-    """Supports the Charlieplexed feather wing"""
-
-    width = 15
-    height = 7
-
-    @staticmethod
-    def pixel_addr(x, y):
-        """Calulate the offset into the device array for x,y pixel"""
-        if x > 7:
-            x = 15 - x
-            y += 8
-        else:
-            y = 7 - y
-        return x * 16 + y
-
-
-class CharlieBonnet(Matrix):
-    """Supports the Charlieplexed bonnet"""
-
-    width = 16
-    height = 8
-
-    @staticmethod
-    def pixel_addr(x, y):
-        """Calulate the offset into the device array for x,y pixel"""
-        if x >= 8:
-            return (x - 6) * 16 - (y + 1)
-        return (x + 1) * 16 + (7 - y)
-
-
-class ScrollPhatHD(Matrix):
-    """Supports the Scroll pHAT HD by Pimoroni"""
-
-    width = 17
-    height = 7
-
-    @staticmethod
-    def pixel_addr(x, y):
-        """Translate an x,y coordinate to a pixel index."""
-        if x <= 8:
-            x = 8 - x
-            y = 6 - y
-        else:
-            x = x - 8
-            y = y - 8
-        return x * 16 + y
-
-
-class LedShim(Matrix):
-    """Supports the LED SHIM by Pimoroni"""
-
-    width = 28
-    height = 3
-
-    def __init__(self, i2c, address=0x75):
-        super().__init__(i2c, address)
-
-    # pylint: disable-msg=too-many-arguments
-    def pixelrgb(self, x, r, g, b, blink=None, frame=None):
-        """
-        Blink or brightness for x-pixel
-
-        :param x: horizontal 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
-        """
-        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):
-        """Translate an x,y coordinate to a pixel index."""
-        if y == 0:
-            if x < 7:
-                return 118 - x
-            if x < 15:
-                return 141 - x
-            if x < 21:
-                return 106 + x
-            if x == 21:
-                return 15
-            return x - 14
-
-        if y == 1:
-            if x < 2:
-                return 69 - x
-            if x < 7:
-                return 86 - x
-            if x < 12:
-                return 28 - x
-            if x < 14:
-                return 45 - x
-            if x == 14:
-                return 47
-            if x == 15:
-                return 41
-            if x < 21:
-                return x + 9
-            if x == 21:
-                return 95
-            if x < 26:
-                return x + 67
-            return x + 50
-
-        if x == 0:
-            return 85
-        if x < 7:
-            return 102 - x
-        if x < 11:
-            return 44 - x
-        if x < 14:
-            return 61 - x
-        if x == 14:
-            return 63
-        if x < 17:
-            return 42 + x
-        if x < 21:
-            return x + 25
-        if x == 21:
-            return 111
-        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
-
-    # pylint: disable=too-many-arguments
-
-    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/adafruit_is31fl3731/charlie_bonnet.py b/adafruit_is31fl3731/charlie_bonnet.py
new file mode 100644
index 0000000..5dad110
--- /dev/null
+++ b/adafruit_is31fl3731/charlie_bonnet.py
@@ -0,0 +1,45 @@
+# SPDX-FileCopyrightText: Tony DiCola 2017 for Adafruit Industries
+#
+# SPDX-License-Identifier: MIT
+
+"""
+`adafruit_is31fl3731.charlie_bonnet`
+====================================================
+
+CircuitPython driver for the IS31FL3731 charlieplex IC.
+
+
+* Author(s): Tony DiCola, Melissa LeBlanc-Williams
+
+Implementation Notes
+--------------------
+
+**Hardware:**
+
+* `Adafruit 16x8 CharliePlex LED Matrix Bonnets
+  <https://www.adafruit.com/product/4127>`_
+
+
+**Software and Dependencies:**
+
+* Adafruit CircuitPython firmware for the supported boards:
+  https://github.com/adafruit/circuitpython/releases
+
+"""
+
+# imports
+from . import IS31FL3731
+
+
+class CharlieBonnet(IS31FL3731):
+    """Supports the Charlieplexed bonnet"""
+
+    width = 16
+    height = 8
+
+    @staticmethod
+    def pixel_addr(x, y):
+        """Calulate the offset into the device array for x,y pixel"""
+        if x >= 8:
+            return (x - 6) * 16 - (y + 1)
+        return (x + 1) * 16 + (7 - y)
diff --git a/adafruit_is31fl3731/charlie_wing.py b/adafruit_is31fl3731/charlie_wing.py
new file mode 100644
index 0000000..79d9224
--- /dev/null
+++ b/adafruit_is31fl3731/charlie_wing.py
@@ -0,0 +1,47 @@
+# SPDX-FileCopyrightText: Tony DiCola 2017 for Adafruit Industries
+#
+# SPDX-License-Identifier: MIT
+
+"""
+`adafruit_is31fl3731.charlie_wing`
+====================================================
+
+CircuitPython driver for the IS31FL3731 charlieplex IC.
+
+
+* Author(s): Tony DiCola, Melissa LeBlanc-Williams
+
+Implementation Notes
+--------------------
+
+**Hardware:**
+
+* `Adafruit 15x7 CharliePlex LED Matrix Display FeatherWings
+  <https://www.adafruit.com/product/2965>`_
+
+**Software and Dependencies:**
+
+* Adafruit CircuitPython firmware for the supported boards:
+  https://github.com/adafruit/circuitpython/releases
+
+"""
+
+# imports
+from . import IS31FL3731
+
+
+class CharlieWing(IS31FL3731):
+    """Supports the Charlieplexed feather wing"""
+
+    width = 15
+    height = 7
+
+    @staticmethod
+    def pixel_addr(x, y):
+        """Calulate the offset into the device array for x,y pixel"""
+        if x > 7:
+            x = 15 - x
+            y += 8
+        else:
+            y = 7 - y
+        return x * 16 + y
diff --git a/adafruit_is31fl3731/keybow2040.py b/adafruit_is31fl3731/keybow2040.py
new file mode 100644
index 0000000..d8946a9
--- /dev/null
+++ b/adafruit_is31fl3731/keybow2040.py
@@ -0,0 +1,86 @@
+# SPDX-FileCopyrightText: Tony DiCola 2017 for Adafruit Industries
+#
+# SPDX-License-Identifier: MIT
+
+"""
+`adafruit_is31fl3731.charlie_bonnet`
+====================================================
+
+CircuitPython driver for the IS31FL3731 charlieplex IC.
+
+
+* Author(s): Tony DiCola, Melissa LeBlanc-Williams
+
+Implementation Notes
+--------------------
+
+**Hardware:**
+
+* `Pimoroni Keybow 2040
+  <https://shop.pimoroni.com/products/keybow-2040>`_
+
+
+**Software and Dependencies:**
+
+* Adafruit CircuitPython firmware for the supported boards:
+  https://github.com/adafruit/circuitpython/releases
+
+"""
+
+# imports
+from . import IS31FL3731
+
+
+class Keybow2040(IS31FL3731):
+    """Supports the Pimoroni Keybow 2040 with 4x4 matrix of RGB LEDs """
+
+    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
+
+        :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 = (4 * (3 - x)) + y
+
+        super().pixel(x, 0, g, blink, frame)
+        super().pixel(x, 1, r, 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/adafruit_is31fl3731/led_shim.py b/adafruit_is31fl3731/led_shim.py
new file mode 100644
index 0000000..fbba938
--- /dev/null
+++ b/adafruit_is31fl3731/led_shim.py
@@ -0,0 +1,115 @@
+# SPDX-FileCopyrightText: Tony DiCola 2017 for Adafruit Industries
+#
+# SPDX-License-Identifier: MIT
+
+"""
+`adafruit_is31fl3731.led_shim`
+====================================================
+
+CircuitPython driver for the IS31FL3731 charlieplex IC.
+
+
+* Author: David Glaude
+
+Implementation Notes
+--------------------
+
+**Hardware:**
+
+* `Pimoroni 28 RGB Led Shim
+  <https://www.adafruit.com/product/3831>`_
+
+**Software and Dependencies:**
+
+* Adafruit CircuitPython firmware for the supported boards:
+  https://github.com/adafruit/circuitpython/releases
+
+"""
+
+# imports
+from . import IS31FL3731
+
+
+class LedShim(IS31FL3731):
+    """Supports the LED SHIM by Pimoroni"""
+
+    width = 28
+    height = 3
+
+    def __init__(self, i2c, address=0x75):
+        super().__init__(i2c, address)
+
+    # pylint: disable-msg=too-many-arguments
+    def pixelrgb(self, x, r, g, b, blink=None, frame=None):
+        """
+        Blink or brightness for x-pixel
+
+        :param x: horizontal 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
+        """
+        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):
+        """Translate an x,y coordinate to a pixel index."""
+        if y == 0:
+            if x < 7:
+                return 118 - x
+            if x < 15:
+                return 141 - x
+            if x < 21:
+                return 106 + x
+            if x == 21:
+                return 15
+            return x - 14
+
+        if y == 1:
+            if x < 2:
+                return 69 - x
+            if x < 7:
+                return 86 - x
+            if x < 12:
+                return 28 - x
+            if x < 14:
+                return 45 - x
+            if x == 14:
+                return 47
+            if x == 15:
+                return 41
+            if x < 21:
+                return x + 9
+            if x == 21:
+                return 95
+            if x < 26:
+                return x + 67
+            return x + 50
+
+        if x == 0:
+            return 85
+        if x < 7:
+            return 102 - x
+        if x < 11:
+            return 44 - x
+        if x < 14:
+            return 61 - x
+        if x == 14:
+            return 63
+        if x < 17:
+            return 42 + x
+        if x < 21:
+            return x + 25
+        if x == 21:
+            return 111
+        if x < 27:
+            return x + 83
+        return 93
diff --git a/adafruit_is31fl3731/matrix.py b/adafruit_is31fl3731/matrix.py
new file mode 100644
index 0000000..94a2c9e
--- /dev/null
+++ b/adafruit_is31fl3731/matrix.py
@@ -0,0 +1,42 @@
+# SPDX-FileCopyrightText: Tony DiCola 2017 for Adafruit Industries
+#
+# SPDX-License-Identifier: MIT
+
+"""
+`adafruit_is31fl3731.matrix`
+====================================================
+
+CircuitPython driver for the IS31FL3731 charlieplex IC.
+
+
+* Author(s): Tony DiCola, Melissa LeBlanc-Williams
+
+Implementation Notes
+--------------------
+
+**Hardware:**
+
+* `Adafruit 16x9 Charlieplexed PWM LED Matrix Driver - IS31FL3731
+  <https://www.adafruit.com/product/2946>`_
+
+**Software and Dependencies:**
+
+* Adafruit CircuitPython firmware for the supported boards:
+  https://github.com/adafruit/circuitpython/releases
+
+"""
+
+# imports
+from . import IS31FL3731
+
+
+class Matrix(IS31FL3731):
+    """Supports the Charlieplexed feather wing"""
+
+    width = 16
+    height = 9
+
+    @staticmethod
+    def pixel_addr(x, y):
+        """Calulate the offset into the device array for x,y pixel"""
+        return x + y * 16
diff --git a/adafruit_is31fl3731/matrix_11x7.py b/adafruit_is31fl3731/matrix_11x7.py
new file mode 100644
index 0000000..dc61d61
--- /dev/null
+++ b/adafruit_is31fl3731/matrix_11x7.py
@@ -0,0 +1,49 @@
+# SPDX-FileCopyrightText: Tony DiCola 2017 for Adafruit Industries
+#
+# SPDX-License-Identifier: MIT
+
+"""
+`adafruit_is31fl3731.charlie_bonnet`
+====================================================
+
+CircuitPython driver for the IS31FL3731 charlieplex IC.
+
+
+* Author(s): Tony DiCola, Melissa LeBlanc-Williams
+
+Implementation Notes
+--------------------
+
+**Hardware:**
+
+* `Pimoroni 11x7 LED Matrix Breakout <https://shop.pimoroni.com/products/11x7-led-matrix-breakout>`_
+
+
+**Software and Dependencies:**
+
+* Adafruit CircuitPython firmware for the supported boards:
+  https://github.com/adafruit/circuitpython/releases
+
+"""
+
+# imports
+from . import IS31FL3731
+
+
+class Matrix11x7(IS31FL3731):
+    """Supports the 11x7 LED Matrix Breakout by Pimoroni"""
+
+    width = 11
+    height = 7
+
+    def __init__(self, i2c, address=0x75):
+        super().__init__(i2c, address)
+
+    @staticmethod
+    def pixel_addr(x, y):
+        """Translate an x,y coordinate to a pixel index."""
+        if x <= 5:
+            r = x * 16 + y
+        else:
+            r = (x - 5) * 16 + y - 8
+        return r
diff --git a/adafruit_is31fl3731/scroll_phat_hd.py b/adafruit_is31fl3731/scroll_phat_hd.py
new file mode 100644
index 0000000..9504a36
--- /dev/null
+++ b/adafruit_is31fl3731/scroll_phat_hd.py
@@ -0,0 +1,48 @@
+# SPDX-FileCopyrightText: Tony DiCola 2017 for Adafruit Industries
+#
+# SPDX-License-Identifier: MIT
+
+"""
+`adafruit_is31fl3731.scroll_phat_hd`
+====================================================
+
+CircuitPython driver for the Pimoroni 17x7 Scroll pHAT HD.
+
+
+* Author: David Glaude
+
+Implementation Notes
+--------------------
+
+**Hardware:**
+
+* `Pimoroni 17x7 Scroll pHAT HD
+  <https://www.adafruit.com/product/3473>`_
+
+**Software and Dependencies:**
+
+* Adafruit CircuitPython firmware for the supported boards:
+  https://github.com/adafruit/circuitpython/releases
+
+"""
+
+# imports
+from . import IS31FL3731
+
+
+class ScrollPhatHD(IS31FL3731):
+    """Supports the Scroll pHAT HD by Pimoroni"""
+
+    width = 17
+    height = 7
+
+    @staticmethod
+    def pixel_addr(x, y):
+        """Translate an x,y coordinate to a pixel index."""
+        if x <= 8:
+            x = 8 - x
+            y = 6 - y
+        else:
+            x = x - 8
+            y = y - 8
+        return x * 16 + y
diff --git a/docs/api.rst b/docs/api.rst
index 49effac..6a34fc9 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -3,3 +3,18 @@
 
 .. automodule:: adafruit_is31fl3731
    :members:
+
+.. automodule:: adafruit_is31fl3731.charlie_bonnet
+  :members:
+
+.. automodule:: adafruit_is31fl3731.charlie_wing
+  :members:
+
+.. automodule:: adafruit_is31fl3731.matrix
+  :members:
+
+.. automodule:: adafruit_is31fl3731.scroll_phat_hd
+  :members:
+
+.. automodule:: adafruit_is31fl3731.led_shim
+  :members:
diff --git a/docs/examples.rst b/docs/examples.rst
index 3c7e1f8..6c51f3d 100644
--- a/docs/examples.rst
+++ b/docs/examples.rst
@@ -7,9 +7,11 @@ Ensure your device works with this simple test.
     :caption: examples/is31fl3731_simpletest.py
     :linenos:
 
-Other Examples
+Matrix Examples
 ---------------
 
+Other examples working on matrix display.
+
 .. literalinclude:: ../examples/is31fl3731_blink_example.py
     :caption: examples/is31fl3731_blink_example.py
     :linenos:
@@ -25,3 +27,31 @@ Other Examples
 .. literalinclude:: ../examples/is31fl3731_wave_example.py
     :caption: examples/is31fl3731_wave_example.py
     :linenos:
+
+Pillow Examples
+---------------
+
+Examples that utilize the Python Imaging Library (Pillow) for use on (Linux)
+computers that are using CPython with Adafruit Blinka to support CircuitPython
+libraries. CircuitPython does not support PIL/pillow (python imaging library)!
+
+.. literalinclude:: ../examples/is31fl3731_pillow_animated_gif.py
+    :caption: examples/is31fl3731_pillow_animated_gif.py
+    :linenos:
+
+.. literalinclude:: ../examples/is31fl3731_pillow_marquee.py
+    :caption: examples/is31fl3731_pillow_marquee.py
+    :linenos:
+
+.. literalinclude:: ../examples/is31fl3731_pillow_numbers.py
+    :caption: examples/is31fl3731_pillow_numbers.py
+    :linenos:
+
+Led Shim Example
+----------------
+
+Example that work on the RGB Led Shim.
+
+.. literalinclude:: ../examples/is31fl3731_ledshim_rainbow.py
+    :caption: examples/is31fl3731_ledshim_rainbow.py
+    :linenos:
diff --git a/examples/is31fl3731_blink_example.py b/examples/is31fl3731_blink_example.py
index 8fc8016..d27af3e 100644
--- a/examples/is31fl3731_blink_example.py
+++ b/examples/is31fl3731_blink_example.py
@@ -1,23 +1,25 @@
 # SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
 # SPDX-License-Identifier: MIT
 
-import busio
 import board
-import adafruit_is31fl3731
+import busio
+
+# uncomment next line if you are using Feather CharlieWing LED 15 x 7
+from adafruit_is31fl3731.charlie_wing import CharlieWing as Display
+
+# uncomment next line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
+# from adafruit_is31fl3731.matrix import Matrix as Display
+# uncomment next line if you are using Adafruit 16x8 Charlieplexed Bonnet
+# from adafruit_is31fl3731.charlie_bonnet import CharlieBonnet as Display
+# uncomment next line if you are using Pimoroni Scroll Phat HD LED 17 x 7
+# from adafruit_is31fl3731.scroll_phat_hd import ScrollPhatHD as Display
 
 i2c = busio.I2C(board.SCL, board.SDA)
 
 # array pattern in bits; top row-> bottom row, 8 bits in each row
 an_arrow = bytearray((0x08, 0x0C, 0xFE, 0xFF, 0xFE, 0x0C, 0x08, 0x00, 0x00))
 
-# initial display using Feather CharlieWing LED 15 x 7
-display = adafruit_is31fl3731.CharlieWing(i2c)
-# uncomment next line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
-# display = adafruit_is31fl3731.Matrix(i2c)
-# uncomment line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
-# display = adafruit_is31fl3731.CharlieBonnet(i2c)
-# initial display using Pimoroni Scroll Phat HD LED 17 x 7
-# display = adafruit_is31fl3731.ScrollPhatHD(i2c)
+display = Display(i2c)
 
 # first load the frame with the arrows; moves the an_arrow to the right in each
 # frame
diff --git a/examples/is31fl3731_frame_example.py b/examples/is31fl3731_frame_example.py
index 7e88ae2..f7411d0 100644
--- a/examples/is31fl3731_frame_example.py
+++ b/examples/is31fl3731_frame_example.py
@@ -4,21 +4,23 @@
 import time
 import board
 import busio
-import adafruit_is31fl3731
+
+# uncomment next line if you are using Feather CharlieWing LED 15 x 7
+from adafruit_is31fl3731.charlie_wing import CharlieWing as Display
+
+# uncomment next line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
+# from adafruit_is31fl3731.matrix import Matrix as Display
+# uncomment next line if you are using Adafruit 16x8 Charlieplexed Bonnet
+# from adafruit_is31fl3731.charlie_bonnet import CharlieBonnet as Display
+# uncomment next line if you are using Pimoroni Scroll Phat HD LED 17 x 7
+# from adafruit_is31fl3731.scroll_phat_hd import ScrollPhatHD as Display
 
 i2c = busio.I2C(board.SCL, board.SDA)
 
 # arrow pattern in bits; top row-> bottom row, 8 bits in each row
 arrow = bytearray((0x08, 0x0C, 0xFE, 0xFF, 0xFE, 0x0C, 0x08, 0x00, 0x00))
 
-# initial display using Feather CharlieWing LED 15 x 7
-display = adafruit_is31fl3731.CharlieWing(i2c)
-# uncomment line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
-# display = adafruit_is31fl3731.Matrix(i2c)
-# uncomment line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
-# display = adafruit_is31fl3731.CharlieBonnet(i2c)
-# initial display using Pimoroni Scroll Phat HD LED 17 x 7
-# display = adafruit_is31fl3731.ScrollPhatHD(i2c)
+display = Display(i2c)
 
 
 # first load the frame with the arrows; moves the arrow to the right in each
diff --git a/examples/is31fl3731_keybow_2040_rainbow.py b/examples/is31fl3731_keybow_2040_rainbow.py
index 5042797..92088a1 100644
--- a/examples/is31fl3731_keybow_2040_rainbow.py
+++ b/examples/is31fl3731_keybow_2040_rainbow.py
@@ -18,7 +18,6 @@
 import time
 import math
 import board
-import busio
 
 import adafruit_is31fl3731
 
@@ -62,7 +61,7 @@ def hsv_to_rgb(hue, sat, val):
         return (val, p, q)
 
 
-i2c = busio.I2C(board.GP5, board.GP4)
+i2c = board.I2C()
 
 # Set up 4x4 RGB matrix of Keybow 2040
 display = adafruit_is31fl3731.Keybow2040(i2c)
diff --git a/examples/is31fl3731_ledshim_rainbow.py b/examples/is31fl3731_ledshim_rainbow.py
index c7727a2..3617c31 100644
--- a/examples/is31fl3731_ledshim_rainbow.py
+++ b/examples/is31fl3731_ledshim_rainbow.py
@@ -4,44 +4,25 @@
 import time
 import board
 import busio
-import adafruit_is31fl3731
+from adafruit_is31fl3731.led_shim import LedShim as Display
 
 i2c = busio.I2C(board.SCL, board.SDA)
 
 # initial display if you are using Pimoroni LED SHIM
-display = adafruit_is31fl3731.LedShim(i2c)
+display = Display(i2c)
 
+# fmt: off
 # This list 28 colors from a rainbow...
 rainbow = [
-    (255, 0, 0),
-    (255, 54, 0),
-    (255, 109, 0),
-    (255, 163, 0),
-    (255, 218, 0),
-    (236, 255, 0),
-    (182, 255, 0),
-    (127, 255, 0),
-    (72, 255, 0),
-    (18, 255, 0),
-    (0, 255, 36),
-    (0, 255, 91),
-    (0, 255, 145),
-    (0, 255, 200),
-    (0, 255, 255),
-    (0, 200, 255),
-    (0, 145, 255),
-    (0, 91, 255),
-    (0, 36, 255),
-    (18, 0, 255),
-    (72, 0, 255),
-    (127, 0, 255),
-    (182, 0, 255),
-    (236, 0, 255),
-    (255, 0, 218),
-    (255, 0, 163),
-    (255, 0, 109),
-    (255, 0, 54),
+    (255, 0, 0), (255, 54, 0), (255, 109, 0), (255, 163, 0),
+    (255, 218, 0), (236, 255, 0), (182, 255, 0), (127, 255, 0),
+    (72, 255, 0), (18, 255, 0), (0, 255, 36), (0, 255, 91),
+    (0, 255, 145), (0, 255, 200), (0, 255, 255), (0, 200, 255),
+    (0, 145, 255), (0, 91, 255), (0, 36, 255), (18, 0, 255),
+    (72, 0, 255), (127, 0, 255), (182, 0, 255), (236, 0, 255),
+    (255, 0, 218), (255, 0, 163), (255, 0, 109), (255, 0, 54),
 ]
+# fmt: on
 
 
 for y in range(3):
diff --git a/examples/is31fl3731_pillow_animated_gif.py b/examples/is31fl3731_pillow_animated_gif.py
index ad90537..e33f626 100644
--- a/examples/is31fl3731_pillow_animated_gif.py
+++ b/examples/is31fl3731_pillow_animated_gif.py
@@ -18,14 +18,19 @@
 import sys
 import board
 from PIL import Image
-import adafruit_is31fl3731
+
+# uncomment next line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
+# from adafruit_is31fl3731.matrix import Matrix as Display
+# uncomment next line if you are using Adafruit 16x8 Charlieplexed Bonnet
+from adafruit_is31fl3731.charlie_bonnet import CharlieBonnet as Display
+
+# uncomment next line if you are using Pimoroni Scroll Phat HD LED 17 x 7
+# from adafruit_is31fl3731.scroll_phat_hd import ScrollPhatHD as Display
 
 i2c = board.I2C()
 
-# uncomment line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
-# display = adafruit_is31fl3731.Matrix(i2c)
-# uncomment line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
-display = adafruit_is31fl3731.CharlieBonnet(i2c)
+display = Display(i2c)
+
 
 # Open the gif
 if len(sys.argv) < 2:
diff --git a/examples/is31fl3731_pillow_marquee.py b/examples/is31fl3731_pillow_marquee.py
index edbfb47..e15d3a5 100644
--- a/examples/is31fl3731_pillow_marquee.py
+++ b/examples/is31fl3731_pillow_marquee.py
@@ -13,17 +13,21 @@
 
 import board
 from PIL import Image, ImageDraw, ImageFont
-import adafruit_is31fl3731
+
+# uncomment next line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
+# from adafruit_is31fl3731.matrix import Matrix as Display
+# uncomment next line if you are using Adafruit 16x8 Charlieplexed Bonnet
+from adafruit_is31fl3731.charlie_bonnet import CharlieBonnet as Display
+
+# uncomment next line if you are using Pimoroni Scroll Phat HD LED 17 x 7
+# from adafruit_is31fl3731.scroll_phat_hd import ScrollPhatHD as Display
 
 SCROLLING_TEXT = "You can display a personal message here..."
 BRIGHTNESS = 64  # Brightness can be between 0-255
 
 i2c = board.I2C()
 
-# uncomment line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
-# display = adafruit_is31fl3731.Matrix(i2c)
-# uncomment line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
-display = adafruit_is31fl3731.CharlieBonnet(i2c)
+display = Display(i2c)
 
 # Load a font
 font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 8)
diff --git a/examples/is31fl3731_pillow_numbers.py b/examples/is31fl3731_pillow_numbers.py
index ba2555c..8481c57 100644
--- a/examples/is31fl3731_pillow_numbers.py
+++ b/examples/is31fl3731_pillow_numbers.py
@@ -14,16 +14,20 @@
 
 import board
 from PIL import Image, ImageDraw, ImageFont
-import adafruit_is31fl3731
+
+# uncomment next line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
+# from adafruit_is31fl3731.matrix import Matrix as Display
+# uncomment next line if you are using Adafruit 16x8 Charlieplexed Bonnet
+from adafruit_is31fl3731.charlie_bonnet import CharlieBonnet as Display
+
+# uncomment next line if you are using Pimoroni Scroll Phat HD LED 17 x 7
+# from adafruit_is31fl3731.scroll_phat_hd import ScrollPhatHD as Display
 
 BRIGHTNESS = 32  # Brightness can be between 0-255
 
 i2c = board.I2C()
 
-# uncomment line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
-# display = adafruit_is31fl3731.Matrix(i2c)
-# uncomment line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
-display = adafruit_is31fl3731.CharlieBonnet(i2c)
+display = Display(i2c)
 
 display.fill(0)
 
diff --git a/examples/is31fl3731_text_example.py b/examples/is31fl3731_text_example.py
index 75cb84d..0ba44e5 100644
--- a/examples/is31fl3731_text_example.py
+++ b/examples/is31fl3731_text_example.py
@@ -4,19 +4,20 @@
 import board
 import busio
 import adafruit_framebuf
-import adafruit_is31fl3731
 
+# uncomment next line if you are using Feather CharlieWing LED 15 x 7
+# from adafruit_is31fl3731.charlie_wing import CharlieWing as Display
+# uncomment next line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
+# from adafruit_is31fl3731.matrix import Matrix as Display
+# uncomment next line if you are using Adafruit 16x8 Charlieplexed Bonnet
+from adafruit_is31fl3731.charlie_bonnet import CharlieBonnet as Display
+
+# uncomment next line if you are using Pimoroni Scroll Phat HD LED 17 x 7
+# from adafruit_is31fl3731.scroll_phat_hd import ScrollPhatHD as Display
 
 i2c = busio.I2C(board.SCL, board.SDA)
 
-# initial display using Feather CharlieWing LED 15 x 7
-# display = adafruit_is31fl3731.CharlieWing(i2c)
-# uncomment line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
-# display = adafruit_is31fl3731.Matrix(i2c)
-# uncomment line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
-display = adafruit_is31fl3731.CharlieBonnet(i2c)
-# initial display using Pimoroni Scroll Phat HD LED 17 x 7
-# display = adafruit_is31fl3731.ScrollPhatHD(i2c)
+display = Display(i2c)
 
 text_to_show = "Adafruit!!"
 
diff --git a/examples/is31fl3731_wave_example.py b/examples/is31fl3731_wave_example.py
index 283874c..6f83400 100644
--- a/examples/is31fl3731_wave_example.py
+++ b/examples/is31fl3731_wave_example.py
@@ -3,47 +3,27 @@
 
 import board
 import busio
-import adafruit_is31fl3731
+
+# uncomment next line if you are using Feather CharlieWing LED 15 x 7
+from adafruit_is31fl3731.charlie_wing import CharlieWing as Display
+
+# uncomment next line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
+# from adafruit_is31fl3731.matrix import Matrix as Display
+# uncomment next line if you are using Adafruit 16x8 Charlieplexed Bonnet
+# from adafruit_is31fl3731.charlie_bonnet import CharlieBonnet as Display
+# uncomment next line if you are using Pimoroni Scroll Phat HD LED 17 x 7
+# from adafruit_is31fl3731.scroll_phat_hd import ScrollPhatHD as Display
 
 i2c = busio.I2C(board.SCL, board.SDA)
 
-sweep = [
-    1,
-    2,
-    3,
-    4,
-    6,
-    8,
-    10,
-    15,
-    20,
-    30,
-    40,
-    60,
-    60,
-    40,
-    30,
-    20,
-    15,
-    10,
-    8,
-    6,
-    4,
-    3,
-    2,
-    1,
-]
+# fmt: off
+sweep = [ 1, 2, 3, 4, 6, 8, 10, 15, 20, 30, 40, 60,
+    60, 40, 30, 20, 15, 10, 8, 6, 4, 3, 2, 1, ]
+# fmt: on
 
 frame = 0
 
-# initialize display using Feather CharlieWing LED 15 x 7
-display = adafruit_is31fl3731.CharlieWing(i2c)
-# uncomment next line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
-# display = adafruit_is31fl3731.Matrix(i2c)
-# uncomment next line if you are using Adafruit 16x8 Charlieplexed Bonnet
-# display = adafruit_is31fl3731.CharlieBonnet(i2c)
-# initial display using Pimoroni Scroll Phat HD LED 17 x 7
-# display = adafruit_is31fl3731.ScrollPhatHD(i2c)
+display = Display(i2c)
 
 while True:
     for incr in range(24):
diff --git a/setup.py b/setup.py
index 508cfff..c5fb2a4 100644
--- a/setup.py
+++ b/setup.py
@@ -53,5 +53,5 @@
     "breakout hardware micropython circuitpython",
     # You can just specify the packages manually here if your project is
     # simple. Or you can use find_packages().
-    py_modules=["adafruit_is31fl3731"],
+    packages=["adafruit_is31fl3731"],
 )


Test patch:
diff --git a/examples/is31fl3731_simpletest.py b/examples/is31fl3731_simpletest.py
index 8e00c19..9997383 100644
--- a/examples/is31fl3731_simpletest.py
+++ b/examples/is31fl3731_simpletest.py
@@ -3,21 +3,20 @@
 
 import board
 import busio
-import adafruit_is31fl3731
 
-i2c = busio.I2C(board.SCL, board.SDA)
-
-# initialize display using Feather CharlieWing LED 15 x 7
-display = adafruit_is31fl3731.CharlieWing(i2c)
+# uncomment next line if you are using Feather CharlieWing LED 15 x 7
+from adafruit_is31fl3731.charlie_wing import CharlieWing as Display
 
 # uncomment next line if you are using Adafruit 16x9 Charlieplexed PWM LED Matrix
-# display = adafruit_is31fl3731.Matrix(i2c)
-
+# from adafruit_is31fl3731.matrix import Matrix as Display
 # uncomment next line if you are using Adafruit 16x8 Charlieplexed Bonnet
-# display = adafruit_is31fl3731.CharlieBonnet(i2c)
+# from adafruit_is31fl3731.charlie_bonnet import CharlieBonnet as Display
+# uncomment next line if you are using Pimoroni Scroll Phat HD LED 17 x 7
+# from adafruit_is31fl3731.scroll_phat_hd import ScrollPhatHD as Display
+
+i2c = busio.I2C(board.SCL, board.SDA)
 
-# initial display using Pimoroni Scroll Phat HD LED 17 x 7
-# display = adafruit_is31fl3731.ScrollPhatHD(i2c)
+display = Display(i2c)
 
 # draw a box on the display
 # first draw the top and bottom edges