Created
June 10, 2023 20:16
-
-
Save Tom-Archer/6bfd9f017b28e601e4d484e4b21ceb14 to your computer and use it in GitHub Desktop.
Battlestar Chronometer Sample Python Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Import all board pins and bus interface. | |
import board | |
import busio | |
# Import the HT16K33 LED matrix module. | |
from adafruit_ht16k33 import matrix | |
import datetime | |
import random | |
import time | |
# Create the I2C interface. | |
i2c = busio.I2C(board.SCL, board.SDA) | |
class LEDBackpack(matrix.HT16K33): | |
"""LED Backpack interface akin to the C-version""" | |
def set_pixel(self, x, y, on=1): | |
"""Convenience function to set a specific pixel.""" | |
self._pixel(x,y,on) | |
def clear(self): | |
"""Convenience function to clear the display.""" | |
self.fill(0) | |
seconds_matrix = LEDBackpack(i2c, address=0x70, auto_write=False) | |
minutes_matrix = LEDBackpack(i2c, address=0x71, auto_write=False) | |
hours_matrix = LEDBackpack(i2c, address=0x72, auto_write=False) | |
def setup(): | |
minutes_matrix.brightness = 1.0 * 12/15 | |
def clear_all(): | |
"""Clear all the displays.""" | |
seconds_matrix.clear() | |
minutes_matrix.clear() | |
hours_matrix.clear() | |
def write_all(): | |
"""Write to all the displays.""" | |
seconds_matrix.show() | |
minutes_matrix.show() | |
hours_matrix.show() | |
def blink_all(b): | |
"""Blink all the displays (doesn't require a write).""" | |
seconds_matrix.blink_rate = b | |
minutes_matrix.blink_rate = b | |
hours_matrix.blink_rate = b | |
write_all() # TBD | |
# The HT16K33 internal memory looks like | |
# a 8x16 bit matrix (8 rows, 16 columns) | |
# The HT16K33 has 8 cathodes and 16 anodes | |
def pixel_test_single_rings(delta, iterations): | |
""" Turn on each ring individually.""" | |
# Clear all the LEDs for good measure | |
clear_all() | |
write_all() | |
for i in range(0, iterations): | |
# Seconds | |
seconds_matrix.clear() | |
seconds_matrix.show() | |
for a in range(0, 60): | |
k = a//8 | |
seconds_matrix.set_pixel(a%8, k) | |
seconds_matrix.show() | |
time.sleep(delta/1000) | |
seconds_matrix.clear() | |
seconds_matrix.show() | |
# Minutes | |
minutes_matrix.clear() | |
minutes_matrix.show() | |
for a in range(0, 60): | |
k = a//8 | |
minutes_matrix.set_pixel(a%8, k) | |
minutes_matrix.show() | |
time.sleep(delta/1000) | |
minutes_matrix.clear() | |
minutes_matrix.show() | |
# Hours - LED Pairs | |
hours_matrix.clear() | |
hours_matrix.show() | |
for a in range(0, 12): | |
k = (a//8)*2 | |
hours_matrix.set_pixel(a%8, k) | |
hours_matrix.set_pixel(a%8, k+1) | |
hours_matrix.show() | |
time.sleep(delta*5/1000) | |
hours_matrix.clear() | |
hours_matrix.show() | |
def pixel_test_all_rings(delta, iterations): | |
"""Turn on all the rings and then turn off all the rings for the number of iterations.""" | |
# Clear all the LEDs for good measure | |
clear_all() | |
write_all() | |
for i in range(0, iterations*2): | |
on = (i+1)%2 | |
# Seconds | |
for a in range(0, 60): | |
k = a//8 | |
seconds_matrix.set_pixel(a%8, k, on) | |
seconds_matrix.show() | |
time.sleep(delta/1000) | |
# Minutes | |
for a in range(0, 60): | |
k = a//8 | |
minutes_matrix.set_pixel(a%8, k, on) | |
minutes_matrix.show() | |
time.sleep(delta/1000) | |
# Hours - Individual LEDs | |
for j in range(1,-1,-1): | |
for a in range(0, 12): | |
k = j + (a//8)*2 | |
hours_matrix.set_pixel(a%8, k, on) | |
hours_matrix.show() | |
time.sleep(delta*5/1000) | |
def pixel_test_spiral(delta, iterations): | |
"""Illuminate the LEDs in a spiral pattern.""" | |
# Clear all the LEDs for good measure | |
clear_all() | |
write_all() | |
group_size = 6 | |
num_groups = 10 | |
for i in range(0, iterations*2): | |
on = (i+1)%2 | |
# Seconds | |
for g in range(0, group_size): | |
for n in range(0, num_groups): | |
a = n*group_size + g | |
k = a//8 | |
seconds_matrix.set_pixel(a%8, k, on) | |
seconds_matrix.show() | |
# Delay here means nth LEDs turn on one after another | |
# and not at the same time. | |
time.sleep(delta/1000) | |
# Minutes | |
for g in range(0, group_size): | |
for n in range(0, num_groups): | |
a = n*group_size + g | |
k = a//8 | |
minutes_matrix.set_pixel(a%8, k, on) | |
minutes_matrix.show() | |
# Delay here means nth LEDs turn on one after another | |
# and not at the same time. | |
time.sleep(delta/1000) | |
# Hours - Individual LEDs | |
for j in range(1,-1,-1): | |
for g in range(0, 3): | |
for n in range(0, 4): | |
a = n*3 + g | |
k = j + (a//8)*2 | |
hours_matrix.set_pixel(a%8, k, on) | |
hours_matrix.show() | |
# Delay here means nth LEDs turn on one after another | |
# and not at the same time. | |
time.sleep(delta*5/1000) | |
def pixel_test_fan(delta, iterations): | |
"""Rotate a fixed number (6) of LEDs around the display.""" | |
# Clear all the LEDs for good measure | |
clear_all() | |
write_all() | |
# Hours - LED Pairs | |
# All on, always | |
hours_matrix.fill(1) | |
hours_matrix.show() | |
group_size = 6 | |
num_groups = 5 | |
interval = 60//num_groups | |
# Make the LEDs appear nicely | |
for g in range(0, group_size-1): | |
for n in range(0, num_groups): | |
a = (n*interval + g)%60 | |
k = a//8 | |
seconds_matrix.set_pixel(a%8, k) | |
minutes_matrix.set_pixel(a%8, k) | |
write_all() | |
time.sleep(delta*2/1000) | |
# Rotate | |
for i in range(0, 120*iterations + 1): | |
seconds_matrix.clear() | |
minutes_matrix.clear() | |
for n in range(0, num_groups): | |
for g in range(0, group_size): | |
a = (n*interval + g + i)%60 | |
k = a//8 | |
seconds_matrix.set_pixel(a%8, k) | |
minutes_matrix.set_pixel(a%8, k) | |
write_all() | |
time.sleep(delta/1000) | |
# Make remaining LEDs disappear nicely | |
for g in range(0, group_size): | |
for n in range(0, num_groups): | |
a = (n*interval + g)%60 | |
k = a//8 | |
seconds_matrix.set_pixel(a%8, k, 0) | |
minutes_matrix.set_pixel(a%8, k, 0) | |
write_all() | |
time.sleep(delta*2/1000) | |
def display_time(the_time): | |
"""Show a provided time.""" | |
# Clear all the LEDs for good measure | |
clear_all() | |
mins = the_time.minute | |
seconds = the_time.second | |
hours = the_time.hour % 12 | |
# Make 0 illuminate all LEDs | |
if seconds == 0: | |
seconds = 60 | |
if mins == 0: | |
mins = 60 | |
if hours == 0: | |
hours = 12 | |
# Set the seconds value | |
for i in range (0, seconds): | |
seconds_matrix.set_pixel(i%8, i//8) | |
# Set the minutes value | |
for i in range (0, mins): | |
minutes_matrix.set_pixel(i%8, i//8) | |
# Set the hours value | |
for i in range (0, hours): | |
k = (i//8)*2 | |
hours_matrix.set_pixel(i%8, k) | |
hours_matrix.set_pixel(i%8, k+1) | |
# Display | |
write_all() | |
print(hours, mins, seconds) | |
def time_demo(duration): | |
"""Display the time and count up for the provided number of seconds.""" | |
for i in range (0, duration): | |
display_time(datetime.datetime.now()) | |
time.sleep(1) | |
def countdown_demo(h, m, s, delta): | |
"""Countdown from the provided time (hours, minutes and seconds).""" | |
# Clear all the LEDs for good measure | |
clear_all() | |
# Create the countdown time | |
now = datetime.datetime.now() | |
countdown_time = datetime.datetime(now.year, now.month, now.day, h, m, s) | |
# Display for delta (1 second) | |
display_time(countdown_time) | |
time.sleep(delta/1000) | |
while True: | |
# Decrement the countdown time by 1 second | |
countdown_time -= datetime.timedelta(seconds=1) | |
# Display for delta (1 second) | |
display_time(countdown_time) | |
time.sleep(delta/1000) | |
# Check whether 0h0m0s has been reached | |
if countdown_time.hour == 0 and countdown_time.minute == 0 and countdown_time.second == 0: | |
break | |
# Blink the display | |
blink_all(2) | |
time.sleep(5) | |
clear_all() | |
write_all() | |
blink_all(0) | |
class Snake: | |
"""Defines a snake""" | |
def __init__(self, snake_length, matrix_length=60, it_low=30, it_high=50): | |
"""Constructor.""" | |
self.snake_length = snake_length | |
self.matrix_length = matrix_length | |
self.it_low = it_low | |
self.it_high = it_high | |
self.start_point = random.randrange(0, matrix_length) | |
self.direction = random.randrange(0, 2) | |
if not self.direction: | |
self.end_point = self.start_point | |
self.start_point = (self.end_point - self.snake_length)%self.matrix_length | |
else: | |
self.end_point = (self.start_point + self.snake_length)%self.matrix_length | |
# Get a number of iterations | |
self.iterations = random.randrange(self.it_low, self.it_high+1) | |
self.iteration = 0 | |
def update(self): | |
"""Update the position.""" | |
# Move the snake | |
if not self.direction: | |
self.start_point = (self.start_point - 1)%self.matrix_length | |
self.end_point = (self.end_point - 1)%self.matrix_length | |
else: | |
self.start_point = (self.start_point + 1)%self.matrix_length | |
self.end_point = (self.end_point + 1)%self.matrix_length | |
# Update the iteration | |
self.iteration += 1 | |
if self.iteration > self.iterations: | |
self.direction = not self.direction | |
self.iterations = random.randrange(self.it_low, self.it_high+1) | |
self.iteration = 0 | |
def write(self, matrix, a): | |
k = a//8 | |
matrix.set_pixel(a%8, k) | |
def draw(self, matrix): | |
if self.start_point < self.end_point: | |
for a in range (self.start_point, self.end_point): | |
self.write(matrix, a) | |
else: | |
for a in range (self.start_point, self.matrix_length): | |
self.write(matrix, a) | |
for a in range (0, self.end_point): | |
self.write(matrix, a) | |
class HoursOuterSnake(Snake): | |
"""Defines a snake on the outer hours LEDs.""" | |
def write(self, matrix, a): | |
k = (a//8)*2 + 1 | |
matrix.set_pixel(a%8, k) | |
class HoursInnerSnake(Snake): | |
"""Defines a snake on the inner hours LEDs.""" | |
def write(self, matrix, a): | |
k = (a//8)*2 | |
matrix.set_pixel(a%8, k) | |
def pixel_test_larson(delta): | |
"""Curved Larson scanners.""" | |
# Clear all the LEDs for good measure | |
clear_all() | |
write_all() | |
# Define the snakes | |
secondsSnake = Snake(6, 60, 30, 50) | |
minutesSnake = Snake(8, 60, 30, 50) | |
hoursOuterSnake = HoursOuterSnake(4, 12, 15, 25) | |
hoursInnerSnake = HoursInnerSnake(3, 12, 15, 25) | |
while True: | |
clear_all() | |
secondsSnake.draw(seconds_matrix) | |
minutesSnake.draw(minutes_matrix) | |
hoursOuterSnake.draw(hours_matrix) | |
hoursInnerSnake.draw(hours_matrix) | |
write_all() | |
secondsSnake.update() | |
minutesSnake.update() | |
hoursOuterSnake.update() | |
hoursInnerSnake.update() | |
time.sleep(delta/1000) | |
if __name__ == '__main__': | |
setup() | |
while True: | |
time.sleep(1) | |
pixel_test_single_rings(20, 3) | |
pixel_test_all_rings(10, 3) | |
pixel_test_spiral(10, 3) | |
pixel_test_fan(10, 3) | |
pixel_test_larson(100) | |
#time_demo(10) | |
#countdown_demo(0, 1, 15, 200) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment