ht16k33_animation_demo.py
1 """ 2 Test script for display animations on an HT16K33 with alphanumeric display 3 4 The display must be initialized with auto_write=False. 5 """ 6 7 from time import sleep 8 import board 9 import busio 10 from adafruit_ht16k33.segments import Seg14x4 11 12 # 13 # Segment bits on the HT16K33 with alphanumeric display. 14 # 15 # Add the values of the segments you need to create a bitmask 16 # 17 18 N = 16384 19 M = 8192 20 L = 4096 21 K = 2048 22 J = 1024 23 I = 512 24 H = 256 25 G2 = 128 26 G1 = 64 27 F = 32 28 E = 16 29 D = 8 30 C = 4 31 B = 2 32 A = 1 33 34 # The number of seconds to delay between writing segments 35 DEFAULT_CHAR_DELAY_SEC = 0.2 36 37 # The number of cycles to go for each animation 38 DEFAULT_CYCLES = 5 39 40 # Brightness of the display (0 to 15) 41 DEFAULT_DISPLAY_BRIGHTNESS = 0.3 42 43 # Initialize the I2C bus 44 i2c = busio.I2C(board.SCL, board.SDA) 45 46 # Initialize the HT16K33 with alphanumeric display featherwing. 47 # 48 # You MUST set auto_write=False 49 display = Seg14x4(i2c, auto_write=False) 50 display.brightness = DEFAULT_DISPLAY_BRIGHTNESS 51 52 53 def animate(digits, bitmasks, delay=DEFAULT_CHAR_DELAY_SEC, auto_write=True): 54 """ 55 Main driver for all alphanumeric display animations (WIP!!!) 56 Param: digits - a list of the digits to write to, in order, like [0, 1, 3]. The digits are 57 0 to 3 starting at the left most digit. 58 Param: bitmasks - a list of the bitmasks to write, in sequence, to the specified digits. 59 Param: delay - The delay, in seconds (or fractions of), between writing bitmasks to a digit. 60 Param: auto_write - Whether to actually write to the display immediately or not. 61 62 Returns: Nothing 63 """ 64 if not isinstance(digits, list): 65 raise ValueError("The first parameter MUST be a list!") 66 if not isinstance(bitmasks, list): 67 raise ValueError("The second parameter MUST be a list!") 68 if delay < 0: 69 raise ValueError("The delay between frames must be positive!") 70 for dig in digits: 71 if not 0 <= dig <= 3: 72 raise ValueError( 73 "Digit value must be \ 74 an integer in the range: 0-3" 75 ) 76 77 for bits in bitmasks: 78 if not 0 <= bits <= 0xFFFF: 79 raise ValueError( 80 "Bitmask value must be an \ 81 integer in the range: 0-65535" 82 ) 83 84 display.set_digit_raw(dig, bits) 85 86 if auto_write: 87 display.show() 88 sleep(delay) 89 90 91 def chase_forward_and_reverse(delay=DEFAULT_CHAR_DELAY_SEC, cycles=DEFAULT_CYCLES): 92 cy = 0 93 94 while cy < cycles: 95 animate([0, 1, 2, 3], [A, 0], delay) 96 animate([3], [B, C, D, 0], delay) 97 animate([2, 1, 0], [D, 0], delay) 98 animate([0], [E, F, H, G2, 0], delay) 99 animate([1, 2], [G1, G2, 0], delay) 100 animate([3], [G1, J, A, 0], delay) 101 animate([2, 1], [A, 0], delay) 102 animate([0], [A, F, E, D, 0], delay) 103 animate([1, 2], [D, 0], delay) 104 animate([3], [D, C, B, J, G1, 0], delay) 105 animate([2, 1], [G2, G1, 0], delay) 106 animate([0], [H, 0], delay) 107 108 cy += 1 109 110 111 def prelude_to_spinners(delay=DEFAULT_CHAR_DELAY_SEC, cycles=DEFAULT_CYCLES): 112 cy = 0 113 auto_write = False 114 115 while cy < cycles: 116 animate([1, 2], [A], 0, auto_write) 117 display.show() 118 sleep(delay) 119 120 animate([0, 3], [A], 0, auto_write) 121 display.show() 122 sleep(delay) 123 124 animate([0], [A + F], 0, auto_write) 125 animate([3], [A + B], 0, auto_write) 126 display.show() 127 sleep(delay) 128 129 animate([0], [A + E + F], 0, auto_write) 130 animate([3], [A + B + C], 0, auto_write) 131 display.show() 132 sleep(delay) 133 134 animate([0], [A + D + E + F], 0, auto_write) 135 animate([3], [A + B + C + D], 0, auto_write) 136 display.show() 137 sleep(delay) 138 139 animate([1], [A + D], 0, auto_write) 140 animate([2], [A + D], 0, auto_write) 141 display.show() 142 sleep(delay) 143 144 animate([1], [A + D + M], 0, auto_write) 145 animate([2], [A + D + K], 0, auto_write) 146 display.show() 147 sleep(delay) 148 149 animate([1], [A + D + M + H], 0, auto_write) 150 animate([2], [A + D + K + J], 0, auto_write) 151 display.show() 152 sleep(delay) 153 154 animate([0], [A + E + F + J + D], 0, auto_write) 155 animate([3], [A + B + C + H + D], 0, auto_write) 156 display.show() 157 sleep(delay) 158 159 animate([0], [A + E + F + J + K + D], 0, auto_write) 160 animate([3], [A + B + C + H + M + D], 0, auto_write) 161 display.show() 162 sleep(delay) 163 164 display.fill(0) 165 display.show() 166 sleep(delay) 167 168 cy += 1 169 170 171 def spinners(delay=DEFAULT_CHAR_DELAY_SEC, cycles=DEFAULT_CYCLES): 172 cy = 0 173 auto_write = False 174 175 while cy < cycles: 176 animate([0], [H + M], 0, auto_write) 177 animate([1], [J + K], 0, auto_write) 178 animate([2], [H + M], 0, auto_write) 179 animate([3], [J + K], 0, auto_write) 180 display.show() 181 sleep(delay) 182 183 animate([0], [G1 + G2], 0, auto_write) 184 animate([1], [G1 + G2], 0, auto_write) 185 animate([2], [G1 + G2], 0, auto_write) 186 animate([3], [G1 + G2], 0, auto_write) 187 display.show() 188 sleep(delay) 189 190 animate([0], [J + K], 0, auto_write) 191 animate([1], [H + M], 0, auto_write) 192 animate([2], [J + K], 0, auto_write) 193 animate([3], [H + M], 0, auto_write) 194 display.show() 195 sleep(delay) 196 197 cy += 1 198 199 display.fill(0) 200 201 202 def enclosed_spinners(delay=DEFAULT_CHAR_DELAY_SEC, cycles=DEFAULT_CYCLES): 203 cy = 0 204 auto_write = False 205 206 while cy < cycles: 207 animate([0], [A + D + E + F + H + M], 0, auto_write) 208 animate([1], [A + D + J + K], 0, auto_write) 209 animate([2], [A + D + H + M], 0, auto_write) 210 animate([3], [A + B + C + D + J + K], 0, auto_write) 211 display.show() 212 sleep(delay) 213 214 animate([0], [A + D + E + F + G1 + G2], 0, auto_write) 215 animate([1], [A + D + G1 + G2], 0, auto_write) 216 animate([2], [A + D + G1 + G2], 0, auto_write) 217 animate([3], [A + B + C + D + G1 + G2], 0, auto_write) 218 display.show() 219 sleep(delay) 220 221 animate([0], [A + D + E + F + J + K], 0, auto_write) 222 animate([1], [A + D + H + M], 0, auto_write) 223 animate([2], [A + D + J + K], 0, auto_write) 224 animate([3], [A + B + C + D + H + M], 0, auto_write) 225 display.show() 226 sleep(delay) 227 228 cy += 1 229 230 display.fill(0) 231 232 233 def count_down(): 234 auto_write = False 235 numbers = [ 236 [A + B + C + D + G1 + G2 + N], 237 [A + B + D + E + G1 + G2 + N], 238 [B + C + N], 239 ] 240 index = 0 241 242 display.fill(0) 243 244 while index < len(numbers): 245 animate([index], numbers[index], 0, auto_write) 246 display.show() 247 sleep(1) 248 display.fill(0) 249 sleep(0.5) 250 251 index += 1 252 253 sleep(1) 254 display.fill(0) 255 256 257 try: 258 text = "Init" 259 260 display.fill(1) 261 display.show() 262 sleep(1) 263 display.fill(0) 264 display.show() 265 266 display.print(text) 267 display.show() 268 sleep(2) 269 display.fill(0) 270 display.show() 271 sleep(1) 272 273 count_down() 274 sleep(0.2) 275 276 text = "Go!!" 277 278 display.print(text) 279 display.show() 280 sleep(1.5) 281 display.fill(0) 282 display.show() 283 sleep(0.5) 284 print() 285 286 while True: 287 # Arrow 288 print("Arrow") 289 animate([0, 1, 2], [G1 + G2], 0.1) 290 animate([3], [G1 + H + K], 0.1) 291 sleep(1.0) 292 display.fill(0) 293 sleep(1.0) 294 295 # Flying 296 print("Flying") 297 cyc = 0 298 299 while cyc < DEFAULT_CYCLES: 300 animate([0], [H + J, G1 + G2, K + M, G1 + G2], DEFAULT_CHAR_DELAY_SEC) 301 302 cyc += 1 303 304 animate([0], [0]) 305 sleep(1.0) 306 display.fill(0) 307 sleep(1.0) 308 309 # Chase forward and reverse. 310 print("Chase forward and reverse") 311 chase_forward_and_reverse(0.01, 5) 312 sleep(1.0) 313 display.fill(0) 314 sleep(1.0) 315 316 # Testing writing to more than one segment simultaneously 317 print("Prelude to Spinners") 318 prelude_to_spinners(0.1, 5) 319 sleep(1.0) 320 display.fill(0) 321 display.show() 322 sleep(1.0) 323 324 print("Spinners") 325 spinners(0.1, 20) 326 sleep(1.0) 327 display.fill(0) 328 display.show() 329 sleep(1.0) 330 331 print("Enclosed Spinners") 332 enclosed_spinners(0.1, 20) 333 sleep(1.0) 334 display.fill(0) 335 display.show() 336 sleep(1.0) 337 338 print() 339 except KeyboardInterrupt: 340 display.fill(0) 341 display.show()