Last active
January 10, 2022 06:53
-
-
Save idriszmy/45d5df6510b99e8b4904a5d5c377105c to your computer and use it in GitHub Desktop.
Internet Clock using Maker Pi Pico and CircuitPython.
This file contains 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
""" | |
Internet Clock using Maker Pi Pico and CircuitPython | |
Items: | |
- Maker Pi Pico | |
https://my.cytron.io/p-maker-pi-pico | |
- ESP8266 ESP-01 WiFi Serial Transceiver Module | |
https://my.cytron.io/p-esp-01-wifi-serial-transceiver-module-esp8266 | |
- 4 In 1 MAX7219 Dot Matrix Display Module | |
https://my.cytron.io/p-4-in-1-max7219-dot-matrix-display-module | |
- USB Micro B Cable | |
https://my.cytron.io/p-usb-micro-b-cable | |
Libraries required from bundle (https://circuitpython.org/libraries): | |
- adafruit_espatcontrol | |
- adafruit_max7219 | |
- adafruit_framebuf.mpy | |
- adafruit_requests.mpy | |
- simpleio.mpy | |
- font5x8.bin (in examples folder) | |
References: | |
- https://tutorial.cytron.io/2019/10/23/dot-matrix-clock-with-ntp-server-using-esp32/ | |
Last update: 3 Jan 2022 | |
""" | |
import time | |
import busio | |
import digitalio | |
import simpleio | |
from board import * | |
from adafruit_max7219 import matrices | |
import adafruit_requests as requests | |
import adafruit_espatcontrol.adafruit_espatcontrol_socket as socket | |
from adafruit_espatcontrol import adafruit_espatcontrol | |
import json | |
# Get wifi details and more from a secrets.py file | |
try: | |
from secrets import secrets | |
except ImportError: | |
print("All secret keys are kept in secrets.py, please add them there!") | |
raise | |
TIME_API = "http://worldtimeapi.org/api/ip" | |
led = digitalio.DigitalInOut(LED) | |
led.direction = digitalio.Direction.OUTPUT | |
BUZZER = GP18 | |
# Initialize UART connection to the ESP8266 WiFi Module. | |
RX = GP17 | |
TX = GP16 | |
uart = busio.UART(TX, RX, receiver_buffer_size=2048) # Use large buffer as we're not using hardware flow control. | |
esp = adafruit_espatcontrol.ESP_ATcontrol(uart, 115200, debug=False) | |
requests.set_socket(socket, esp) | |
print("Resetting ESP module") | |
esp.soft_reset() | |
mosi = GP7 | |
clk = GP6 | |
cs = digitalio.DigitalInOut(GP5) | |
spi = busio.SPI(clk, MOSI=mosi) | |
display = matrices.CustomMatrix(spi, cs, 32, 8) | |
day = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] | |
NOTE_C4 = 261 | |
NOTE_F4 = 349 | |
NOTE_G4 = 392 | |
NOTE_A4 = 440 | |
notes_hour = [ | |
NOTE_A4, NOTE_F4, NOTE_G4, NOTE_C4, 0, NOTE_C4, NOTE_G4, NOTE_A4, NOTE_F4 | |
] | |
noteduration_hour = [ | |
2, 2, 2, 2, 2, 2, 2, 2, 2 | |
] | |
def play_melody(notes, duration): | |
for i in range(len(notes)): | |
simpleio.tone(BUZZER, notes[i], 1/duration[i]) | |
def display_colon(): | |
display.pixel(15, 2, 1) | |
display.pixel(16, 2, 1) | |
display.pixel(15, 3, 1) | |
display.pixel(16, 3, 1) | |
display.pixel(15, 5, 1) | |
display.pixel(16, 5, 1) | |
display.pixel(15, 6, 1) | |
display.pixel(16, 6, 1) | |
display.clear_all() | |
prev_seconds = None | |
prev_minutes = None | |
am_pm = "" | |
time_offset = 0 | |
request_time = False | |
display_date = False | |
internet = True | |
while not esp.is_connected: | |
try: | |
print("Connecting...") | |
esp.connect(secrets) | |
except (ValueError, RuntimeError, adafruit_espatcontrol.OKError) as e: | |
print("Failed, retrying\n", e) | |
while True: | |
if not request_time: | |
try: | |
led.value = True | |
response = requests.get(TIME_API) | |
json = response.json() | |
time_offset = json["unixtime"] + json["raw_offset"] - time.time() | |
led.value = False | |
request_time = True | |
except: | |
continue | |
current_time = time.time() + time_offset | |
now = time.localtime(current_time) | |
seconds = now.tm_sec | |
if seconds != prev_seconds: | |
prev_seconds = seconds | |
year = now.tm_year | |
month = now.tm_mon | |
mday = now.tm_mday | |
hours = now.tm_hour | |
minutes = now.tm_min | |
days = day[now.tm_wday] | |
if hours > 12: | |
hours = hours - 12 | |
am_pm = "PM" | |
else: | |
am_pm = "AM" | |
print("{}, {}/{}/{} {}:{:02}:{:02} {}".format(days, mday, month, year, hours, minutes, seconds, am_pm)) | |
if (minutes % 10 == 0 or minutes == 0) and display_date == False: | |
display_date = True | |
prev_minutes = minutes | |
day_date = "{} {} {:02}/{:02}".format(days, year, mday, month) | |
# scroll a string across the display | |
for pixel_position in range((len(day_date)-5)*6+32): | |
display.fill(0) | |
display.text(day_date, -pixel_position+32, 0) | |
display.show() | |
time.sleep(0.1) | |
if minutes == 0: | |
play_melody(notes_hour, noteduration_hour) | |
else: | |
time.sleep(5) | |
if not esp.is_connected: | |
for i in range(3): | |
try: | |
print("Connecting...") | |
esp.connect(secrets) | |
request_time = False | |
internet = True | |
break | |
except (ValueError, RuntimeError, adafruit_espatcontrol.OKError) as e: | |
print("Failed, retrying\n", e) | |
internet = False | |
else: | |
display.fill(0) | |
display.text("{:02}".format(hours), 3, 0) | |
display.text("{:02}".format(minutes), 18, 0) | |
if seconds % 2 or internet == False: | |
display_colon() | |
display.show() | |
if minutes != prev_minutes and display_date: | |
display_date = False |
This file contains 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
# Secret Keys. | |
secrets = { | |
"ssid" : "my_wifi_ssid", | |
"password" : "my_wifi_password" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment