Skip to content

Commit 18b23af

Browse files
committed
magtag haiku viewer project files
1 parent 749b53c commit 18b23af

3 files changed

Lines changed: 255 additions & 0 deletions

File tree

18 KB
Binary file not shown.

MagTag/MagTag_Haiku_Viewer/code.py

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
# SPDX-FileCopyrightText: 2025 Tim C, written for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
"""
5+
MagTag Haiku Viewer
6+
7+
Displays haikus loaded from the haikus.txt file and/or the
8+
AdafruitIO feed 'haikus'. Press left and right buttons to
9+
cycle through the avialble haikus. Press the D12 button
10+
to change to a new random haiku.
11+
"""
12+
import os
13+
import random
14+
import time
15+
16+
import bitmaptools
17+
import board
18+
import digitalio
19+
import displayio
20+
import supervisor
21+
import wifi
22+
23+
from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError
24+
from adafruit_bitmap_font import bitmap_font
25+
import adafruit_connection_manager
26+
from adafruit_debouncer import Debouncer
27+
from adafruit_display_text.bitmap_label import Label
28+
import adafruit_imageload
29+
import adafruit_requests
30+
31+
32+
# AdafruitIO connection. Will stay None if no WIFI or AIO credentials in settings.toml
33+
io = None
34+
35+
# list of all haikus collected from the local file and
36+
# ones pulled from 'haikus' feed on Adafruit IO
37+
all_haikus = []
38+
39+
# If the WIFI is auto connected from web workflow
40+
if wifi.radio.connected:
41+
# Check for AdafruitIO credentials in settings.toml
42+
aio_username = os.getenv("ADAFRUIT_AIO_USERNAME")
43+
aio_key = os.getenv("ADAFRUIT_AIO_KEY")
44+
45+
# if there are AIO credentials
46+
if None not in {aio_username, aio_key}:
47+
# Initialize connection_manager and requests
48+
pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio)
49+
ssl_context = adafruit_connection_manager.get_radio_ssl_context(wifi.radio)
50+
requests = adafruit_requests.Session(pool, ssl_context)
51+
# Initialize an Adafruit IO HTTP API object
52+
io = IO_HTTP(aio_username, aio_key, requests)
53+
54+
# variable to hold the built-in eInk display reference
55+
display = supervisor.runtime.display
56+
57+
# main group to hold all other visual elements
58+
main_group = displayio.Group()
59+
60+
# background group used for white background behind the quote
61+
# scale 8x to save memory on the Bitmap
62+
bg_group = displayio.Group(scale=8)
63+
64+
# Create & append Bitmap for the white background
65+
bg_bmp = displayio.Bitmap(display.width // 8, display.height // 8, 1)
66+
bg_palette = displayio.Palette(1)
67+
bg_palette[0] = 0xFFFFFF
68+
bg_tg = displayio.TileGrid(bg_bmp, pixel_shader=bg_palette)
69+
bg_group.append(bg_tg)
70+
main_group.append(bg_group)
71+
72+
73+
# Bamboo image element across the bottom
74+
bamboo_bmp, bamboo_palette = adafruit_imageload.load("bamboo.bmp")
75+
bamboo_tg = displayio.TileGrid(bitmap=bamboo_bmp, pixel_shader=bamboo_palette)
76+
bamboo_tg.y = display.height - bamboo_tg.tile_height - 5
77+
main_group.append(bamboo_tg)
78+
79+
# Grey border around the edges of the display
80+
border_group = displayio.Group(scale=4)
81+
border_bmp = displayio.Bitmap(display.width // 4, display.height // 4, 1)
82+
border_palette = displayio.Palette(2)
83+
border_palette[0] = 0x999999
84+
border_palette[1] = 0xFFFFFF
85+
border_palette.make_transparent(1)
86+
bitmaptools.fill_region(
87+
border_bmp, 1, 1, border_bmp.width - 1, border_bmp.height - 1, 1
88+
)
89+
border_tg = displayio.TileGrid(border_bmp, pixel_shader=border_palette)
90+
border_group.append(border_tg)
91+
main_group.append(border_group)
92+
93+
# if the AdafruitIO connection is active
94+
if io is not None:
95+
try:
96+
# Connect to the haikus IO feed
97+
haiku_feed = io.get_feed("haikus")
98+
# Retrieve data value from the feed
99+
print("Retrieving data from haiku feed...")
100+
haikus_data_from_io = io.receive_all_data(haiku_feed["key"])
101+
102+
# add the fetched haikus to the list
103+
for haiku_data in haikus_data_from_io:
104+
# replace escaped double slash newlines with single slash newline
105+
all_haikus.append(haiku_data["value"].replace("\\n", "\n"))
106+
except AdafruitIO_RequestError as re:
107+
print("No haikus feed found on AdafruitIO. Using local haikus.txt file only.")
108+
109+
110+
# attempt to load hakus from local file
111+
try:
112+
with open("haikus.txt", "r") as f:
113+
haiku_txt_file_content = f.read()
114+
115+
# add all the haikus from the file to the list
116+
for haiku in haiku_txt_file_content.split("\n\n"):
117+
all_haikus.append(haiku)
118+
except OSError as e:
119+
print("No haikus.txt file found.")
120+
121+
# make sure there is at least one haiku to show
122+
if len(all_haikus) == 0:
123+
raise ValueError(
124+
"\nNo haikus were found.\nPlease add haikus to IO\nor the haikus file."
125+
)
126+
127+
print(f"Choosing from {len(all_haikus)} haikus")
128+
# index of haiku to show. start on a random one
129+
current_index = random.randint(0, len(all_haikus) - 1)
130+
131+
# get the selected haiku from the list
132+
haiku = all_haikus[current_index]
133+
134+
# load the custom font & initialze Label to show haiku
135+
FONT = bitmap_font.load_font("fanwood_webfont_15.bdf", displayio.Bitmap)
136+
haiku_lbl = Label(FONT, text=haiku, scale=1, color=0x333333, line_spacing=1.0)
137+
haiku_lbl.anchor_point = (0, 0)
138+
haiku_lbl.anchored_position = (8, 0)
139+
main_group.append(haiku_lbl)
140+
141+
# set up left button pin and debouncer
142+
left_btn_pin = digitalio.DigitalInOut(board.D15)
143+
left_btn_pin.direction = digitalio.Direction.INPUT
144+
left_btn_pin.pull = digitalio.Pull.UP
145+
left_btn = Debouncer(left_btn_pin)
146+
147+
# set up right button pin and debouncer
148+
right_btn_pin = digitalio.DigitalInOut(board.D11)
149+
right_btn_pin.direction = digitalio.Direction.INPUT
150+
right_btn_pin.pull = digitalio.Pull.UP
151+
right_btn = Debouncer(right_btn_pin)
152+
153+
# setup D12 button and debouncer
154+
random_btn_pin = digitalio.DigitalInOut(board.D12)
155+
random_btn_pin.direction = digitalio.Direction.INPUT
156+
random_btn_pin.pull = digitalio.Pull.UP
157+
random_btn = Debouncer(random_btn_pin)
158+
159+
# set main_group as root_group to show on the display
160+
display.root_group = main_group
161+
162+
163+
def refresh_display():
164+
"""
165+
Wait until the display is ready to refresh,
166+
and then call refresh() on it.
167+
:return:
168+
"""
169+
time.sleep(display.time_to_refresh)
170+
display.refresh()
171+
172+
173+
# initial refresh to show the first haiku
174+
refresh_display()
175+
176+
# main loop
177+
while True:
178+
# update the button debouncers
179+
right_btn.update()
180+
left_btn.update()
181+
random_btn.update()
182+
183+
# if the right button was pressed
184+
if right_btn.fell:
185+
print("right button pressed")
186+
# increment the current index
187+
current_index += 1
188+
# wrap around if past len of the list
189+
if current_index >= len(all_haikus):
190+
current_index = 0
191+
# get the new haiku
192+
haiku = all_haikus[current_index % len(all_haikus)]
193+
# set the new haiku text on the Label
194+
haiku_lbl.text = haiku
195+
refresh_display()
196+
197+
# if the left button was pressed
198+
if left_btn.fell:
199+
print("left button pressed")
200+
# decrement the current index
201+
current_index -= 1
202+
# wrap around if below 0
203+
if current_index < 0:
204+
current_index = len(all_haikus) - 1
205+
# get the new haiku
206+
haiku = all_haikus[current_index % len(all_haikus)]
207+
# set the new haiku text on the Label
208+
haiku_lbl.text = haiku
209+
refresh_display()
210+
211+
# if the (D12) random button was pressed
212+
if random_btn.fell:
213+
# ensure at least 2 haikus for random function
214+
if len(all_haikus) > 1:
215+
# choose a random haiku, different from currently showing one
216+
old_index = current_index
217+
while current_index == old_index:
218+
current_index = random.randint(0, len(all_haikus) - 1)
219+
220+
# get the new haiku
221+
haiku = all_haikus[current_index % len(all_haikus)]
222+
# set the new haiku text on the Label
223+
haiku_lbl.text = haiku
224+
refresh_display()
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
while True: run this code
2+
'sudo make me a sandwich'
3+
good to the last byte
4+
5+
hot iron, cool bench
6+
everything is organized
7+
nirvana achieved
8+
9+
continuity?
10+
the multimeter goes beep
11+
testing continues
12+
13+
rainbow LEDs
14+
blink and chase and undulate
15+
example code.py
16+
17+
the printer makes noise
18+
molten plastic is coming out
19+
this never gets old
20+
21+
something big is coming
22+
the soul of a new machine
23+
abort, retry, fail?
24+
25+
The keyboard goes clack
26+
writing code at 3AM
27+
time for espresso!
28+
29+
Here is the email:
30+
your Adafruit order shipped!
31+
black box incoming

0 commit comments

Comments
 (0)