/ adafruit_ht16k33 / ht16k33.py
ht16k33.py
1 # The MIT License (MIT) 2 # 3 # Copyright (c) 2016 Radomir Dopieralski & Tony DiCola for 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. 22 23 """ 24 `adafruit_ht16k33.ht16k33` 25 =========================== 26 27 * Authors: Radomir Dopieralski & Tony DiCola for Adafruit Industries 28 29 """ 30 31 from adafruit_bus_device import i2c_device 32 from micropython import const 33 34 __version__ = "0.0.0-auto.0" 35 __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_HT16K33.git" 36 37 _HT16K33_BLINK_CMD = const(0x80) 38 _HT16K33_BLINK_DISPLAYON = const(0x01) 39 _HT16K33_CMD_BRIGHTNESS = const(0xE0) 40 _HT16K33_OSCILATOR_ON = const(0x21) 41 42 43 class HT16K33: 44 """ 45 The base class for all displays. Contains common methods. 46 47 :param int address: The I2C addess of the HT16K33. 48 :param bool auto_write: True if the display should immediately change when 49 set. If False, `show` must be called explicitly. 50 :param float brightness: 0.0 - 1.0 default brightness level. 51 """ 52 53 def __init__(self, i2c, address=0x70, auto_write=True, brightness=1.0): 54 self.i2c_device = i2c_device.I2CDevice(i2c, address) 55 self._temp = bytearray(1) 56 self._buffer = bytearray(17) 57 self._auto_write = auto_write 58 self.fill(0) 59 self._write_cmd(_HT16K33_OSCILATOR_ON) 60 self._blink_rate = None 61 self._brightness = None 62 self.blink_rate = 0 63 self.brightness = brightness 64 65 def _write_cmd(self, byte): 66 self._temp[0] = byte 67 with self.i2c_device: 68 self.i2c_device.write(self._temp) 69 70 @property 71 def blink_rate(self): 72 """The blink rate. Range 0-3.""" 73 return self._blink_rate 74 75 @blink_rate.setter 76 def blink_rate(self, rate=None): 77 if not 0 <= rate <= 3: 78 raise ValueError("Blink rate must be an integer in the range: 0-3") 79 rate = rate & 0x03 80 self._blink_rate = rate 81 self._write_cmd(_HT16K33_BLINK_CMD | _HT16K33_BLINK_DISPLAYON | rate << 1) 82 83 @property 84 def brightness(self): 85 """The brightness. Range 0.0-1.0""" 86 return self._brightness 87 88 @brightness.setter 89 def brightness(self, brightness): 90 if not 0.0 <= brightness <= 1.0: 91 raise ValueError( 92 "Brightness must be a decimal number in the range: 0.0-1.0" 93 ) 94 95 self._brightness = brightness 96 xbright = round(15 * brightness) 97 xbright = xbright & 0x0F 98 self._write_cmd(_HT16K33_CMD_BRIGHTNESS | xbright) 99 100 @property 101 def auto_write(self): 102 """Auto write updates to the display.""" 103 return self._auto_write 104 105 @auto_write.setter 106 def auto_write(self, auto_write): 107 if isinstance(auto_write, bool): 108 self._auto_write = auto_write 109 else: 110 raise ValueError("Must set to either True or False.") 111 112 def show(self): 113 """Refresh the display and show the changes.""" 114 with self.i2c_device: 115 # Byte 0 is 0x00, address of LED data register. The remaining 16 116 # bytes are the display register data to set. 117 self.i2c_device.write(self._buffer) 118 119 def fill(self, color): 120 """Fill the whole display with the given color.""" 121 fill = 0xFF if color else 0x00 122 for i in range(16): 123 self._buffer[i + 1] = fill 124 if self._auto_write: 125 self.show() 126 127 def _pixel(self, x, y, color=None): 128 addr = 2 * y + x // 8 129 mask = 1 << x % 8 130 if color is None: 131 return bool(self._buffer[addr + 1] & mask) 132 if color: 133 # set the bit 134 self._buffer[addr + 1] |= mask 135 else: 136 # clear the bit 137 self._buffer[addr + 1] &= ~mask 138 if self._auto_write: 139 self.show() 140 return None 141 142 def _set_buffer(self, i, value): 143 self._buffer[i + 1] = value # Offset by 1 to move past register address. 144 145 def _get_buffer(self, i): 146 return self._buffer[i + 1] # Offset by 1 to move past register address.