Update Countdown Clock to support Qualia + include assets
This commit is contained in:
parent
24457b8a7b
commit
0217c1b612
4 changed files with 173 additions and 49 deletions
Binary file not shown.
|
After Width: | Height: | Size: 416 KiB |
|
|
@ -1,8 +1,3 @@
|
|||
# SPDX-FileCopyrightText: 2024 Liz Clark for Adafruit Industries
|
||||
# SPDX-FileCopyrightText: 2024 Tyeth Gundry for Adafruit Industries
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
import os
|
||||
import time
|
||||
import wifi
|
||||
|
|
@ -24,21 +19,34 @@ from adafruit_ticks import ticks_ms, ticks_add, ticks_diff
|
|||
## See TZ Identifier column at https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
## If you want to set the timezone, you can do so with the following line:
|
||||
timezone = "GB"
|
||||
#timezone = None # Or instead rely on automatic timezone detection based on IP Address
|
||||
# timezone = None # Or instead rely on automatic timezone detection based on IP Address
|
||||
|
||||
|
||||
## The time of the thing!
|
||||
EVENT_YEAR = 2024
|
||||
EVENT_MONTH = 8
|
||||
EVENT_DAY = 16
|
||||
EVENT_HOUR = 0
|
||||
EVENT_MINUTE = 0
|
||||
EVENT_DAY = 11 # 16
|
||||
EVENT_HOUR = 10 # 0
|
||||
EVENT_MINUTE = 28 # 0
|
||||
## we'll make a python-friendly structure
|
||||
event_time = time.struct_time((EVENT_YEAR, EVENT_MONTH, EVENT_DAY,
|
||||
EVENT_HOUR, EVENT_MINUTE, 0, # we don't track seconds
|
||||
-1, -1, False)) # we dont know day of week/year or DST
|
||||
event_time = time.struct_time(
|
||||
(
|
||||
EVENT_YEAR,
|
||||
EVENT_MONTH,
|
||||
EVENT_DAY,
|
||||
EVENT_HOUR,
|
||||
EVENT_MINUTE,
|
||||
0, # we don't track seconds
|
||||
-1, # we dont know day of week/year or DST
|
||||
-1,
|
||||
False,
|
||||
)
|
||||
)
|
||||
|
||||
wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"))
|
||||
print("Connecting to WiFi...")
|
||||
wifi.radio.connect(
|
||||
os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD")
|
||||
)
|
||||
|
||||
## Initialize a requests session using the newer connection manager
|
||||
## See https://adafruit-playground.com/u/justmobilize/pages/adafruit-connection-manager
|
||||
|
|
@ -47,28 +55,38 @@ ssl_context = adafruit_connection_manager.get_radio_ssl_context(wifi.radio)
|
|||
requests = adafruit_requests.Session(pool, ssl_context)
|
||||
|
||||
## Create an instance of the Adafruit IO HTTP client
|
||||
io = IO_HTTP(os.getenv("ADAFRUIT_AIO_USERNAME"), os.getenv("ADAFRUIT_AIO_KEY"), requests)
|
||||
io = IO_HTTP(
|
||||
os.getenv("ADAFRUIT_AIO_USERNAME"), os.getenv("ADAFRUIT_AIO_KEY"), requests
|
||||
)
|
||||
|
||||
## Setup RGB LEDs - comment out the DotStar import and setup if using NeoPixel
|
||||
pixels_length = 1 # Set to the number of pixels in your strip (funhouse has 5)
|
||||
pixels_brightness = 0.4 # Set to a value between 0.0 and 1.0
|
||||
# Uncomment the following lines if you are using DotStar and update pins if necessary
|
||||
dotstar_clock_pin = board.DOTSTAR_CLOCK
|
||||
dotstar_data_pin = board.DOTSTAR_DATA
|
||||
pixels = DotStar(dotstar_clock_pin, dotstar_data_pin, pixels_length, brightness=pixels_brightness)
|
||||
## Uncomment the following lines if you are using NeoPixel and update pin if necessary
|
||||
# neopixel_pin = board.NEOPIXEL
|
||||
# pixels = neopixel.NeoPixel(neopixel_pin, pixels_length, brightness=pixels_brightness)
|
||||
|
||||
pixels.fill((0, 0, 0)) # Turn off all pixels
|
||||
|
||||
# Setup built-in display
|
||||
display = board.DISPLAY
|
||||
## Setup display and size appropriate assets
|
||||
if board.board_id == "adafruit_qualia_s3_rgb666":
|
||||
# Display Initialisation for 3.2" Bar display (320x820)
|
||||
from qualia_bar_display_320x820 import setup_display
|
||||
display = setup_display()
|
||||
display.rotation = 90 # Rotate the display
|
||||
BITMAP_FILE = "/circuitpython_day_2024_820x260_16bit.bmp"
|
||||
FONT_FILE = "/font_free_mono_bold_48.pcf"
|
||||
FONT_Y_OFFSET = 30
|
||||
blinka_bitmap = displayio.OnDiskBitmap(BITMAP_FILE)
|
||||
PIXEL_SHADER = displayio.ColorConverter(
|
||||
input_colorspace=displayio.Colorspace.RGB565
|
||||
)
|
||||
else:
|
||||
# Setup built-in display
|
||||
display = board.DISPLAY
|
||||
BITMAP_FILE = "/cpday_tft.bmp"
|
||||
FONT_FILE = "/Helvetica-Bold-16.pcf"
|
||||
FONT_Y_OFFSET = 13
|
||||
PIXEL_SHADER = displayio.ColorConverter()
|
||||
blinka_bitmap = displayio.OnDiskBitmap(BITMAP_FILE)
|
||||
PIXEL_SHADER = blinka_bitmap.pixel_shader
|
||||
group = displayio.Group()
|
||||
font = bitmap_font.load_font("/Helvetica-Bold-16.pcf")
|
||||
blinka_bitmap = displayio.OnDiskBitmap("/cpday_tft.bmp")
|
||||
font = bitmap_font.load_font(FONT_FILE)
|
||||
# blinka_bitmap = displayio.OnDiskBitmap(BITMAP_FILE)
|
||||
blinka_grid = displayio.TileGrid(blinka_bitmap, pixel_shader=blinka_bitmap.pixel_shader)
|
||||
scrolling_label = bitmap_label.Label(font, text=" ", y=display.height - 13)
|
||||
# blinka_grid.y = -100
|
||||
scrolling_label = bitmap_label.Label(font, text=" ", y=display.height - FONT_Y_OFFSET)
|
||||
|
||||
group.append(blinka_grid)
|
||||
group.append(scrolling_label)
|
||||
|
|
@ -94,9 +112,9 @@ while True:
|
|||
print(now)
|
||||
total_seconds = time.mktime(now)
|
||||
refresh_clock = ticks_add(refresh_clock, refresh_timer)
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
print("Some error occured, retrying via reset in 5seconds! -", e)
|
||||
time.sleep(5)
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
print("Some error occured, retrying via reset in 15seconds! -", e)
|
||||
time.sleep(15)
|
||||
microcontroller.reset()
|
||||
|
||||
if ticks_diff(ticks_ms(), clock_clock) >= clock_timer:
|
||||
|
|
@ -113,24 +131,24 @@ while True:
|
|||
days_remaining = -remaining
|
||||
finished = True
|
||||
if not first_run and days_remaining == 0:
|
||||
scrolling_label.text = "It's CircuitPython Day 2024! The snakiest day of the year!"
|
||||
# Flash on/off blinka colours (nice purple) each second
|
||||
if pixels[0] == (0, 0, 0):
|
||||
pixels.fill((0x40, 0x00, 0x80))
|
||||
else:
|
||||
pixels.fill((0, 0, 0))
|
||||
scrolling_label.text = (
|
||||
"It's CircuitPython Day 2024! The snakiest day of the year!"
|
||||
)
|
||||
|
||||
# Check for the moment of the event to trigger something (a NASA snake launch)
|
||||
if not triggered and (
|
||||
hours_remaining==0 and mins_remaining == 0 and secs_remaining <= 0
|
||||
hours_remaining == 0
|
||||
and mins_remaining == 0
|
||||
and secs_remaining <= 1
|
||||
# Change at/after xx:yy:01 seconds so we've already updated the display
|
||||
):
|
||||
# send a signal to an adafruit IO feed, where an Action is listening
|
||||
print("Launch the snakes!")
|
||||
print("Launch the snakes! (sending message to Adafruit IO)")
|
||||
triggered = True
|
||||
io.send_data("cpday-countdown", "Launch the snakes!")
|
||||
else:
|
||||
pixels.fill((0, 0, 0)) # Turn off all pixels
|
||||
|
||||
else:
|
||||
# calculate time until event
|
||||
secs_remaining = remaining % 60
|
||||
remaining //= 60
|
||||
mins_remaining = remaining % 60
|
||||
|
|
@ -138,10 +156,19 @@ while True:
|
|||
hours_remaining = remaining % 24
|
||||
remaining //= 24
|
||||
days_remaining = remaining
|
||||
pixels.fill((0, 0, 0)) # Turn off all pixels
|
||||
if not finished or (finished and days_remaining < 0):
|
||||
scrolling_label.text = (f"{days_remaining} DAYS, {hours_remaining} HOURS," +
|
||||
f"{mins_remaining} MINUTES & {secs_remaining} SECONDS")
|
||||
# Remove 1 from days_remaining to count from end of day instead of start
|
||||
if days_remaining < 0:
|
||||
print(
|
||||
f"Event time in past: Adding 1 to days_remaining ({days_remaining}) to count from end of day"
|
||||
)
|
||||
days_remaining += 1
|
||||
# Update the display with current countdown value
|
||||
scrolling_label.text = (
|
||||
f"{days_remaining} DAYS, {hours_remaining} HOURS,"
|
||||
+ f"{mins_remaining} MINUTES & {secs_remaining} SECONDS"
|
||||
)
|
||||
|
||||
total_seconds += 1
|
||||
clock_clock = ticks_add(clock_clock, clock_timer)
|
||||
if ticks_diff(ticks_ms(), scroll_clock) >= scroll_timer:
|
||||
|
|
@ -150,5 +177,5 @@ while True:
|
|||
scrolling_label.x = display.width + 2
|
||||
display.refresh()
|
||||
scroll_clock = ticks_add(scroll_clock, scroll_timer)
|
||||
|
||||
|
||||
first_run = False
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,97 @@
|
|||
def setup_display():
|
||||
from displayio import release_displays
|
||||
release_displays()
|
||||
|
||||
import random
|
||||
import displayio
|
||||
import time
|
||||
import busio
|
||||
import board
|
||||
import dotclockframebuffer
|
||||
from framebufferio import FramebufferDisplay
|
||||
|
||||
init_sequence_tl032 = bytes((
|
||||
b'\x11\x80d'
|
||||
b'\xff\x05w\x01\x00\x00\x13'
|
||||
b'\xef\x01\x08'
|
||||
b'\xff\x05w\x01\x00\x00\x10'
|
||||
b'\xc0\x02\xe5\x02'
|
||||
b'\xc1\x02\x0c\n'
|
||||
b'\xc2\x02\x07\x0f'
|
||||
b'\xc3\x01\x02'
|
||||
b'\xcc\x01\x10'
|
||||
b'\xcd\x01\x08'
|
||||
b'\xb0\x10\x00\x08Q\r\xce\x06\x00\x08\x08\x1d\x02\xd0\x0fo6?'
|
||||
b'\xb1\x10\x00\x10O\x0c\x11\x05\x00\x07\x07\x1f\x05\xd3\x11n4?'
|
||||
b'\xff\x05w\x01\x00\x00\x11'
|
||||
b'\xb0\x01M'
|
||||
b'\xb1\x01\x1c'
|
||||
b'\xb2\x01\x87'
|
||||
b'\xb3\x01\x80'
|
||||
b'\xb5\x01G'
|
||||
b'\xb7\x01\x85'
|
||||
b'\xb8\x01!'
|
||||
b'\xb9\x01\x10'
|
||||
b'\xc1\x01x'
|
||||
b'\xc2\x01x'
|
||||
b'\xd0\x81\x88d'
|
||||
b'\xe0\x03\x80\x00\x02'
|
||||
b'\xe1\x0b\x04\xa0\x00\x00\x05\xa0\x00\x00\x00``'
|
||||
b'\xe2\r00``<\xa0\x00\x00=\xa0\x00\x00\x00'
|
||||
b'\xe3\x04\x00\x0033'
|
||||
b'\xe4\x02DD'
|
||||
b'\xe5\x10\x06>\xa0\xa0\x08@\xa0\xa0\nB\xa0\xa0\x0cD\xa0\xa0'
|
||||
b'\xe6\x04\x00\x0033'
|
||||
b'\xe7\x02DD'
|
||||
b'\xe8\x10\x07?\xa0\xa0\tA\xa0\xa0\x0bC\xa0\xa0\rE\xa0\xa0'
|
||||
b'\xeb\x07\x00\x01NN\xeeD\x00'
|
||||
b"\xed\x10\xff\xff\x04Vr\xff\xff\xff\xff\xff\xff'e@\xff\xff"
|
||||
b'\xef\x06\x10\r\x04\x08?\x1f'
|
||||
b'\xff\x05w\x01\x00\x00\x13'
|
||||
b'\xe8\x02\x00\x0e'
|
||||
b'\xff\x05w\x01\x00\x00\x00'
|
||||
b'\x11\x80x'
|
||||
b'\xff\x05w\x01\x00\x00\x13'
|
||||
b'\xe8\x82\x00\x0c\n'
|
||||
b'\xe8\x02\x00\x00'
|
||||
b'\xff\x05w\x01\x00\x00\x00'
|
||||
b'6\x01\x00'
|
||||
b':\x01f'
|
||||
b'\x11\x80x'
|
||||
b')\x80x'
|
||||
))
|
||||
|
||||
board.I2C().deinit()
|
||||
i2c = busio.I2C(board.SCL, board.SDA, frequency=400_000)
|
||||
tft_io_expander = dict(board.TFT_IO_EXPANDER)
|
||||
#tft_io_expander['i2c_address'] = 0x38 # uncomment for rev B
|
||||
dotclockframebuffer.ioexpander_send_init_sequence(i2c, init_sequence_tl032, **tft_io_expander)
|
||||
i2c.deinit()
|
||||
|
||||
tft_pins = dict(board.TFT_PINS)
|
||||
|
||||
tft_timings = {
|
||||
"frequency": 16000000,
|
||||
"width": 320,
|
||||
"height": 820,
|
||||
|
||||
"hsync_pulse_width": 3,
|
||||
"hsync_back_porch": 251,
|
||||
"hsync_front_porch": 150,
|
||||
"hsync_idle_low": False,
|
||||
|
||||
"vsync_pulse_width": 6,
|
||||
"vsync_back_porch": 90,
|
||||
"vsync_front_porch": 100,
|
||||
"vsync_idle_low": False,
|
||||
|
||||
"pclk_active_high": False,
|
||||
"pclk_idle_high": False,
|
||||
"de_idle_high": False,
|
||||
}
|
||||
|
||||
#bitmap = displayio.OnDiskBitmap("/display-ruler-720p.bmp")
|
||||
|
||||
fb = dotclockframebuffer.DotClockFramebuffer(**tft_pins, **tft_timings)
|
||||
display = FramebufferDisplay(fb, auto_refresh=False)
|
||||
return display
|
||||
Loading…
Reference in a new issue