Hi everybody, I build a learning clock for my classroom. I teach second grade in Belgium and my childern (ages 7-8) learn the analoge clock to quarter of an hour precise. So, I used a Inky Frame 7.3 to accompany an analoge clock and explain the hands of the clock duing the day. So, its almost/now/beyond hour/quarter past/half hour/quarter to.
The clock works great, the data is shown nicely I think. But I always get an error from the NTP time module:
MPY: soft reboot
Syncing RTC with NTP server...
Failed to sync with NTP server: -6
Starting main loop...
On computer, the code then uses my clock of my laptop to sync. On battery, the Inky assumes 12.00. This is my full code:
import time
import ntptime
import inky_frame
from picographics import PicoGraphics, DISPLAY_INKY_FRAME_7 as DISPLAY # 7.3"
# Set tz_offset to be the number of hours off of UTC for your local zone.
tz_offset = 0
tz_seconds = tz_offset * 3600
# Font sizes
TOP_TEXT_SCALE = 12 # Font size for the top 1/3 of the screen
BOTTOM_TEXT_SCALE = 12 # Font size for the bottom 2/3 of the screen
def sync_rtc_from_ntp():
try:
print("Syncing RTC with NTP server...")
ntptime.settime() # Sync time from NTP server
print("RTC synced with NTP server.")
except Exception as e:
print(f"Failed to sync with NTP server: {e}")
def time_to_text(hour, minute):
# Convert hour to 12-hour format
hour_12 = hour % 12 or 12
next_hour = (hour + 1) % 12 or 12
if 58 <= minute or minute <= 2:
return f"Het is nu {hour_12} uur.", (255, 255, 255), (255, 165, 0) # white, orange
elif 3 <= minute <= 7:
return f"Het is voorbij {hour_12} uur.", (255, 0, 0), (255, 165, 0) # red, orange
elif 8 <= minute <= 12:
return f"Het is bijna kwart over {hour_12}.", (0, 128, 0), (0, 128, 0) # dark green, dark green
elif 13 <= minute <= 17:
return f"Het is nu kwart over {hour_12}.", (255, 255, 255), (0, 128, 0) # white, dark green
elif 18 <= minute <= 22:
return f"Het is voorbij kwart over {hour_12}.", (255, 0, 0), (0, 128, 0) # red, dark green
elif 23 <= minute <= 27:
return f"Het is bijna half {next_hour}.", (0, 128, 0), (255, 0, 0) # dark green, red
elif 28 <= minute <= 32:
return f"Het is nu half {next_hour}.", (255, 255, 255), (255, 0, 0) # white, red
elif 33 <= minute <= 37:
return f"Het is voorbij half {next_hour}.", (255, 0, 0), (255, 0, 0) # red, red
elif 38 <= minute <= 42:
return f"Het is bijna kwart voor {next_hour}.", (0, 128, 0), (0, 0, 255) # dark green, blue
elif 43 <= minute <= 47:
return f"Het is nu kwart voor {next_hour}.", (255, 255, 255), (0, 0, 255) # white, blue
elif 48 <= minute <= 52:
return f"Het is voorbij kwart voor {next_hour}.", (255, 0, 0), (0, 0, 255) # red, blue
elif 53 <= minute <= 57:
return f"Het is bijna {hour_12} uur.", (0, 128, 0), (255, 165, 0) # dark green, orange
return f"Het is nu {hour_12} uur.", (255, 255, 255), (255, 255, 255) # default white
def split_time_text(time_text):
parts = time_text.split(" ")
if parts[2] in ["bijna", "voorbij", "nu"]:
first_part = f"Het is {parts[2]}"
second_part = " ".join(parts[3:])
else:
first_part = "Het is nu"
second_part = " ".join(parts[2:])
return first_part, second_part
def update_display():
graphics = PicoGraphics(DISPLAY)
WIDTH, HEIGHT = graphics.get_bounds()
last_update_minute = -1 # Initialized to -1 to ensure the first update occurs
while True:
current_time = time.localtime()
year, month, day, hour, minute, second, dow, _ = current_time
# Adjust for time zone offset
adjusted_hour = (hour + tz_offset) % 24
# Update only at specific minute intervals
if minute in [58, 3, 8, 13, 18, 23, 28, 33, 38, 43, 48, 53] and minute != last_update_minute:
last_update_minute = minute
# Determine background color for the top 1/3 of the screen
time_text, top_color, bottom_color = time_to_text(adjusted_hour, minute)
first_part, second_part = split_time_text(time_text)
# Set the top part background color
graphics.set_pen(graphics.create_pen(*top_color))
graphics.rectangle(0, 0, WIDTH, HEIGHT // 3)
# Set the line color
graphics.set_pen(graphics.create_pen(0, 0, 0))
graphics.rectangle(0, HEIGHT // 3 - 1, WIDTH, 1) # Black line between top and bottom parts
# Set the background color for the bottom 2/3 part
graphics.set_pen(graphics.create_pen(*bottom_color))
graphics.rectangle(0, HEIGHT // 3, WIDTH, 2 * HEIGHT // 3)
# Convert text for both parts
graphics.set_font("bitmap8")
# Calculate positions for the two parts
top_text_height = 8 * TOP_TEXT_SCALE
bottom_text_height = 8 * BOTTOM_TEXT_SCALE
first_part_width = graphics.measure_text(first_part, scale=TOP_TEXT_SCALE)
second_part_width = graphics.measure_text(second_part, scale=BOTTOM_TEXT_SCALE)
offset_left_first = (WIDTH - first_part_width) // 2
offset_top_first = (HEIGHT // 3 - top_text_height) // 2
offset_left_second = (WIDTH - second_part_width) // 2
offset_top_second = (2 * HEIGHT // 3 - bottom_text_height) // 2 + HEIGHT // 3
# Draw the text
graphics.set_pen(graphics.create_pen(0, 0, 0)) # Set text color to black for readability
graphics.text(first_part, offset_left_first, offset_top_first, scale=TOP_TEXT_SCALE)
graphics.text(second_part, offset_left_second, offset_top_second, scale=BOTTOM_TEXT_SCALE)
graphics.update()
# Wait for a while before checking the time again
time.sleep(5)
def sync_rtc_daily():
while True:
current_time = time.localtime()
year, month, day, hour, minute, second, dow, _ = current_time
# Adjust for time zone offset
adjusted_hour = (hour + tz_offset) % 24
if adjusted_hour == 4 and minute == 0:
sync_rtc_from_ntp()
print("RTC synced with NTP server at 4 AM.")
print("Local time after syncing RTC:", time.localtime())
# Wait for a while before checking the time again
time.sleep(60)
def main():
sync_rtc_from_ntp() # Initial sync with NTP server
print("Starting main loop...")
while True:
update_display()
sync_rtc_daily()
# Run the main function
main()