diff --git a/adafruit_featherwing/matrix_featherwing.py b/adafruit_featherwing/matrix_featherwing.py new file mode 100755 index 0000000..a2afe33 --- /dev/null +++ b/adafruit_featherwing/matrix_featherwing.py @@ -0,0 +1,193 @@ +# The MIT License (MIT) +# +# Copyright (c) 2019 Melissa LeBlanc-Williams for Adafruit Industries LLC +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +`adafruit_featherwing.matrix_featherwing` +==================================================== + +Helper for using the `Adafruit 8x16 LED Matrix FeatherWing +`_. + +* Author(s): Melissa LeBlanc-Williams +""" + +__version__ = "0.0.0-auto.0" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_FeatherWing.git" + +import adafruit_ht16k33.matrix as matrix +from adafruit_featherwing import shared + +class MatrixFeatherWing: + """Class representing an `Adafruit 8x16 LED Matrix FeatherWing + `_. + + Automatically uses the feather's I2C bus.""" + def __init__(self, address=0x70): + self._matrix = matrix.Matrix16x8(shared.I2C_BUS, address) + self._matrix.auto_write = False + self.columns = 16 + self.rows = 8 + self._auto_write = True + + def __getitem__(self, key): + """ + Get the current value of a pixel + """ + x, y = key + return self.pixel(x, y) + + def __setitem__(self, key, value): + """ + Turn a pixel off or on + """ + x, y = key + self.pixel(x, y, value) + self._update() + + def _update(self): + """ + Update the Display automatically if auto_write is set to True + """ + if self._auto_write: + self._matrix.show() + + def pixel(self, x, y, color=None): + """ + Turn a pixel on or off or retrieve a pixel value + + :param int x: The pixel row + :param int y: The pixel column + :param color: Whether to turn the pixel on or off + :type color: int or bool + """ + value = self._matrix.pixel(x, y, color) + self._update() + return value + + def show(self): + """ + Update the Pixels. This is only needed if auto_write is set to False + This can be very useful for more advanced graphics effects. + """ + self._matrix.show() + + def fill(self, fill): + """ + Turn all pixels on or off + + :param bool fill: True turns all pixels on, False turns all pixels off + + """ + if isinstance(fill, bool): + self._matrix.fill(1 if fill else 0) + self._update() + else: + raise ValueError('Must set to either True or False.') + + def shift_right(self, rotate=False): + """ + Shift all pixels right + + :param rotate: (Optional) Rotate the shifted pixels to the left side (default=False) + """ + for y in range(0, self.rows): + last_pixel = self._matrix[self.columns - 1, y] if rotate else 0 + for x in range(self.columns - 1, 0, -1): + self._matrix[x, y] = self._matrix[x - 1, y] + self._matrix[0, y] = last_pixel + self._update() + + def shift_left(self, rotate=False): + """ + Shift all pixels left + + :param rotate: (Optional) Rotate the shifted pixels to the right side (default=False) + """ + for y in range(0, self.rows): + last_pixel = self._matrix[0, y] if rotate else 0 + for x in range(0, self.columns - 1): + self._matrix[x, y] = self._matrix[x + 1, y] + self._matrix[self.columns - 1, y] = last_pixel + self._update() + + def shift_up(self, rotate=False): + """ + Shift all pixels up + + :param rotate: (Optional) Rotate the shifted pixels to bottom (default=False) + """ + for x in range(0, self.columns): + last_pixel = self._matrix[x, self.rows - 1] if rotate else 0 + for y in range(self.rows - 1, 0, -1): + self._matrix[x, y] = self._matrix[x, y - 1] + self._matrix[x, 0] = last_pixel + self._update() + + def shift_down(self, rotate=False): + """ + Shift all pixels down + + :param rotate: (Optional) Rotate the shifted pixels to top (default=False) + """ + for x in range(0, self.columns): + last_pixel = self._matrix[x, 0] if rotate else 0 + for y in range(0, self.rows - 1): + self._matrix[x, y] = self._matrix[x, y + 1] + self._matrix[x, self.rows - 1] = last_pixel + self._update() + + @property + def auto_write(self): + """ + Whether or not we are automatically updating + If set to false, be sure to call show() to update + """ + return self._auto_write + + @auto_write.setter + def auto_write(self, write): + if isinstance(write, bool): + self._auto_write = write + + @property + def blink_rate(self): + """ + Blink Rate returns the current rate that the pixels blink. + 0 = Not Blinking + 1-3 = Successively slower blink rates + """ + return self._matrix.blink_rate + + @blink_rate.setter + def blink_rate(self, rate): + self._matrix.blink_rate = rate + + @property + def brightness(self): + """ + Brightness returns the current display brightness. + 0-15 = Dimmest to Brightest Setting + """ + return self._matrix.brightness + + @brightness.setter + def brightness(self, brightness): + self._matrix.brightness = brightness diff --git a/docs/api.rst b/docs/api.rst index 469668b..5927698 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -21,3 +21,6 @@ .. automodule:: adafruit_featherwing.gps_featherwing :members: + +.. automodule:: adafruit_featherwing.matrix_featherwing + :members: diff --git a/docs/examples.rst b/docs/examples.rst index ff1b1fe..7ae3b67 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -35,6 +35,10 @@ Ensure your device works with this simple test. :caption: examples/featherwing_gps_simpletest.py :linenos: +.. literalinclude:: ../examples/featherwing_matrix_simpletest.py + :caption: examples/featherwing_matrix_simpletest.py + :linenos: + Other Tests ------------ diff --git a/examples/featherwing_matrix_simpletest.py b/examples/featherwing_matrix_simpletest.py new file mode 100644 index 0000000..f2fffb5 --- /dev/null +++ b/examples/featherwing_matrix_simpletest.py @@ -0,0 +1,63 @@ +""" +This example will demonstrate some graphic effects and then +draw a smiley face and shift it around the display +""" +import time +from adafruit_featherwing import matrix_featherwing + +matrix = matrix_featherwing.MatrixFeatherWing() + +# Create a Fade-in Effect +matrix.brightness = 0 +matrix.fill(True) +for level in range(0, 16): + matrix.brightness = level + time.sleep(0.1) + +# Show the different Blink Rates +for level in range(3, -1, -1): + matrix.blink_rate = level + time.sleep(4) + +# Create a Fade-out Effect +for level in range(15, -1, -1): + matrix.brightness = level + time.sleep(0.1) +matrix.fill(False) + +# Reset the brightness to full +matrix.brightness = 15 + +# Clear the Screen +matrix.fill(False) + +# Draw a Smiley Face +for row in range(2, 6): + matrix[row, 0] = 1 + matrix[row, 7] = 1 + +for column in range(2, 6): + matrix[0, column] = 1 + matrix[7, column] = 1 + +matrix[1, 1] = 1 +matrix[1, 6] = 1 +matrix[6, 1] = 1 +matrix[6, 6] = 1 +matrix[2, 5] = 1 +matrix[5, 5] = 1 +matrix[2, 3] = 1 +matrix[5, 3] = 1 +matrix[3, 2] = 1 +matrix[4, 2] = 1 + +# Move the Smiley Face Around +while True: + for frame in range(0, 8): + matrix.shift_right() + for frame in range(0, 8): + matrix.shift_down(True) + for frame in range(0, 8): + matrix.shift_left() + for frame in range(0, 8): + matrix.shift_up(True)