├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── Adafruit_LED_Backpack ├── AlphaNum4.py ├── BicolorBargraph24.py ├── BicolorMatrix8x8.py ├── HT16K33.py ├── Matrix8x16.py ├── Matrix8x8.py ├── SevenSegment.py └── __init__.py ├── LICENSE ├── README.md ├── examples ├── alphanum4_test.py ├── bicolor_bargraph24_test.py ├── bicolor_matrix8x8_test.py ├── ex_7segment_clock.py ├── matrix8x16_test.py ├── matrix8x8_test.py └── sevensegment_test.py ├── ez_setup.py └── setup.py /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for opening an issue on an Adafruit Python library repository. To 2 | improve the speed of resolution please review the following guidelines and 3 | common troubleshooting steps below before creating the issue: 4 | 5 | - **Do not use GitHub issues for troubleshooting projects and issues.** Instead use 6 | the forums at http://forums.adafruit.com to ask questions and troubleshoot why 7 | something isn't working as expected. In many cases the problem is a common issue 8 | that you will more quickly receive help from the forum community. GitHub issues 9 | are meant for known defects in the code. If you don't know if there is a defect 10 | in the code then start with troubleshooting on the forum first. 11 | 12 | - **If following a tutorial or guide be sure you didn't miss a step.** Carefully 13 | check all of the steps and commands to run have been followed. Consult the 14 | forum if you're unsure or have questions about steps in a guide/tutorial. 15 | 16 | - **For Python/Raspberry Pi projects check these very common issues to ensure they don't apply**: 17 | 18 | - If you are receiving an **ImportError: No module named...** error then a 19 | library the code depends on is not installed. Check the tutorial/guide or 20 | README to ensure you have installed the necessary libraries. Usually the 21 | missing library can be installed with the `pip` tool, but check the tutorial/guide 22 | for the exact command. 23 | 24 | - **Be sure you are supplying adequate power to the board.** Check the specs of 25 | your board and power in an external power supply. In many cases just 26 | plugging a board into your computer is not enough to power it and other 27 | peripherals. 28 | 29 | - **Double check all soldering joints and connections.** Flakey connections 30 | cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints. 31 | 32 | If you're sure this issue is a defect in the code and checked the steps above 33 | please fill in the following fields to provide enough troubleshooting information. 34 | You may delete the guideline and text above to just leave the following details: 35 | 36 | - Platform/operating system (i.e. Raspberry Pi with Raspbian operating system, 37 | Windows 32-bit, Windows 64-bit, Mac OSX 64-bit, etc.): **INSERT PLATFORM/OPERATING 38 | SYSTEM HERE** 39 | 40 | - Python version (run `python -version` or `python3 -version`): **INSERT PYTHON 41 | VERSION HERE** 42 | 43 | - Error message you are receiving, including any Python exception traces: **INSERT 44 | ERROR MESAGE/EXCEPTION TRACES HERE*** 45 | 46 | - List the steps to reproduce the problem below (if possible attach code or commands 47 | to run): **LIST REPRO STEPS BELOW** 48 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for creating a pull request to contribute to Adafruit's GitHub code! 2 | Before you open the request please review the following guidelines and tips to 3 | help it be more easily integrated: 4 | 5 | - **Describe the scope of your change--i.e. what the change does and what parts 6 | of the code were modified.** This will help us understand any risks of integrating 7 | the code. 8 | 9 | - **Describe any known limitations with your change.** For example if the change 10 | doesn't apply to a supported platform of the library please mention it. 11 | 12 | - **Please run any tests or examples that can exercise your modified code.** We 13 | strive to not break users of the code and running tests/examples helps with this 14 | process. 15 | 16 | Thank you again for contributing! We will try to test and integrate the change 17 | as soon as we can, but be aware we have many GitHub repositories to manage and 18 | can't immediately respond to every request. There is no need to bump or check in 19 | on a pull request (it will clutter the discussion of the request). 20 | 21 | Also don't be worried if the request is closed or not integrated--sometimes the 22 | priorities of Adafruit's GitHub code (education, ease of use) might not match the 23 | priorities of the pull request. Don't fret, the open source community thrives on 24 | forks and GitHub makes it easy to keep your changes in a forked repo. 25 | 26 | After reviewing the guidelines above you can delete this text from the pull request. 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | *.egg-info 3 | *.pyc 4 | setuptools-* 5 | dist/* 6 | -------------------------------------------------------------------------------- /Adafruit_LED_Backpack/AlphaNum4.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Adafruit Industries 2 | # Author: Tony DiCola 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | # THE SOFTWARE. 21 | from . import HT16K33 22 | 23 | 24 | # Digit value to bitmask mapping: 25 | DIGIT_VALUES = { 26 | ' ': 0b0000000000000000, 27 | '!': 0b0000000000000110, 28 | '"': 0b0000001000100000, 29 | '#': 0b0001001011001110, 30 | '$': 0b0001001011101101, 31 | '%': 0b0000110000100100, 32 | '&': 0b0010001101011101, 33 | '\'': 0b0000010000000000, 34 | '(': 0b0010010000000000, 35 | ')': 0b0000100100000000, 36 | '*': 0b0011111111000000, 37 | '+': 0b0001001011000000, 38 | ',': 0b0000100000000000, 39 | '-': 0b0000000011000000, 40 | '.': 0b0000000000000000, 41 | '/': 0b0000110000000000, 42 | '0': 0b0000110000111111, 43 | '1': 0b0000000000000110, 44 | '2': 0b0000000011011011, 45 | '3': 0b0000000010001111, 46 | '4': 0b0000000011100110, 47 | '5': 0b0010000001101001, 48 | '6': 0b0000000011111101, 49 | '7': 0b0000000000000111, 50 | '8': 0b0000000011111111, 51 | '9': 0b0000000011101111, 52 | ':': 0b0001001000000000, 53 | ';': 0b0000101000000000, 54 | '<': 0b0010010000000000, 55 | '=': 0b0000000011001000, 56 | '>': 0b0000100100000000, 57 | '?': 0b0001000010000011, 58 | '@': 0b0000001010111011, 59 | 'A': 0b0000000011110111, 60 | 'B': 0b0001001010001111, 61 | 'C': 0b0000000000111001, 62 | 'D': 0b0001001000001111, 63 | 'E': 0b0000000011111001, 64 | 'F': 0b0000000001110001, 65 | 'G': 0b0000000010111101, 66 | 'H': 0b0000000011110110, 67 | 'I': 0b0001001000000000, 68 | 'J': 0b0000000000011110, 69 | 'K': 0b0010010001110000, 70 | 'L': 0b0000000000111000, 71 | 'M': 0b0000010100110110, 72 | 'N': 0b0010000100110110, 73 | 'O': 0b0000000000111111, 74 | 'P': 0b0000000011110011, 75 | 'Q': 0b0010000000111111, 76 | 'R': 0b0010000011110011, 77 | 'S': 0b0000000011101101, 78 | 'T': 0b0001001000000001, 79 | 'U': 0b0000000000111110, 80 | 'V': 0b0000110000110000, 81 | 'W': 0b0010100000110110, 82 | 'X': 0b0010110100000000, 83 | 'Y': 0b0001010100000000, 84 | 'Z': 0b0000110000001001, 85 | '[': 0b0000000000111001, 86 | '\\': 0b0010000100000000, 87 | ']': 0b0000000000001111, 88 | '^': 0b0000110000000011, 89 | '_': 0b0000000000001000, 90 | '`': 0b0000000100000000, 91 | 'a': 0b0001000001011000, 92 | 'b': 0b0010000001111000, 93 | 'c': 0b0000000011011000, 94 | 'd': 0b0000100010001110, 95 | 'e': 0b0000100001011000, 96 | 'f': 0b0000000001110001, 97 | 'g': 0b0000010010001110, 98 | 'h': 0b0001000001110000, 99 | 'i': 0b0001000000000000, 100 | 'j': 0b0000000000001110, 101 | 'k': 0b0011011000000000, 102 | 'l': 0b0000000000110000, 103 | 'm': 0b0001000011010100, 104 | 'n': 0b0001000001010000, 105 | 'o': 0b0000000011011100, 106 | 'p': 0b0000000101110000, 107 | 'q': 0b0000010010000110, 108 | 'r': 0b0000000001010000, 109 | 's': 0b0010000010001000, 110 | 't': 0b0000000001111000, 111 | 'u': 0b0000000000011100, 112 | 'v': 0b0010000000000100, 113 | 'w': 0b0010100000010100, 114 | 'x': 0b0010100011000000, 115 | 'y': 0b0010000000001100, 116 | 'z': 0b0000100001001000, 117 | '{': 0b0000100101001001, 118 | '|': 0b0001001000000000, 119 | '}': 0b0010010010001001, 120 | '~': 0b0000010100100000 121 | } 122 | 123 | 124 | class AlphaNum4(HT16K33.HT16K33): 125 | """Alphanumeric 14 segment LED backpack display.""" 126 | 127 | def __init__(self, **kwargs): 128 | """Initialize display. All arguments will be passed to the HT16K33 class 129 | initializer, including optional I2C address and bus number parameters. 130 | """ 131 | super(AlphaNum4, self).__init__(**kwargs) 132 | 133 | def set_digit_raw(self, pos, bitmask): 134 | """Set digit at position to raw bitmask value. Position should be a value 135 | of 0 to 3 with 0 being the left most digit on the display.""" 136 | if pos < 0 or pos > 3: 137 | # Ignore out of bounds digits. 138 | return 139 | # Set the digit bitmask value at the appropriate position. 140 | # Also set bit 7 (decimal point) if decimal is True. 141 | self.buffer[pos*2] = bitmask & 0xFF 142 | self.buffer[pos*2+1] = (bitmask >> 8) & 0xFF 143 | 144 | def set_decimal(self, pos, decimal): 145 | """Turn decimal point on or off at provided position. Position should be 146 | a value 0 to 3 with 0 being the left most digit on the display. Decimal 147 | should be True to turn on the decimal point and False to turn it off. 148 | """ 149 | if pos < 0 or pos > 3: 150 | # Ignore out of bounds digits. 151 | return 152 | # Set bit 14 (decimal point) based on provided value. 153 | if decimal: 154 | self.buffer[pos*2+1] |= (1 << 6) 155 | else: 156 | self.buffer[pos*2+1] &= ~(1 << 6) 157 | 158 | def set_digit(self, pos, digit, decimal=False): 159 | """Set digit at position to provided value. Position should be a value 160 | of 0 to 3 with 0 being the left most digit on the display. Digit should 161 | be any ASCII value 32-127 (printable ASCII). 162 | """ 163 | self.set_digit_raw(pos, DIGIT_VALUES.get(str(digit), 0x00)) 164 | if decimal: 165 | self.set_decimal(pos, True) 166 | 167 | def print_str(self, value, justify_right=True): 168 | """Print a 4 character long string of values to the display. Characters 169 | in the string should be any ASCII value 32 to 127 (printable ASCII). 170 | """ 171 | # Calculcate starting position of digits based on justification. 172 | pos = (4-len(value)) if justify_right else 0 173 | # Go through each character and print it on the display. 174 | for i, ch in enumerate(value): 175 | self.set_digit(i+pos, ch) 176 | 177 | def print_number_str(self, value, justify_right=True): 178 | """Print a 4 character long string of numeric values to the display. This 179 | function is similar to print_str but will interpret periods not as 180 | characters but as decimal points associated with the previous character. 181 | """ 182 | # Calculate length of value without decimals. 183 | length = len(value.translate(None, '.')) 184 | # Error if value without decimals is longer than 4 characters. 185 | if length > 4: 186 | self.print_str('----') 187 | return 188 | # Calculcate starting position of digits based on justification. 189 | pos = (4-length) if justify_right else 0 190 | # Go through each character and print it on the display. 191 | for i, ch in enumerate(value): 192 | if ch == '.': 193 | # Print decimal points on the previous digit. 194 | self.set_decimal(pos-1, True) 195 | else: 196 | self.set_digit(pos, ch) 197 | pos += 1 198 | 199 | def print_float(self, value, decimal_digits=2, justify_right=True): 200 | """Print a numeric value to the display. If value is negative 201 | it will be printed with a leading minus sign. Decimal digits is the 202 | desired number of digits after the decimal point. 203 | """ 204 | format_string = '{{0:0.{0}F}}'.format(decimal_digits) 205 | self.print_number_str(format_string.format(value), justify_right) 206 | 207 | def print_hex(self, value, justify_right=True): 208 | """Print a numeric value in hexadecimal. Value should be from 0 to FFFF. 209 | """ 210 | if value < 0 or value > 0xFFFF: 211 | # Ignore out of range values. 212 | return 213 | self.print_str('{0:X}'.format(value), justify_right) 214 | -------------------------------------------------------------------------------- /Adafruit_LED_Backpack/BicolorBargraph24.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Adafruit Industries 2 | # Author: Tony DiCola 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | # THE SOFTWARE. 21 | from __future__ import division 22 | 23 | from . import HT16K33 24 | 25 | 26 | # Color values as convenient globals. 27 | # This is a bitmask value where the first bit is green, and the second bit is 28 | # red. If both bits are set the color is yellow (red + green light). 29 | OFF = 0 30 | GREEN = 1 31 | RED = 2 32 | YELLOW = 3 33 | 34 | 35 | class BicolorBargraph24(HT16K33.HT16K33): 36 | """Bi-color 24 segment bar graph LED backpack display.""" 37 | 38 | def __init__(self, **kwargs): 39 | """Initialize display. All arguments will be passed to the HT16K33 class 40 | initializer, including optional I2C address and bus number parameters. 41 | """ 42 | super(BicolorBargraph24, self).__init__(**kwargs) 43 | 44 | def set_bar(self, bar, value): 45 | """Set bar to desired color. Bar should be a value of 0 to 23, and value 46 | should be OFF, GREEN, RED, or YELLOW. 47 | """ 48 | if bar < 0 or bar > 23: 49 | # Ignore out of bounds bars. 50 | return 51 | # Compute cathode and anode value. 52 | c = (bar if bar < 12 else bar - 12) // 4 53 | a = bar % 4 54 | if bar >= 12: 55 | a += 4 56 | # Set green LED based on 1st bit in value. 57 | self.set_led(c*16+a+8, 1 if value & GREEN > 0 else 0) 58 | # Set red LED based on 2nd bit in value. 59 | self.set_led(c*16+a, 1 if value & RED > 0 else 0) 60 | -------------------------------------------------------------------------------- /Adafruit_LED_Backpack/BicolorMatrix8x8.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Adafruit Industries 2 | # Author: Tony DiCola 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | # THE SOFTWARE. 21 | from .Matrix8x8 import Matrix8x8 22 | 23 | # Color values as convenient globals. 24 | # This is a bitmask value where the first bit is green, and the second bit is 25 | # red. If both bits are set the color is yellow (red + green light). 26 | OFF = 0 27 | GREEN = 1 28 | RED = 2 29 | YELLOW = 3 30 | 31 | 32 | class BicolorMatrix8x8(Matrix8x8): 33 | """Bi-color 8x8 matrix LED backpack display.""" 34 | 35 | def __init__(self, **kwargs): 36 | """Initialize display. All arguments will be passed to the HT16K33 class 37 | initializer, including optional I2C address and bus number parameters. 38 | """ 39 | super(BicolorMatrix8x8, self).__init__(**kwargs) 40 | 41 | def set_pixel(self, x, y, value): 42 | """Set pixel at position x, y to the given value. X and Y should be values 43 | of 0 to 8. Value should be OFF, GREEN, RED, or YELLOW. 44 | """ 45 | if x < 0 or x > 7 or y < 0 or y > 7: 46 | # Ignore out of bounds pixels. 47 | return 48 | # Set green LED based on 1st bit in value. 49 | self.set_led(y * 16 + x, 1 if value & GREEN > 0 else 0) 50 | # Set red LED based on 2nd bit in value. 51 | self.set_led(y * 16 + x + 8, 1 if value & RED > 0 else 0) 52 | 53 | def set_image(self, image): 54 | """Set display buffer to Python Image Library image. Red pixels (r=255, 55 | g=0, b=0) will map to red LEDs, green pixels (r=0, g=255, b=0) will map to 56 | green LEDs, and yellow pixels (r=255, g=255, b=0) will map to yellow LEDs. 57 | All other pixel values will map to an unlit LED value. 58 | """ 59 | imwidth, imheight = image.size 60 | if imwidth != 8 or imheight != 8: 61 | raise ValueError('Image must be an 8x8 pixels in size.') 62 | # Convert image to RGB and grab all the pixels. 63 | pix = image.convert('RGB').load() 64 | # Loop through each pixel and write the display buffer pixel. 65 | for x in [0, 1, 2, 3, 4, 5, 6, 7]: 66 | for y in [0, 1, 2, 3, 4, 5, 6, 7]: 67 | color = pix[(x, y)] 68 | # Handle the color of the pixel. 69 | if color == (255, 0, 0): 70 | self.set_pixel(x, y, RED) 71 | elif color == (0, 255, 0): 72 | self.set_pixel(x, y, GREEN) 73 | elif color == (255, 255, 0): 74 | self.set_pixel(x, y, YELLOW) 75 | else: 76 | # Unknown color, default to LED off. 77 | self.set_pixel(x, y, OFF) 78 | -------------------------------------------------------------------------------- /Adafruit_LED_Backpack/HT16K33.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Adafruit Industries 2 | # Author: Tony DiCola 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | # THE SOFTWARE. 21 | from __future__ import division 22 | 23 | 24 | # Constants 25 | DEFAULT_ADDRESS = 0x70 26 | HT16K33_BLINK_CMD = 0x80 27 | HT16K33_BLINK_DISPLAYON = 0x01 28 | HT16K33_BLINK_OFF = 0x00 29 | HT16K33_BLINK_2HZ = 0x02 30 | HT16K33_BLINK_1HZ = 0x04 31 | HT16K33_BLINK_HALFHZ = 0x06 32 | HT16K33_SYSTEM_SETUP = 0x20 33 | HT16K33_OSCILLATOR = 0x01 34 | HT16K33_CMD_BRIGHTNESS = 0xE0 35 | 36 | 37 | class HT16K33(object): 38 | """Driver for interfacing with a Holtek HT16K33 16x8 LED driver.""" 39 | 40 | def __init__(self, address=DEFAULT_ADDRESS, i2c=None, **kwargs): 41 | """Create an HT16K33 driver for device on the specified I2C address 42 | (defaults to 0x70) and I2C bus (defaults to platform specific bus). 43 | """ 44 | if i2c is None: 45 | import Adafruit_GPIO.I2C as I2C 46 | i2c = I2C 47 | self._device = i2c.get_i2c_device(address, **kwargs) 48 | self.buffer = bytearray([0]*16) 49 | 50 | def begin(self): 51 | """Initialize driver with LEDs enabled and all turned off.""" 52 | # Turn on the oscillator. 53 | self._device.writeList(HT16K33_SYSTEM_SETUP | HT16K33_OSCILLATOR, []) 54 | # Turn display on with no blinking. 55 | self.set_blink(HT16K33_BLINK_OFF) 56 | # Set display to full brightness. 57 | self.set_brightness(15) 58 | 59 | def set_blink(self, frequency): 60 | """Blink display at specified frequency. Note that frequency must be a 61 | value allowed by the HT16K33, specifically one of: HT16K33_BLINK_OFF, 62 | HT16K33_BLINK_2HZ, HT16K33_BLINK_1HZ, or HT16K33_BLINK_HALFHZ. 63 | """ 64 | if frequency not in [HT16K33_BLINK_OFF, HT16K33_BLINK_2HZ, 65 | HT16K33_BLINK_1HZ, HT16K33_BLINK_HALFHZ]: 66 | raise ValueError('Frequency must be one of HT16K33_BLINK_OFF, HT16K33_BLINK_2HZ, HT16K33_BLINK_1HZ, or HT16K33_BLINK_HALFHZ.') 67 | self._device.writeList(HT16K33_BLINK_CMD | HT16K33_BLINK_DISPLAYON | frequency, []) 68 | 69 | def set_brightness(self, brightness): 70 | """Set brightness of entire display to specified value (16 levels, from 71 | 0 to 15). 72 | """ 73 | if brightness < 0 or brightness > 15: 74 | raise ValueError('Brightness must be a value of 0 to 15.') 75 | self._device.writeList(HT16K33_CMD_BRIGHTNESS | brightness, []) 76 | 77 | def set_led(self, led, value): 78 | """Sets specified LED (value of 0 to 127) to the specified value, 0/False 79 | for off and 1 (or any True/non-zero value) for on. 80 | """ 81 | if led < 0 or led > 127: 82 | raise ValueError('LED must be value of 0 to 127.') 83 | # Calculate position in byte buffer and bit offset of desired LED. 84 | pos = led // 8 85 | offset = led % 8 86 | if not value: 87 | # Turn off the specified LED (set bit to zero). 88 | self.buffer[pos] &= ~(1 << offset) 89 | else: 90 | # Turn on the speciried LED (set bit to one). 91 | self.buffer[pos] |= (1 << offset) 92 | 93 | def write_display(self): 94 | """Write display buffer to display hardware.""" 95 | for i, value in enumerate(self.buffer): 96 | self._device.write8(i, value) 97 | 98 | def clear(self): 99 | """Clear contents of display buffer.""" 100 | for i, value in enumerate(self.buffer): 101 | self.buffer[i] = 0 102 | -------------------------------------------------------------------------------- /Adafruit_LED_Backpack/Matrix8x16.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 Adafruit Industries 2 | # Author: Carter Nelson 3 | # Modified from Matrix8x8 by Tony DiCola 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | from . import HT16K33 23 | from PIL import Image 24 | import time 25 | 26 | class Matrix8x16(HT16K33.HT16K33): 27 | """Single color 8x16 matrix LED backpack display.""" 28 | 29 | def __init__(self, **kwargs): 30 | """Initialize display. All arguments will be passed to the HT16K33 class 31 | initializer, including optional I2C address and bus number parameters. 32 | """ 33 | super(Matrix8x16, self).__init__(**kwargs) 34 | 35 | def set_pixel(self, x, y, value): 36 | """Set pixel at position x, y to the given value. X and Y should be values 37 | of 0 to 7 and 0 to 15, resp. Value should be 0 for off and non-zero for on. 38 | """ 39 | if x < 0 or x > 7 or y < 0 or y > 15: 40 | # Ignore out of bounds pixels. 41 | return 42 | self.set_led((7 - x) * 16 + y, value) 43 | 44 | def set_image(self, image): 45 | """Set display buffer to Python Image Library image. Image will be converted 46 | to 1 bit color and non-zero color values will light the LEDs. 47 | """ 48 | imwidth, imheight = image.size 49 | if imwidth != 8 or imheight != 16: 50 | raise ValueError('Image must be an 8x16 pixels in size.') 51 | # Convert image to 1 bit color and grab all the pixels. 52 | pix = image.convert('1').load() 53 | # Loop through each pixel and write the display buffer pixel. 54 | for x in xrange(8): 55 | for y in xrange(16): 56 | color = pix[(x, y)] 57 | # Handle the color of the pixel, off or on. 58 | if color == 0: 59 | self.set_pixel(x, y, 0) 60 | else: 61 | self.set_pixel(x, y, 1) 62 | 63 | def create_blank_image(self): 64 | return Image.new("RGB", (8, 16)) 65 | 66 | 67 | def horizontal_scroll(self, image, padding=True): 68 | """Returns a list of images which appear to scroll from left to right 69 | across the input image when displayed on the LED matrix in order. 70 | 71 | The input image is not limited to being 8x16. If the input image is 72 | larger than this, then all columns will be scrolled through but only 73 | the top 16 rows of pixels will be displayed. 74 | 75 | Keyword arguments: 76 | image -- The image to scroll across. 77 | padding -- If True, the animation will begin with a blank screen and the 78 | input image will scroll into the blank screen one pixel column at a 79 | time. Similarly, after scrolling across the whole input image, the 80 | end of the image will scroll out of a blank screen one column at a 81 | time. If this is not True, then only the input image will be scroll 82 | across without beginning or ending with "whitespace." 83 | (Default = True) 84 | """ 85 | 86 | image_list = list() 87 | width = image.size[0] 88 | # Scroll into the blank image. 89 | if padding: 90 | for x in range(8): 91 | section = image.crop((0, 0, x, 16)) 92 | display_section = self.create_blank_image() 93 | display_section.paste(section, (8 - x, 0, 8, 16)) 94 | image_list.append(display_section) 95 | 96 | #Scroll across the input image. 97 | for x in range(8, width + 1): 98 | section = image.crop((x - 8, 0, x, 16)) 99 | display_section = self.create_blank_image() 100 | display_section.paste(section, (0, 0, 8, 16)) 101 | image_list.append(display_section) 102 | 103 | #Scroll out, leaving the blank image. 104 | if padding: 105 | for x in range(width - 7, width + 1): 106 | section = image.crop((x, 0, width, 16)) 107 | display_section = self.create_blank_image() 108 | display_section.paste(section, (0, 0, 7 - (x - (width - 7)), 16)) 109 | image_list.append(display_section) 110 | 111 | #Return the list of images created 112 | return image_list 113 | 114 | def vertical_scroll(self, image, padding=True): 115 | """Returns a list of images which appear to scroll from top to bottom 116 | down the input image when displayed on the LED matrix in order. 117 | 118 | The input image is not limited to being 8x16. If the input image is 119 | largerthan this, then all rows will be scrolled through but only the 120 | left-most 8 columns of pixels will be displayed. 121 | 122 | Keyword arguments: 123 | image -- The image to scroll down. 124 | padding -- If True, the animation will begin with a blank screen and the 125 | input image will scroll into the blank screen one pixel row at a 126 | time. Similarly, after scrolling down the whole input image, the end 127 | of the image will scroll out of a blank screen one row at a time. 128 | If this is not True, then only the input image will be scroll down 129 | without beginning or ending with "whitespace." (Default = True) 130 | """ 131 | 132 | image_list = list() 133 | height = image.size[1] 134 | # Scroll into the blank image. 135 | if padding: 136 | for y in range(16): 137 | section = image.crop((0, 0, 8, y)) 138 | display_section = self.create_blank_image() 139 | display_section.paste(section, (0, 8 - y, 8, 16)) 140 | image_list.append(display_section) 141 | 142 | #Scroll across the input image. 143 | for y in range(16, height + 1): 144 | section = image.crop((0, y - 16, 8, y)) 145 | display_section = self.create_blank_image() 146 | display_section.paste(section, (0, 0, 8, 16)) 147 | image_list.append(display_section) 148 | 149 | #Scroll out, leaving the blank image. 150 | if padding: 151 | for y in range(height - 15, height + 1): 152 | section = image.crop((0, y, 8, height)) 153 | display_section = self.create_blank_image() 154 | display_section.paste(section, (0, 0, 8, 7 - (y - (height - 15)))) 155 | image_list.append(display_section) 156 | 157 | #Return the list of images created 158 | return image_list 159 | 160 | def animate(self, images, delay=.25): 161 | """Displays each of the input images in order, pausing for "delay" 162 | seconds after each image. 163 | 164 | Keyword arguments: 165 | image -- An iterable collection of Image objects. 166 | delay -- How many seconds to wait after displaying an image before 167 | displaying the next one. (Default = .25) 168 | """ 169 | for image in images: 170 | # Draw the image on the display buffer. 171 | self.set_image(image) 172 | 173 | # Draw the buffer to the display hardware. 174 | self.write_display() 175 | time.sleep(delay) 176 | -------------------------------------------------------------------------------- /Adafruit_LED_Backpack/Matrix8x8.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Adafruit Industries 2 | # Author: Tony DiCola 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | # THE SOFTWARE. 21 | from . import HT16K33 22 | from PIL import Image 23 | import time 24 | 25 | 26 | class Matrix8x8(HT16K33.HT16K33): 27 | """Single color 8x8 matrix LED backpack display.""" 28 | 29 | def __init__(self, **kwargs): 30 | """Initialize display. All arguments will be passed to the HT16K33 class 31 | initializer, including optional I2C address and bus number parameters. 32 | """ 33 | super(Matrix8x8, self).__init__(**kwargs) 34 | 35 | def set_pixel(self, x, y, value): 36 | """Set pixel at position x, y to the given value. X and Y should be values 37 | of 0 to 7. Value should be 0 for off and non-zero for on. 38 | """ 39 | if x < 0 or x > 7 or y < 0 or y > 7: 40 | # Ignore out of bounds pixels. 41 | return 42 | self.set_led(y * 16 + ((x + 7) % 8), value) 43 | 44 | def set_image(self, image): 45 | """Set display buffer to Python Image Library image. Image will be converted 46 | to 1 bit color and non-zero color values will light the LEDs. 47 | """ 48 | imwidth, imheight = image.size 49 | if imwidth != 8 or imheight != 8: 50 | raise ValueError('Image must be an 8x8 pixels in size.') 51 | # Convert image to 1 bit color and grab all the pixels. 52 | pix = image.convert('1').load() 53 | # Loop through each pixel and write the display buffer pixel. 54 | for x in [0, 1, 2, 3, 4, 5, 6, 7]: 55 | for y in [0, 1, 2, 3, 4, 5, 6, 7]: 56 | color = pix[(x, y)] 57 | # Handle the color of the pixel, off or on. 58 | if color == 0: 59 | self.set_pixel(x, y, 0) 60 | else: 61 | self.set_pixel(x, y, 1) 62 | 63 | def create_blank_image(self): 64 | return Image.new("RGB", (8, 8)) 65 | 66 | 67 | def horizontal_scroll(self, image, padding=True): 68 | """Returns a list of images which appear to scroll from left to right 69 | across the input image when displayed on the LED matrix in order. 70 | 71 | The input image is not limited to being 8x8. If the input image is 72 | larger than this, then all columns will be scrolled through but only 73 | the top 8 rows of pixels will be displayed. 74 | 75 | Keyword arguments: 76 | image -- The image to scroll across. 77 | padding -- If True, the animation will begin with a blank screen and the 78 | input image will scroll into the blank screen one pixel column at a 79 | time. Similarly, after scrolling across the whole input image, the 80 | end of the image will scroll out of a blank screen one column at a 81 | time. If this is not True, then only the input image will be scroll 82 | across without beginning or ending with "whitespace." 83 | (Default = True) 84 | """ 85 | 86 | image_list = list() 87 | width = image.size[0] 88 | # Scroll into the blank image. 89 | if padding: 90 | for x in range(8): 91 | section = image.crop((0, 0, x, 8)) 92 | display_section = self.create_blank_image() 93 | display_section.paste(section, (8 - x, 0, 8, 8)) 94 | image_list.append(display_section) 95 | 96 | #Scroll across the input image. 97 | for x in range(8, width + 1): 98 | section = image.crop((x - 8, 0, x, 8)) 99 | display_section = self.create_blank_image() 100 | display_section.paste(section, (0, 0, 8, 8)) 101 | image_list.append(display_section) 102 | 103 | #Scroll out, leaving the blank image. 104 | if padding: 105 | for x in range(width - 7, width + 1): 106 | section = image.crop((x, 0, width, 8)) 107 | display_section = self.create_blank_image() 108 | display_section.paste(section, (0, 0, 7 - (x - (width - 7)), 8)) 109 | image_list.append(display_section) 110 | 111 | #Return the list of images created 112 | return image_list 113 | 114 | def vertical_scroll(self, image, padding=True): 115 | """Returns a list of images which appear to scroll from top to bottom 116 | down the input image when displayed on the LED matrix in order. 117 | 118 | The input image is not limited to being 8x8. If the input image is 119 | largerthan this, then all rows will be scrolled through but only the 120 | left-most 8 columns of pixels will be displayed. 121 | 122 | Keyword arguments: 123 | image -- The image to scroll down. 124 | padding -- If True, the animation will begin with a blank screen and the 125 | input image will scroll into the blank screen one pixel row at a 126 | time. Similarly, after scrolling down the whole input image, the end 127 | of the image will scroll out of a blank screen one row at a time. 128 | If this is not True, then only the input image will be scroll down 129 | without beginning or ending with "whitespace." (Default = True) 130 | """ 131 | 132 | image_list = list() 133 | height = image.size[1] 134 | # Scroll into the blank image. 135 | if padding: 136 | for y in range(8): 137 | section = image.crop((0, 0, 8, y)) 138 | display_section = self.create_blank_image() 139 | display_section.paste(section, (0, 8 - y, 8, 8)) 140 | image_list.append(display_section) 141 | 142 | #Scroll across the input image. 143 | for y in range(8, height + 1): 144 | section = image.crop((0, y - 8, 8, y)) 145 | display_section = self.create_blank_image() 146 | display_section.paste(section, (0, 0, 8, 8)) 147 | image_list.append(display_section) 148 | 149 | #Scroll out, leaving the blank image. 150 | if padding: 151 | for y in range(height - 7, height + 1): 152 | section = image.crop((0, y, 8, height)) 153 | display_section = self.create_blank_image() 154 | display_section.paste(section, (0, 0, 8, 7 - (y - (height - 7)))) 155 | image_list.append(display_section) 156 | 157 | #Return the list of images created 158 | return image_list 159 | 160 | def animate(self, images, delay=.25): 161 | """Displays each of the input images in order, pausing for "delay" 162 | seconds after each image. 163 | 164 | Keyword arguments: 165 | image -- An iterable collection of Image objects. 166 | delay -- How many seconds to wait after displaying an image before 167 | displaying the next one. (Default = .25) 168 | """ 169 | for image in images: 170 | # Draw the image on the display buffer. 171 | self.set_image(image) 172 | 173 | # Draw the buffer to the display hardware. 174 | self.write_display() 175 | time.sleep(delay) 176 | -------------------------------------------------------------------------------- /Adafruit_LED_Backpack/SevenSegment.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Adafruit Industries 2 | # Author: Tony DiCola 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | # THE SOFTWARE. 21 | from . import HT16K33 22 | 23 | 24 | # Digit value to bitmask mapping: 25 | DIGIT_VALUES = { 26 | ' ': 0x00, 27 | '-': 0x40, 28 | '0': 0x3F, 29 | '1': 0x06, 30 | '2': 0x5B, 31 | '3': 0x4F, 32 | '4': 0x66, 33 | '5': 0x6D, 34 | '6': 0x7D, 35 | '7': 0x07, 36 | '8': 0x7F, 37 | '9': 0x6F, 38 | 'A': 0x77, 39 | 'B': 0x7C, 40 | 'C': 0x39, 41 | 'D': 0x5E, 42 | 'E': 0x79, 43 | 'F': 0x71 44 | } 45 | 46 | IDIGIT_VALUES = { 47 | ' ': 0x00, 48 | '-': 0x40, 49 | '0': 0x3F, 50 | '1': 0x30, 51 | '2': 0x5B, 52 | '3': 0x79, 53 | '4': 0x74, 54 | '5': 0x6D, 55 | '6': 0x6F, 56 | '7': 0x38, 57 | '8': 0x7F, 58 | '9': 0x7D, 59 | 'A': 0x7E, 60 | 'B': 0x67, 61 | 'C': 0x0F, 62 | 'D': 0x73, 63 | 'E': 0x4F, 64 | 'F': 0x4E 65 | } 66 | 67 | 68 | 69 | class SevenSegment(HT16K33.HT16K33): 70 | """Seven segment LED backpack display.""" 71 | 72 | def __init__(self, invert=False, **kwargs): 73 | """Initialize display. All arguments will be passed to the HT16K33 class 74 | initializer, including optional I2C address and bus number parameters. 75 | """ 76 | super(SevenSegment, self).__init__(**kwargs) 77 | self.invert = invert 78 | 79 | def set_invert(self, _invert): 80 | """Set whether the display is upside-down or not. 81 | """ 82 | self.invert = _invert 83 | 84 | def set_digit_raw(self, pos, bitmask): 85 | """Set digit at position to raw bitmask value. Position should be a value 86 | of 0 to 3 with 0 being the left most digit on the display.""" 87 | if pos < 0 or pos > 3: 88 | # Ignore out of bounds digits. 89 | return 90 | # Jump past the colon at position 2 by adding a conditional offset. 91 | offset = 0 if pos < 2 else 1 92 | 93 | # Calculate the correct position depending on orientation 94 | if self.invert: 95 | pos = 4-(pos+offset) 96 | else: 97 | pos = pos+offset 98 | 99 | # Set the digit bitmask value at the appropriate position. 100 | self.buffer[pos*2] = bitmask & 0xFF 101 | 102 | def set_decimal(self, pos, decimal): 103 | """Turn decimal point on or off at provided position. Position should be 104 | a value 0 to 3 with 0 being the left most digit on the display. Decimal 105 | should be True to turn on the decimal point and False to turn it off. 106 | """ 107 | if pos < 0 or pos > 3: 108 | # Ignore out of bounds digits. 109 | return 110 | # Jump past the colon at position 2 by adding a conditional offset. 111 | offset = 0 if pos < 2 else 1 112 | 113 | # Calculate the correct position depending on orientation 114 | if self.invert: 115 | pos = 4-(pos+offset) 116 | else: 117 | pos = pos+offset 118 | 119 | # Set bit 7 (decimal point) based on provided value. 120 | if decimal: 121 | self.buffer[pos*2] |= (1 << 7) 122 | else: 123 | self.buffer[pos*2] &= ~(1 << 7) 124 | 125 | def set_digit(self, pos, digit, decimal=False): 126 | """Set digit at position to provided value. Position should be a value 127 | of 0 to 3 with 0 being the left most digit on the display. Digit should 128 | be a number 0-9, character A-F, space (all LEDs off), or dash (-). 129 | """ 130 | if self.invert: 131 | self.set_digit_raw(pos, IDIGIT_VALUES.get(str(digit).upper(), 0x00)) 132 | else: 133 | self.set_digit_raw(pos, DIGIT_VALUES.get(str(digit).upper(), 0x00)) 134 | 135 | if decimal: 136 | self.set_decimal(pos, True) 137 | 138 | def set_colon(self, show_colon): 139 | """Turn the colon on with show colon True, or off with show colon False.""" 140 | if show_colon: 141 | self.buffer[4] |= 0x02 142 | else: 143 | self.buffer[4] &= (~0x02) & 0xFF 144 | 145 | def set_left_colon(self, show_colon): 146 | """Turn the left colon on with show color True, or off with show colon 147 | False. Only the large 1.2" 7-segment display has a left colon. 148 | """ 149 | if show_colon: 150 | self.buffer[4] |= 0x04 151 | self.buffer[4] |= 0x08 152 | else: 153 | self.buffer[4] &= (~0x04) & 0xFF 154 | self.buffer[4] &= (~0x08) & 0xFF 155 | 156 | def set_fixed_decimal(self, show_decimal): 157 | """Turn on/off the single fixed decimal point on the large 1.2" 7-segment 158 | display. Set show_decimal to True to turn on and False to turn off. 159 | Only the large 1.2" 7-segment display has this decimal point (in the 160 | upper right in the normal orientation of the display). 161 | """ 162 | if show_decimal: 163 | self.buffer[4] |= 0x10 164 | else: 165 | self.buffer[4] &= (~0x10) & 0xFF 166 | 167 | def print_number_str(self, value, justify_right=True): 168 | """Print a 4 character long string of numeric values to the display. 169 | Characters in the string should be any supported character by set_digit, 170 | or a decimal point. Decimal point characters will be associated with 171 | the previous character. 172 | """ 173 | # Calculate length of value without decimals. 174 | length = sum(map(lambda x: 1 if x != '.' else 0, value)) 175 | # Error if value without decimals is longer than 4 characters. 176 | if length > 4: 177 | self.print_number_str('----') 178 | return 179 | # Calculcate starting position of digits based on justification. 180 | pos = (4-length) if justify_right else 0 181 | # Go through each character and print it on the display. 182 | for i, ch in enumerate(value): 183 | if ch == '.': 184 | # Print decimal points on the previous digit. 185 | self.set_decimal(pos-1, True) 186 | else: 187 | self.set_digit(pos, ch) 188 | pos += 1 189 | 190 | def print_float(self, value, decimal_digits=2, justify_right=True): 191 | """Print a numeric value to the display. If value is negative 192 | it will be printed with a leading minus sign. Decimal digits is the 193 | desired number of digits after the decimal point. 194 | """ 195 | format_string = '{{0:0.{0}F}}'.format(decimal_digits) 196 | self.print_number_str(format_string.format(value), justify_right) 197 | 198 | def print_hex(self, value, justify_right=True): 199 | """Print a numeric value in hexadecimal. Value should be from 0 to FFFF. 200 | """ 201 | if value < 0 or value > 0xFFFF: 202 | # Ignore out of range values. 203 | return 204 | self.print_number_str('{0:X}'.format(value), justify_right) 205 | -------------------------------------------------------------------------------- /Adafruit_LED_Backpack/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Adafruit_Python_LED_Backpack/a0a91e0bb0a9a16f898b591137a9f091dee6b4ee/Adafruit_LED_Backpack/__init__.py -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Adafruit Industries 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | !! DEPRECATED !! 2 | ================ 3 | 4 | This library is deprecated and has been archived. Please use the new library here: 5 | https://github.com/adafruit/Adafruit_CircuitPython_HT16K33 6 | 7 | 8 | Adafruit Python LED Backpack 9 | ============================ 10 | 11 | Python library for controlling LED backpack displays such as 8x8 matrices, bar graphs, and 7/14-segment displays on a Raspberry Pi or BeagleBone Black. 12 | 13 | Designed specifically to work with the Adafruit LED backpack displays ----> https://learn.adafruit.com/adafruit-led-backpack/overview 14 | 15 | For all platforms (Raspberry Pi and Beaglebone Black) make sure your system is able to compile Python extensions. On Raspbian or Beaglebone Black's Debian/Ubuntu image you can ensure your system is ready by executing: 16 | 17 | ```` 18 | sudo apt-get update 19 | sudo apt-get install build-essential python-dev 20 | ```` 21 | 22 | You will also need to make sure the python-smbus and python-imaging library is installed by executing: 23 | 24 | ```` 25 | sudo apt-get install python-smbus python-imaging 26 | ```` 27 | 28 | Install the library by downloading with the download link on the right, unzipping the archive, navigating inside the library's directory and executing: 29 | 30 | ```` 31 | sudo python setup.py install 32 | ```` 33 | 34 | See example of usage in the examples folder. 35 | 36 | Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! 37 | 38 | Written by Tony DiCola for Adafruit Industries. 39 | 40 | MIT license, all text above must be included in any redistribution 41 | -------------------------------------------------------------------------------- /examples/alphanum4_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Adafruit Industries 2 | # Author: Tony DiCola 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | # THE SOFTWARE. 21 | import time 22 | 23 | from Adafruit_LED_Backpack import AlphaNum4 24 | 25 | 26 | # Create display instance on default I2C address (0x70) and bus number. 27 | display = AlphaNum4.AlphaNum4() 28 | 29 | # Alternatively, create a display with a specific I2C address and/or bus. 30 | # display = AlphaNum4.AlphaNum4(address=0x74, busnum=1) 31 | 32 | # On BeagleBone, try busnum=2 if IOError occurs with busnum=1 33 | # display = AlphaNum4.AlphaNum4(address=0x74, busnum=2) 34 | 35 | # Initialize the display. Must be called once before using the display. 36 | display.begin() 37 | 38 | # Scroll a message across the display 39 | message = 'This is an example of the 4 character alpha-numeric display. THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG? the quick brown fox jumps over the lazy dog!' 40 | pos = 0 41 | print('Press Ctrl-C to quit.') 42 | while True: 43 | # Clear the display buffer. 44 | display.clear() 45 | # Print a 4 character string to the display buffer. 46 | display.print_str(message[pos:pos+4]) 47 | # Write the display buffer to the hardware. This must be called to 48 | # update the actual display LEDs. 49 | display.write_display() 50 | # Increment position. Wrap back to 0 when the end is reached. 51 | pos += 1 52 | if pos > len(message)-4: 53 | pos = 0 54 | # Delay for half a second. 55 | time.sleep(0.5) 56 | 57 | # Note that the alphanumeric display has the same number printing functions 58 | # as the 7 segment display. See the sevensegment_test.py example for good 59 | # examples of these functions. 60 | -------------------------------------------------------------------------------- /examples/bicolor_bargraph24_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Adafruit Industries 2 | # Author: Tony DiCola 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | # THE SOFTWARE. 21 | import time 22 | 23 | from Adafruit_LED_Backpack import BicolorBargraph24 24 | 25 | 26 | # Create display instance on default I2C address (0x70) and bus number. 27 | display = BicolorBargraph24.BicolorBargraph24() 28 | 29 | # Alternatively, create a display with a specific I2C address and/or bus. 30 | # display = BicolorBargraph24.BicolorBargraph24(address=0x74, busnum=1) 31 | 32 | # On BeagleBone, try busnum=2 if IOError occurs with busnum=1 33 | # display = BicolorBargraph24.BicolorBargraph24(address=0x74, busnum=2) 34 | 35 | # Initialize the display. Must be called once before using the display. 36 | display.begin() 37 | 38 | # Run through all bars and colors at different brightness levels. 39 | print('Press Ctrl-C to quit.') 40 | brightness = 15 41 | while True: 42 | # Set display brightness (15 is max, 0 is min). 43 | display.set_brightness(brightness) 44 | for i in range(24): 45 | # Clear the display buffer. 46 | display.clear() 47 | # Light up 3 bars, each a different color and position. 48 | display.set_bar(i, BicolorBargraph24.RED) 49 | display.set_bar(i+1, BicolorBargraph24.GREEN) 50 | display.set_bar(i+2, BicolorBargraph24.YELLOW) 51 | # Write the display buffer to the hardware. This must be called to 52 | # update the actual display LEDs. 53 | display.write_display() 54 | # Delay for half a second. 55 | time.sleep(0.5) 56 | # Decrease brightness, wrapping back to 15 if necessary. 57 | brightness -= 1 58 | if brightness == 0: 59 | brightness = 15 60 | -------------------------------------------------------------------------------- /examples/bicolor_matrix8x8_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Adafruit Industries 2 | # Author: Tony DiCola 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | # THE SOFTWARE. 21 | import time 22 | from PIL import Image 23 | from PIL import ImageDraw 24 | 25 | from Adafruit_LED_Backpack import BicolorMatrix8x8 26 | 27 | 28 | # Create display instance on default I2C address (0x70) and bus number. 29 | display = BicolorMatrix8x8.BicolorMatrix8x8() 30 | 31 | # Alternatively, create a display with a specific I2C address and/or bus. 32 | # display = BicolorMatrix8x8.BicolorMatrix8x8(address=0x74, busnum=1) 33 | 34 | # On BeagleBone, try busnum=2 if IOError occurs with busnum=1 35 | # display = BicolorMatrix8x8.BicolorMatrix8x8(address=0x74, busnum=2) 36 | 37 | # Initialize the display. Must be called once before using the display. 38 | display.begin() 39 | 40 | # Run through each color and pixel. 41 | # Iterate through all colors. 42 | for c in [BicolorMatrix8x8.RED, BicolorMatrix8x8.GREEN, BicolorMatrix8x8.YELLOW]: 43 | # Iterate through all positions x and y. 44 | for x in range(8): 45 | for y in range(8): 46 | # Clear the display buffer. 47 | display.clear() 48 | # Set pixel at position i, j to appropriate color. 49 | display.set_pixel(x, y, c) 50 | # Write the display buffer to the hardware. This must be called to 51 | # update the actual display LEDs. 52 | display.write_display() 53 | # Delay for a quarter second. 54 | time.sleep(0.25) 55 | 56 | # Draw some colored shapes using the Python Imaging Library. 57 | 58 | # Clear the display buffer. 59 | display.clear() 60 | 61 | # First create an 8x8 RGB image. 62 | image = Image.new('RGB', (8, 8)) 63 | 64 | # Then create a draw instance. 65 | draw = ImageDraw.Draw(image) 66 | 67 | # Draw a filled yellow rectangle with red outline. 68 | draw.rectangle((0, 0, 7, 7), outline=(255, 0, 0), fill=(255, 255, 0)) 69 | 70 | # Draw an X with two green lines. 71 | draw.line((1, 1, 6, 6), fill=(0, 255, 0)) 72 | draw.line((1, 6, 6, 1), fill=(0, 255, 0)) 73 | 74 | # Draw the image on the display buffer. 75 | display.set_image(image) 76 | 77 | # Draw the buffer to the display hardware. 78 | display.write_display() 79 | 80 | # Pause for 5 seconds 81 | time.sleep(5) 82 | 83 | # Clear the screen again. 84 | display.clear() 85 | display.set_image(display.create_blank_image()) 86 | 87 | # Make the same image scrollable 88 | scrollable = display.horizontal_scroll(image) 89 | 90 | # Animate the scrollable image 91 | display.animate(scrollable) 92 | 93 | 94 | # See the SSD1306 library for more examples of using the Python Imaging Library 95 | # such as drawing text: https://github.com/adafruit/Adafruit_Python_SSD1306 96 | -------------------------------------------------------------------------------- /examples/ex_7segment_clock.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import time 4 | import datetime 5 | 6 | from Adafruit_LED_Backpack import SevenSegment 7 | 8 | # =========================================================================== 9 | # Clock Example 10 | # =========================================================================== 11 | segment = SevenSegment.SevenSegment(address=0x70) 12 | 13 | # Initialize the display. Must be called once before using the display. 14 | segment.begin() 15 | 16 | print "Press CTRL+Z to exit" 17 | 18 | # Continually update the time on a 4 char, 7-segment display 19 | while(True): 20 | now = datetime.datetime.now() 21 | hour = now.hour 22 | minute = now.minute 23 | second = now.second 24 | 25 | segment.clear() 26 | # Set hours 27 | segment.set_digit(0, int(hour / 10)) # Tens 28 | segment.set_digit(1, hour % 10) # Ones 29 | # Set minutes 30 | segment.set_digit(2, int(minute / 10)) # Tens 31 | segment.set_digit(3, minute % 10) # Ones 32 | # Toggle colon 33 | segment.set_colon(second % 2) # Toggle colon at 1Hz 34 | 35 | # Write the display buffer to the hardware. This must be called to 36 | # update the actual display LEDs. 37 | segment.write_display() 38 | 39 | # Wait a quarter second (less than 1 second to prevent colon blinking getting$ 40 | time.sleep(0.25) 41 | -------------------------------------------------------------------------------- /examples/matrix8x16_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Adafruit Industries 2 | # Author: Carter Nelson 3 | # Modified from matrix8x8_test.py by Tony DiCola 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | import time 23 | 24 | from PIL import Image 25 | from PIL import ImageDraw 26 | 27 | from Adafruit_LED_Backpack import Matrix8x16 28 | 29 | 30 | # Create display instance on default I2C address (0x70) and bus number. 31 | display = Matrix8x16.Matrix8x16() 32 | 33 | # Alternatively, create a display with a specific I2C address and/or bus. 34 | # display = Matrix8x16.Matrix8x16(address=0x74, busnum=1) 35 | 36 | # On BeagleBone, try busnum=2 if IOError occurs with busnum=1 37 | # display = Matrix8x16.Matrix8x16(address=0x74, busnum=2) 38 | 39 | # Initialize the display. Must be called once before using the display. 40 | display.begin() 41 | 42 | # Run through each pixel individually and turn it on. 43 | for x in range(8): 44 | for y in range(16): 45 | # Clear the display buffer. 46 | display.clear() 47 | # Set pixel at position i, j to on. To turn off a pixel set 48 | # the last parameter to 0. 49 | display.set_pixel(x, y, 1) 50 | # Write the display buffer to the hardware. This must be called to 51 | # update the actual display LEDs. 52 | display.write_display() 53 | # Delay for half a second. 54 | time.sleep(0.1) 55 | 56 | # Draw some shapes using the Python Imaging Library. 57 | 58 | # Clear the display buffer. 59 | display.clear() 60 | 61 | # First create an 8x16 1 bit color image. 62 | image = Image.new('1', (8, 16)) 63 | 64 | # Then create a draw instance. 65 | draw = ImageDraw.Draw(image) 66 | 67 | # Draw a rectangle with colored outline 68 | draw.rectangle((0,0,7,15), outline=255, fill=0) 69 | 70 | # Draw an X with two lines. 71 | draw.line((1,1,6,14), fill=255) 72 | draw.line((1,14,6,1), fill=255) 73 | 74 | # Draw the image on the display buffer. 75 | display.set_image(image) 76 | 77 | # Draw the buffer to the display hardware. 78 | display.write_display() 79 | 80 | # See the SSD1306 library for more examples of using the Python Imaging Library 81 | # such as drawing text: https://github.com/adafruit/Adafruit_Python_SSD1306 82 | -------------------------------------------------------------------------------- /examples/matrix8x8_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Adafruit Industries 2 | # Author: Tony DiCola 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | # THE SOFTWARE. 21 | import time 22 | 23 | from PIL import Image 24 | from PIL import ImageDraw 25 | 26 | from Adafruit_LED_Backpack import Matrix8x8 27 | 28 | 29 | # Create display instance on default I2C address (0x70) and bus number. 30 | display = Matrix8x8.Matrix8x8() 31 | 32 | # Alternatively, create a display with a specific I2C address and/or bus. 33 | # display = Matrix8x8.Matrix8x8(address=0x74, busnum=1) 34 | 35 | # On BeagleBone, try busnum=2 if IOError occurs with busnum=1 36 | # display = Matrix8x8.Matrix8x8(address=0x74, busnum=2) 37 | 38 | # Initialize the display. Must be called once before using the display. 39 | display.begin() 40 | 41 | # Run through each pixel individually and turn it on. 42 | for x in range(8): 43 | for y in range(8): 44 | # Clear the display buffer. 45 | display.clear() 46 | # Set pixel at position i, j to on. To turn off a pixel set 47 | # the last parameter to 0. 48 | display.set_pixel(x, y, 1) 49 | # Write the display buffer to the hardware. This must be called to 50 | # update the actual display LEDs. 51 | display.write_display() 52 | # Delay for half a second. 53 | time.sleep(0.5) 54 | 55 | # Draw some shapes using the Python Imaging Library. 56 | 57 | # Clear the display buffer. 58 | display.clear() 59 | 60 | # First create an 8x8 1 bit color image. 61 | image = Image.new('1', (8, 8)) 62 | 63 | # Then create a draw instance. 64 | draw = ImageDraw.Draw(image) 65 | 66 | # Draw a rectangle with colored outline 67 | draw.rectangle((0,0,7,7), outline=255, fill=0) 68 | 69 | # Draw an X with two lines. 70 | draw.line((1,1,6,6), fill=255) 71 | draw.line((1,6,6,1), fill=255) 72 | 73 | # Draw the image on the display buffer. 74 | display.set_image(image) 75 | 76 | # Draw the buffer to the display hardware. 77 | display.write_display() 78 | 79 | # See the SSD1306 library for more examples of using the Python Imaging Library 80 | # such as drawing text: https://github.com/adafruit/Adafruit_Python_SSD1306 81 | -------------------------------------------------------------------------------- /examples/sevensegment_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Adafruit Industries 2 | # Author: Tony DiCola 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | # THE SOFTWARE. 21 | import time 22 | 23 | from Adafruit_LED_Backpack import SevenSegment 24 | 25 | 26 | # Create display instance on default I2C address (0x70) and bus number. 27 | display = SevenSegment.SevenSegment() 28 | 29 | # Alternatively, create a display with a specific I2C address and/or bus. 30 | # display = SevenSegment.SevenSegment(address=0x74, busnum=1) 31 | 32 | # On BeagleBone, try busnum=2 if IOError occurs with busnum=1 33 | # display = SevenSegment.SevenSegment(address=0x74, busnum=2) 34 | 35 | # Initialize the display. Must be called once before using the display. 36 | display.begin() 37 | 38 | # Keep track of the colon being turned on or off. 39 | colon = False 40 | 41 | # Run through different number printing examples. 42 | print('Press Ctrl-C to quit.') 43 | numbers = [0.0, 1.0, -1.0, 0.55, -0.55, 10.23, -10.2, 100.5, -100.5] 44 | while True: 45 | # Print floating point values with default 2 digit precision. 46 | for i in numbers: 47 | # Clear the display buffer. 48 | display.clear() 49 | # Print a floating point number to the display. 50 | display.print_float(i) 51 | # Set the colon on or off (True/False). 52 | display.set_colon(colon) 53 | # Write the display buffer to the hardware. This must be called to 54 | # update the actual display LEDs. 55 | display.write_display() 56 | # Delay for a second. 57 | time.sleep(1.0) 58 | # Print the same numbers with 1 digit precision. 59 | for i in numbers: 60 | display.clear() 61 | display.print_float(i, decimal_digits=1) 62 | display.set_colon(colon) 63 | display.write_display() 64 | time.sleep(1.0) 65 | # Print the same numbers with no decimal digits and left justified. 66 | for i in numbers: 67 | display.clear() 68 | display.print_float(i, decimal_digits=0, justify_right=False) 69 | display.set_colon(colon) 70 | display.write_display() 71 | time.sleep(1.0) 72 | # Run through some hex digits. 73 | for i in range(0xFF): 74 | display.clear() 75 | display.print_hex(i) 76 | display.set_colon(colon) 77 | display.write_display() 78 | time.sleep(0.25) 79 | # Run through hex digits with an inverted (flipped upside down) 80 | # display. 81 | display.set_invert(True) 82 | for i in range(0xFF): 83 | display.clear() 84 | display.print_hex(i) 85 | display.set_colon(colon) 86 | display.write_display() 87 | time.sleep(0.25) 88 | display.set_invert(False) 89 | # For the large 1.2" 7-segment display only there are extra functions to 90 | # turn on/off the left side colon and the fixed decimal point. Uncomment 91 | # to try them out: 92 | # To turn on the left side colon: 93 | #display.set_left_colon(True) 94 | # To turn off the left side colon: 95 | #display.set_left_colon(False) 96 | # To turn on the fixed decimal point (in upper right in normal orientation): 97 | #display.set_fixed_decimal(True) 98 | # To turn off the fixed decimal point: 99 | #display.set_fixed_decimal(False) 100 | # Make sure to call write_display() to make the above visible! 101 | # Flip colon on or off. 102 | colon = not colon 103 | -------------------------------------------------------------------------------- /ez_setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Bootstrap setuptools installation 3 | 4 | To use setuptools in your package's setup.py, include this 5 | file in the same directory and add this to the top of your setup.py:: 6 | 7 | from ez_setup import use_setuptools 8 | use_setuptools() 9 | 10 | To require a specific version of setuptools, set a download 11 | mirror, or use an alternate download directory, simply supply 12 | the appropriate options to ``use_setuptools()``. 13 | 14 | This file can also be run as a script to install or upgrade setuptools. 15 | """ 16 | import os 17 | import shutil 18 | import sys 19 | import tempfile 20 | import zipfile 21 | import optparse 22 | import subprocess 23 | import platform 24 | import textwrap 25 | import contextlib 26 | 27 | from distutils import log 28 | 29 | try: 30 | from site import USER_SITE 31 | except ImportError: 32 | USER_SITE = None 33 | 34 | DEFAULT_VERSION = "3.5.1" 35 | DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/" 36 | 37 | def _python_cmd(*args): 38 | """ 39 | Return True if the command succeeded. 40 | """ 41 | args = (sys.executable,) + args 42 | return subprocess.call(args) == 0 43 | 44 | 45 | def _install(archive_filename, install_args=()): 46 | with archive_context(archive_filename): 47 | # installing 48 | log.warn('Installing Setuptools') 49 | if not _python_cmd('setup.py', 'install', *install_args): 50 | log.warn('Something went wrong during the installation.') 51 | log.warn('See the error message above.') 52 | # exitcode will be 2 53 | return 2 54 | 55 | 56 | def _build_egg(egg, archive_filename, to_dir): 57 | with archive_context(archive_filename): 58 | # building an egg 59 | log.warn('Building a Setuptools egg in %s', to_dir) 60 | _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) 61 | # returning the result 62 | log.warn(egg) 63 | if not os.path.exists(egg): 64 | raise IOError('Could not build the egg.') 65 | 66 | 67 | def get_zip_class(): 68 | """ 69 | Supplement ZipFile class to support context manager for Python 2.6 70 | """ 71 | class ContextualZipFile(zipfile.ZipFile): 72 | def __enter__(self): 73 | return self 74 | def __exit__(self, type, value, traceback): 75 | self.close 76 | return zipfile.ZipFile if hasattr(zipfile.ZipFile, '__exit__') else \ 77 | ContextualZipFile 78 | 79 | 80 | @contextlib.contextmanager 81 | def archive_context(filename): 82 | # extracting the archive 83 | tmpdir = tempfile.mkdtemp() 84 | log.warn('Extracting in %s', tmpdir) 85 | old_wd = os.getcwd() 86 | try: 87 | os.chdir(tmpdir) 88 | with get_zip_class()(filename) as archive: 89 | archive.extractall() 90 | 91 | # going in the directory 92 | subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) 93 | os.chdir(subdir) 94 | log.warn('Now working in %s', subdir) 95 | yield 96 | 97 | finally: 98 | os.chdir(old_wd) 99 | shutil.rmtree(tmpdir) 100 | 101 | 102 | def _do_download(version, download_base, to_dir, download_delay): 103 | egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg' 104 | % (version, sys.version_info[0], sys.version_info[1])) 105 | if not os.path.exists(egg): 106 | archive = download_setuptools(version, download_base, 107 | to_dir, download_delay) 108 | _build_egg(egg, archive, to_dir) 109 | sys.path.insert(0, egg) 110 | 111 | # Remove previously-imported pkg_resources if present (see 112 | # https://bitbucket.org/pypa/setuptools/pull-request/7/ for details). 113 | if 'pkg_resources' in sys.modules: 114 | del sys.modules['pkg_resources'] 115 | 116 | import setuptools 117 | setuptools.bootstrap_install_from = egg 118 | 119 | 120 | def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, 121 | to_dir=os.curdir, download_delay=15): 122 | to_dir = os.path.abspath(to_dir) 123 | rep_modules = 'pkg_resources', 'setuptools' 124 | imported = set(sys.modules).intersection(rep_modules) 125 | try: 126 | import pkg_resources 127 | except ImportError: 128 | return _do_download(version, download_base, to_dir, download_delay) 129 | try: 130 | pkg_resources.require("setuptools>=" + version) 131 | return 132 | except pkg_resources.DistributionNotFound: 133 | return _do_download(version, download_base, to_dir, download_delay) 134 | except pkg_resources.VersionConflict as VC_err: 135 | if imported: 136 | msg = textwrap.dedent(""" 137 | The required version of setuptools (>={version}) is not available, 138 | and can't be installed while this script is running. Please 139 | install a more recent version first, using 140 | 'easy_install -U setuptools'. 141 | 142 | (Currently using {VC_err.args[0]!r}) 143 | """).format(VC_err=VC_err, version=version) 144 | sys.stderr.write(msg) 145 | sys.exit(2) 146 | 147 | # otherwise, reload ok 148 | del pkg_resources, sys.modules['pkg_resources'] 149 | return _do_download(version, download_base, to_dir, download_delay) 150 | 151 | def _clean_check(cmd, target): 152 | """ 153 | Run the command to download target. If the command fails, clean up before 154 | re-raising the error. 155 | """ 156 | try: 157 | subprocess.check_call(cmd) 158 | except subprocess.CalledProcessError: 159 | if os.access(target, os.F_OK): 160 | os.unlink(target) 161 | raise 162 | 163 | def download_file_powershell(url, target): 164 | """ 165 | Download the file at url to target using Powershell (which will validate 166 | trust). Raise an exception if the command cannot complete. 167 | """ 168 | target = os.path.abspath(target) 169 | cmd = [ 170 | 'powershell', 171 | '-Command', 172 | "(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)" % vars(), 173 | ] 174 | _clean_check(cmd, target) 175 | 176 | def has_powershell(): 177 | if platform.system() != 'Windows': 178 | return False 179 | cmd = ['powershell', '-Command', 'echo test'] 180 | devnull = open(os.path.devnull, 'wb') 181 | try: 182 | try: 183 | subprocess.check_call(cmd, stdout=devnull, stderr=devnull) 184 | except Exception: 185 | return False 186 | finally: 187 | devnull.close() 188 | return True 189 | 190 | download_file_powershell.viable = has_powershell 191 | 192 | def download_file_curl(url, target): 193 | cmd = ['curl', url, '--silent', '--output', target] 194 | _clean_check(cmd, target) 195 | 196 | def has_curl(): 197 | cmd = ['curl', '--version'] 198 | devnull = open(os.path.devnull, 'wb') 199 | try: 200 | try: 201 | subprocess.check_call(cmd, stdout=devnull, stderr=devnull) 202 | except Exception: 203 | return False 204 | finally: 205 | devnull.close() 206 | return True 207 | 208 | download_file_curl.viable = has_curl 209 | 210 | def download_file_wget(url, target): 211 | cmd = ['wget', url, '--quiet', '--output-document', target] 212 | _clean_check(cmd, target) 213 | 214 | def has_wget(): 215 | cmd = ['wget', '--version'] 216 | devnull = open(os.path.devnull, 'wb') 217 | try: 218 | try: 219 | subprocess.check_call(cmd, stdout=devnull, stderr=devnull) 220 | except Exception: 221 | return False 222 | finally: 223 | devnull.close() 224 | return True 225 | 226 | download_file_wget.viable = has_wget 227 | 228 | def download_file_insecure(url, target): 229 | """ 230 | Use Python to download the file, even though it cannot authenticate the 231 | connection. 232 | """ 233 | try: 234 | from urllib.request import urlopen 235 | except ImportError: 236 | from urllib2 import urlopen 237 | src = dst = None 238 | try: 239 | src = urlopen(url) 240 | # Read/write all in one block, so we don't create a corrupt file 241 | # if the download is interrupted. 242 | data = src.read() 243 | dst = open(target, "wb") 244 | dst.write(data) 245 | finally: 246 | if src: 247 | src.close() 248 | if dst: 249 | dst.close() 250 | 251 | download_file_insecure.viable = lambda: True 252 | 253 | def get_best_downloader(): 254 | downloaders = [ 255 | download_file_powershell, 256 | download_file_curl, 257 | download_file_wget, 258 | download_file_insecure, 259 | ] 260 | 261 | for dl in downloaders: 262 | if dl.viable(): 263 | return dl 264 | 265 | def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, 266 | to_dir=os.curdir, delay=15, downloader_factory=get_best_downloader): 267 | """ 268 | Download setuptools from a specified location and return its filename 269 | 270 | `version` should be a valid setuptools version number that is available 271 | as an egg for download under the `download_base` URL (which should end 272 | with a '/'). `to_dir` is the directory where the egg will be downloaded. 273 | `delay` is the number of seconds to pause before an actual download 274 | attempt. 275 | 276 | ``downloader_factory`` should be a function taking no arguments and 277 | returning a function for downloading a URL to a target. 278 | """ 279 | # making sure we use the absolute path 280 | to_dir = os.path.abspath(to_dir) 281 | zip_name = "setuptools-%s.zip" % version 282 | url = download_base + zip_name 283 | saveto = os.path.join(to_dir, zip_name) 284 | if not os.path.exists(saveto): # Avoid repeated downloads 285 | log.warn("Downloading %s", url) 286 | downloader = downloader_factory() 287 | downloader(url, saveto) 288 | return os.path.realpath(saveto) 289 | 290 | def _build_install_args(options): 291 | """ 292 | Build the arguments to 'python setup.py install' on the setuptools package 293 | """ 294 | return ['--user'] if options.user_install else [] 295 | 296 | def _parse_args(): 297 | """ 298 | Parse the command line for options 299 | """ 300 | parser = optparse.OptionParser() 301 | parser.add_option( 302 | '--user', dest='user_install', action='store_true', default=False, 303 | help='install in user site package (requires Python 2.6 or later)') 304 | parser.add_option( 305 | '--download-base', dest='download_base', metavar="URL", 306 | default=DEFAULT_URL, 307 | help='alternative URL from where to download the setuptools package') 308 | parser.add_option( 309 | '--insecure', dest='downloader_factory', action='store_const', 310 | const=lambda: download_file_insecure, default=get_best_downloader, 311 | help='Use internal, non-validating downloader' 312 | ) 313 | parser.add_option( 314 | '--version', help="Specify which version to download", 315 | default=DEFAULT_VERSION, 316 | ) 317 | options, args = parser.parse_args() 318 | # positional arguments are ignored 319 | return options 320 | 321 | def main(): 322 | """Install or upgrade setuptools and EasyInstall""" 323 | options = _parse_args() 324 | archive = download_setuptools( 325 | version=options.version, 326 | download_base=options.download_base, 327 | downloader_factory=options.downloader_factory, 328 | ) 329 | return _install(archive, _build_install_args(options)) 330 | 331 | if __name__ == '__main__': 332 | sys.exit(main()) 333 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | try: 2 | # Try using ez_setup to install setuptools if not already installed. 3 | from ez_setup import use_setuptools 4 | use_setuptools() 5 | except ImportError: 6 | # Ignore import error and assume Python 3 which already has setuptools. 7 | pass 8 | 9 | from setuptools import setup, find_packages 10 | 11 | classifiers = ['Development Status :: 4 - Beta', 12 | 'Operating System :: POSIX :: Linux', 13 | 'License :: OSI Approved :: MIT License', 14 | 'Intended Audience :: Developers', 15 | 'Programming Language :: Python :: 2.7', 16 | 'Programming Language :: Python :: 3', 17 | 'Topic :: Software Development', 18 | 'Topic :: System :: Hardware'] 19 | 20 | setup(name = 'Adafruit_LED_Backpack', 21 | version = '1.8.1', 22 | author = 'Tony DiCola', 23 | author_email = 'tdicola@adafruit.com', 24 | description = 'Library to control LED backpack displays such as 8x8 single and bi-color matrices, bargraphs, 7 segment, and 14 segment displays.', 25 | license = 'MIT', 26 | classifiers = classifiers, 27 | url = 'https://github.com/adafruit/Adafruit_Python_LED_Backpack/', 28 | dependency_links = ['https://github.com/adafruit/Adafruit_Python_GPIO/tarball/master#egg=Adafruit-GPIO-0.6.5'], 29 | install_requires = ['Adafruit-GPIO>=0.6.5'], 30 | packages = find_packages()) 31 | --------------------------------------------------------------------------------