77`adafruit_ht16k33.ht16k33`
88===========================
99
10- * Authors: Radomir Dopieralski & Tony DiCola for Adafruit Industries
10+ * Authors: Radomir Dopieralski, Tony DiCola, and Melissa LeBlanc-Williams for Adafruit Industries
1111
1212"""
1313
1414from adafruit_bus_device import i2c_device
1515from micropython import const
1616
1717try :
18- from typing import Optional
18+ from typing import Union , List , Tuple , Optional
1919 from busio import I2C
2020except ImportError :
2121 pass
@@ -43,25 +43,32 @@ class HT16K33:
4343 def __init__ (
4444 self ,
4545 i2c : I2C ,
46- address : int = 0x70 ,
46+ address : Union [ int , Tuple , List ] = 0x70 ,
4747 auto_write : bool = True ,
4848 brightness : float = 1.0 ,
4949 ) -> None :
50- self .i2c_device = i2c_device .I2CDevice (i2c , address )
50+ if isinstance (address , (tuple , list )):
51+ self .i2c_device = []
52+ for addr in address :
53+ self .i2c_device .append (i2c_device .I2CDevice (i2c , addr ))
54+ else :
55+ self .i2c_device = [i2c_device .I2CDevice (i2c , address )]
5156 self ._temp = bytearray (1 )
52- self ._buffer = bytearray (17 )
57+ self ._buffer_size = 17
58+ self ._buffer = bytearray ((self ._buffer_size ) * len (self .i2c_device ))
5359 self ._auto_write = auto_write
5460 self .fill (0 )
55- self ._write_cmd (_HT16K33_OSCILATOR_ON )
61+ for i , _ in enumerate (self .i2c_device ):
62+ self ._write_cmd (_HT16K33_OSCILATOR_ON , i )
5663 self ._blink_rate = None
5764 self ._brightness = None
5865 self .blink_rate = 0
5966 self .brightness = brightness
6067
61- def _write_cmd (self , byte : bytearray ) -> None :
68+ def _write_cmd (self , byte : bytearray , i2c_index : int = 0 ) -> None :
6269 self ._temp [0 ] = byte
63- with self .i2c_device :
64- self .i2c_device .write (self ._temp )
70+ with self .i2c_device [ i2c_index ] :
71+ self .i2c_device [ i2c_index ] .write (self ._temp )
6572
6673 @property
6774 def blink_rate (self ) -> int :
@@ -74,7 +81,10 @@ def blink_rate(self, rate: Optional[int] = None) -> None:
7481 raise ValueError ("Blink rate must be an integer in the range: 0-3" )
7582 rate = rate & 0x03
7683 self ._blink_rate = rate
77- self ._write_cmd (_HT16K33_BLINK_CMD | _HT16K33_BLINK_DISPLAYON | rate << 1 )
84+ for index , _ in enumerate (self .i2c_device ):
85+ self ._write_cmd (
86+ _HT16K33_BLINK_CMD | _HT16K33_BLINK_DISPLAYON | rate << 1 , index
87+ )
7888
7989 @property
8090 def brightness (self ) -> float :
@@ -91,7 +101,8 @@ def brightness(self, brightness: float) -> None:
91101 self ._brightness = brightness
92102 xbright = round (15 * brightness )
93103 xbright = xbright & 0x0F
94- self ._write_cmd (_HT16K33_CMD_BRIGHTNESS | xbright )
104+ for index , _ in enumerate (self .i2c_device ):
105+ self ._write_cmd (_HT16K33_CMD_BRIGHTNESS | xbright , index )
95106
96107 @property
97108 def auto_write (self ) -> bool :
@@ -107,10 +118,13 @@ def auto_write(self, auto_write: bool) -> None:
107118
108119 def show (self ) -> None :
109120 """Refresh the display and show the changes."""
110- with self .i2c_device :
111- # Byte 0 is 0x00, address of LED data register. The remaining 16
112- # bytes are the display register data to set.
113- self .i2c_device .write (self ._buffer )
121+ for index , i2c_dev in enumerate (self .i2c_device ):
122+ with i2c_dev :
123+ # Byte 0 is 0x00, address of LED data register. The remaining 16
124+ # bytes are the display register data to set.
125+ offset = index * self ._buffer_size
126+ buffer = self ._buffer [offset : offset + self ._buffer_size ]
127+ i2c_dev .write (buffer )
114128
115129 def fill (self , color : bool ) -> None :
116130 """Fill the whole display with the given color.
@@ -119,13 +133,16 @@ def fill(self, color: bool) -> None:
119133 """
120134
121135 fill = 0xFF if color else 0x00
122- for i in range (16 ):
123- self ._buffer [i + 1 ] = fill
136+ for device , _ in enumerate (self .i2c_device ):
137+ for i in range (self ._buffer_size - 1 ):
138+ self ._buffer [device * self ._buffer_size + i + 1 ] = fill
124139 if self ._auto_write :
125140 self .show ()
126141
127142 def _pixel (self , x : int , y : int , color : Optional [bool ] = None ) -> Optional [bool ]:
128- addr = 2 * y + x // 8
143+ offset = ((x // 16 ) + (y // 8 )) * self ._buffer_size
144+ addr = 2 * (y % 8 ) + ((x % 16 ) // 8 )
145+ addr = (addr % 16 ) + offset
129146 mask = 1 << x % 8
130147 if color is None :
131148 return bool (self ._buffer [addr + 1 ] & mask )
0 commit comments