/ examples / ht16k33_animation_demo.py
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()