Skip to content

Commit ea2aac8

Browse files
authored
Merge pull request #2904 from FoamyGuy/tft_spirit_board
Tft spirit board
2 parents 77ce50c + de62cdf commit ea2aac8

File tree

7 files changed

+522
-0
lines changed

7 files changed

+522
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# SPDX-FileCopyrightText: 2024 Tim Cocks
2+
#
3+
# SPDX-License-Identifier: MIT
4+
"""
5+
SpiritBoard code.py
6+
Feather ESP32-S3 or S2 + TFT Featherwing 3.5" 480x320 pixels
7+
8+
Receive and display messages from the spirits.
9+
"""
10+
# pylint: disable=import-error, invalid-name
11+
import os
12+
import displayio
13+
import board
14+
from digitalio import DigitalInOut
15+
import adafruit_connection_manager
16+
import wifi
17+
import adafruit_requests
18+
from adafruit_io.adafruit_io import IO_HTTP
19+
from adafruit_hx8357 import HX8357 # TFT Featherwing 3.5" 480x320 display driver
20+
import adafruit_tsc2007
21+
22+
from spirit_board import SpiritBoard
23+
24+
25+
26+
# 3.5" TFT Featherwing is 480x320
27+
displayio.release_displays()
28+
DISPLAY_WIDTH = 480
29+
DISPLAY_HEIGHT = 320
30+
31+
# Initialize TFT Display
32+
spi = board.SPI()
33+
tft_cs = board.D9
34+
tft_dc = board.D10
35+
display_bus = displayio.FourWire(spi, command=tft_dc, chip_select=tft_cs)
36+
display = HX8357(display_bus, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT)
37+
display.rotation = 0
38+
_touch_flip = (False, True)
39+
40+
# Initialize 3.5" TFT Featherwing Touchscreen
41+
ts_cs_pin = DigitalInOut(board.D6)
42+
i2c = board.I2C()
43+
tsc = adafruit_tsc2007.TSC2007(i2c, irq=None)
44+
45+
# Initialize a requests session
46+
pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio)
47+
ssl_context = adafruit_connection_manager.get_radio_ssl_context(wifi.radio)
48+
requests = adafruit_requests.Session(pool, ssl_context)
49+
50+
# Set your Adafruit IO Username and Key in secrets.py
51+
# (visit io.adafruit.com if you need to create an account,
52+
# or if you need your Adafruit IO key.)
53+
aio_username = os.getenv("AIO_USERNAME")
54+
aio_key = os.getenv("AIO_KEY")
55+
56+
# Initialize an Adafruit IO HTTP API object
57+
io = IO_HTTP(aio_username, aio_key, requests)
58+
59+
# initialize the SpiritBoard class
60+
spirit_board = SpiritBoard(display)
61+
62+
# get messages from io or the local file
63+
messages = spirit_board.get_messages(io)
64+
65+
# The planchette is already at the home position.
66+
# Slide it to home again to make it jump, in order
67+
# indicate the message is ready to be received.
68+
spirit_board.slide_planchette(SpiritBoard.LOCATIONS["home"],
69+
delay=0.02, step_size=6)
70+
71+
# current message index
72+
message_index = 0
73+
while True:
74+
# if the display was touched
75+
if tsc.touched:
76+
# write the message at the current index
77+
spirit_board.write_message(messages[message_index], step_size=8)
78+
79+
# if there are more messages in the list inside of context
80+
if message_index < len(messages) - 1:
81+
# increment the message index
82+
message_index += 1
83+
84+
else: # there are no more messages in the list
85+
# reset the index to 0
86+
message_index = 0
87+
print("fetching next")
88+
89+
# fetch new messages
90+
messages = spirit_board.get_messages(io)
91+
92+
# make the planchette jump to indicate messages are ready to display
93+
spirit_board.slide_planchette(SpiritBoard.LOCATIONS["home"],
94+
delay=0.02, step_size=6)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../shared/lib/
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../shared/spirit_board.py
Binary file not shown.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# SPDX-FileCopyrightText: 2024 Tim Cocks
2+
#
3+
# SPDX-License-Identifier: MIT
4+
"""
5+
AnchoredTilegrid helper class
6+
"""
7+
try:
8+
from typing import Tuple
9+
except ImportError:
10+
pass
11+
12+
from displayio import TileGrid
13+
14+
15+
class AnchoredTileGrid(TileGrid):
16+
"""
17+
AnchoredTileGrid extends TileGrid and allows placing the TileGrid
18+
relative to an arbitrary anchor point.
19+
"""
20+
def __init__(self, bitmap, **kwargs):
21+
super().__init__(bitmap, **kwargs)
22+
self._anchor_point = (0, 0)
23+
24+
self._anchored_position = (
25+
0 if "x" not in kwargs else kwargs["x"],
26+
0 if "y" not in kwargs else kwargs["y"]
27+
)
28+
29+
@property
30+
def anchor_point(self):
31+
"""
32+
The anchor point. tuple containing x and y values ranging
33+
from 0 to 1.
34+
"""
35+
return self._anchor_point
36+
37+
@anchor_point.setter
38+
def anchor_point(self, new_anchor_point: Tuple[float, float]) -> None:
39+
self._anchor_point = new_anchor_point
40+
# update the anchored_position using setter
41+
self.anchored_position = self._anchored_position
42+
43+
@property
44+
def anchored_position(self) -> Tuple[int, int]:
45+
"""Position relative to the anchor_point. Tuple containing x,y
46+
pixel coordinates."""
47+
return self._anchored_position
48+
49+
@anchored_position.setter
50+
def anchored_position(self, new_position: Tuple[int, int]) -> None:
51+
self._anchored_position = new_position
52+
53+
if (self._anchor_point is not None) and (self._anchored_position is not None):
54+
# Calculate (x,y) position
55+
self.x = int(
56+
new_position[0]
57+
- round(self._anchor_point[0] * (self.tile_width * self.width))
58+
)
59+
60+
self.y = int(
61+
new_position[1]
62+
- round(self._anchor_point[1] * (self.tile_height * self.height))
63+
)

0 commit comments

Comments
 (0)