# TFT Spirit Board

## Overview

https://www.youtube.com/watch?v=cN1LbZ9Gge8

The Spirit Board project replicates a physical spirit board onto an LCD display. And just like the real board, a puck or planchette slides around. Messages can be fetched from AdafruitIO or loaded into a text file on the device. Customize the messages to delight, amaze, or haunt your friends and family.

The project artwork is designed to fit two display sizes: 480x320 and 320x240. Those are the sizes of the PyPortal Titano, and standard PyPortal. An alternative version is provided that runs on Feather microcontrollers connected to a TFT FeatherWing.

## Parts
### Adafruit PyPortal Titano

[Adafruit PyPortal Titano](https://www.adafruit.com/product/4444)
The **PyPortal Titano** is the big sister to our [popular PyPortal](https://www.adafruit.com/product/4116) now with _twice as many pixels!_ The PyPortal is our easy-to-use IoT device that allows you to create all the things for the “Internet of...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4444)
[Related Guides to the Product](https://learn.adafruit.com/products/4444/guides)
![Hand holding PyPortal Titano development board with SAMD51, ESP32 Wifi, and 3.5" touchscreen TFT display.](https://cdn-shop.adafruit.com/640x480/4444-10.jpg)

### Adafruit PyPortal - CircuitPython Powered Internet Display

[Adafruit PyPortal - CircuitPython Powered Internet Display](https://www.adafruit.com/product/4116)
 **PyPortal** , our easy-to-use IoT device that allows you to create all the things for the “Internet of Things” in minutes. Make custom touch screen interface GUIs, all open-source, and Python-powered using&nbsp;tinyJSON / APIs to get news, stock, weather, cat photos,...

In Stock
[Buy Now](https://www.adafruit.com/product/4116)
[Related Guides to the Product](https://learn.adafruit.com/products/4116/guides)
![Front view of a Adafruit PyPortal - CircuitPython Powered Internet Display with a pyportal logo image on the display. ](https://cdn-shop.adafruit.com/640x480/4116-00.jpeg)

### Adafruit TFT FeatherWing - 3.5" 480x320 Touchscreen for Feathers

[Adafruit TFT FeatherWing - 3.5" 480x320 Touchscreen for Feathers](https://www.adafruit.com/product/3651)
Spice up your Feather project with a beautiful 3.5" touchscreen display shield with built in microSD card socket. This TFT display is 3.5" diagonal with a bright 6 white-LED backlight. You get a massive 480x320 pixels with individual 16-bit color pixel control. It has way more...

In Stock
[Buy Now](https://www.adafruit.com/product/3651)
[Related Guides to the Product](https://learn.adafruit.com/products/3651/guides)
![Overhead shot of a Black woman's hands with a blue and pinkish-red manicure drawing a heart on a touchscreen breakout.](https://cdn-shop.adafruit.com/640x480/3651-05.jpg)

### Adafruit ESP32-S3 Feather with STEMMA QT / Qwiic

[Adafruit ESP32-S3 Feather with STEMMA QT / Qwiic](https://www.adafruit.com/product/5323)
The ESP32-S3 has arrived in Feather format - and what a great way to get started with this powerful new chip from Espressif! With dual 240 MHz cores, WiFi and BLE support, and native USB, this Feather is great for powering your IoT projects.

That's right - it's the new...

In Stock
[Buy Now](https://www.adafruit.com/product/5323)
[Related Guides to the Product](https://learn.adafruit.com/products/5323/guides)
![Angled shot of rectangular microcontroller.](https://cdn-shop.adafruit.com/640x480/5323-06.jpg)

### Adafruit ESP32-S2 Feather - 4 MB Flash + 2 MB PSRAM

[Adafruit ESP32-S2 Feather - 4 MB Flash + 2 MB PSRAM](https://www.adafruit.com/product/5000)
What's Feather-shaped and has an ESP32-S2 WiFi module? What has a STEMMA QT connector for I2C devices? What has your favorite Espressif WiFi microcontroller and lots of Flash and RAM memory for your next IoT project? What will make your next IoT project flyyyyy?

That's right -...

In Stock
[Buy Now](https://www.adafruit.com/product/5000)
[Related Guides to the Product](https://learn.adafruit.com/products/5000/guides)
![Angled shot of rectangular microcontroller.](https://cdn-shop.adafruit.com/640x480/5000-12.jpg)

# TFT Spirit Board

## Project Setup PyPortal

Are you new to using CircuitPython? No worries,&nbsp;[there is a full getting-started guide here](https://learn.adafruit.com/welcome-to-circuitpython "Welcome to CircuitPython").

Plug the device into your computer with a known good USB cable (not a charge-only cable). The device will appear to your computer in File Explorer or Finder (depending on your operating system) as a flash drive named&nbsp; **CIRCUITPY**. If the drive does not appear, you can&nbsp;[install CircuitPython](https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython)&nbsp;on your device and then return here.

Download the project files with the Download Project Bundle button below.&nbsp;Unzip the file and copy/paste the&nbsp; **code.py** &nbsp;and other project files to your&nbsp; **CIRCUITPY** &nbsp;drive using File Explorer or Finder (depending on your operating system).

## Drive Structure

After copying the files, your drive should look like the listing below. It can contain other files as well, but must contain these at a minimum.

The code used by the different sized PyPortals is the same, but they do have different sized graphics. There are drive structure screenshots provided for each device below.

### PyPortal Standard
![pyportal](https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/folder-images/TFT_Spirit_Board_pyportal.png?raw=true )

### PyPortal Titano
![PyPortal](https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/folder-images/TFT_Spirit_Board_pyportal_titano.png?raw=true )

## Code

The **code.py** file for the project is shown below.

The same **code.py** file is used for both the PyPortal and the PyPortal Titano, however the image assets differ.

## PyPortal Standard Bundle

Use this Project Bundle button to download the standard PyPortal project bundle.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/TFT_Spirit_Board/pyportal/code.py

## PyPortal Titano Bundle

Use this Porject Bundle button to download the PyPortal Titano project bundle.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/TFT_Spirit_Board/pyportal_titano/code.py

# TFT Spirit Board

## Project Setup TFT Featherwing

Are you new to using CircuitPython? No worries,&nbsp;[there is a full getting-started guide here](https://learn.adafruit.com/welcome-to-circuitpython "Welcome to CircuitPython").

Plug the your device into your computer with a known good USB cable (not a charge-only cable). The device will appear to your computer in File Explorer or Finder (depending on your operating system) as a flash drive named&nbsp; **CIRCUITPY**. If the drive does not appear, you can&nbsp;[install CircuitPython](https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython)&nbsp;on your device and then return here.

Download the project files with the Download Project Bundle button below.&nbsp;Unzip the file and copy/paste the&nbsp; **code.py** &nbsp;and other project files to your&nbsp; **CIRCUITPY** &nbsp;drive using File Explorer or Finder (depending on your operating system).

## Drive Structure

After copying the files, your drive should look like the listing below. It can contain other files as well, but must contain these at a minimum:

![Feather](https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/folder-images/TFT_Spirit_Board_esp32s3_s2_tft_featherwing_480x320.png?raw=true )

## Code

The **code.py** file for the project is shown below:

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/TFT_Spirit_Board/esp32s3_s2_tft_featherwing_480x320/code.py

# TFT Spirit Board

## Loading Messages

There are 2 ways for the "spirits" to get their messages into the device: dynamically via AdafruitIO, or preloaded into a text file on the&nbsp; **CIRCUITPY** drive. The code provided by the project will attempt to fetch messages from AdafruitIO first, and if that doesn't succeed it will look for the **spirit\_messages.txt** file locally to read messages from.

### AdafruitIO Setup

To fetch messages from AdafruitIO, you need to add your WiFi details to **settings.toml** if you haven't already, and set up a SpiritBoard feed on AdafruitIO.

[This guide page](https://learn.adafruit.com/pico-w-wifi-with-circuitpython/create-your-settings-toml-file "Link to settings.toml setup") shows the process of creating and adding the necessary WiFi details plus AdafruitIO username and token to the **settings.toml** file. If you don't already have those in your **settings.toml** file from other projects then follow along with that page before returning here.&nbsp;

The environment variable names expected by this project are:

- `CIRCUITPY_WIFI_SSID`
- `CIRCUITPY_WIFI_PASSWORD`
- `AIO_USERNAME`
- `AIO_KEY`

Open your browser to adafruit.io and login. Click the feeds link at the top. Next, click the 'New Feed' button near the top left. Enter the name "SpiritBoard" and optionally a description.

![circuitpython_create_feed.png](https://cdn-learn.adafruit.com/assets/assets/000/133/103/medium640/circuitpython_create_feed.png?1728675217)

### Local File

If you don't want to use WiFi, you can instead load your messages one per line into a file called&nbsp; **spirit\_messages.txt&nbsp;** and put it at the root directory (\) of your&nbsp; **CIRCUITPY** drive. An empty **spirit\_messages.txt** file is included in the project bundle so you be able to jump right into editing it (in any text editor) if you loaded the files from the bundle.

Example **spirit\_messages.txt** contents:

```auto
hello world
spirits are near
i &lt;3 circuitpython
goodbye
```

# TFT Spirit Board

## Code Explanation

The code for this project is split into 3 main parts. Two of them are shared across all of the different supported devices, and the last part is more specific to the hardware used.

## General components used by all versions

- `AnchoredTilegrid` - This library provides a small wrapper class that extends TileGrid and provides the ability to place the `TileGrid` relative to points other than it's top left corner. This is useful because it allows us to place the planchette relative to the center of the window and not have to worry about the offset from the top left. See the&nbsp;[documentation](https://docs.circuitpython.org/projects/anchored_tilegrid/en/latest/) and [library repository](https://github.com/adafruit/Adafruit_CircuitPython_Anchored_TileGrid) for more information and basic example usage of this class.
- `SpiritBoard` - This class holds everything needed to display the spirit board and planchette as well as slide the planchette around to write messages.&nbsp;

## Hardware specific code.py and media

The display setup (or lack thereof), the different possible touch overlays, and the different methods used to connect to WiFi mean that this project has a few variations of the **code.py** file in order to support the different possible bits of hardware.

- PyPortal Titano - Built-in display with generic touch driver, esp32spi wifi
- PyPortal - Built-in display w/ smaller size and generic touch driver, esp32spi wifi
- Feather ESP32-S3 or S2 + TFT Featherwing - External display with tsc2007 touch driver, core wifi

The two different supported display sizes are 480x320 and 320x240. There are spirit board and planchette image files provided in the respective project bundles for each of those display sizes.

## SpiritBoard Class

This class contains most of the shared code that all versions use. It is responsible for all of the graphics in this project. It extends the `displayio.Group` class, so that it can hold other displayio elements and can be set as the `root_group` on the display.

When initialized, it loads and displays the spirit board image in the background, and the planchette image in the foreground. It checks the height and width of the display object passed to the initialization to determine which assets should be used. If it finds the smaller of the two supported screen sizes it will also scale down the letter positions to fit the smaller sized board.

### Write Message

The `write_message()` function is the highest level function, and is one of the functions called by the&nbsp; **code.py** files. It accepts a string message and will slide the planchette around to output the message. The logic in the function is responsible for breaking the message into its different words, then determining whether each word is one of the full words on the board, or needs to be output letter by letter. The movement of the planchette is delegated to the another of the primary functions for this class.&nbsp;

### Slide Planchette

The&nbsp;`slide_planchette()` function handles moving the planchette from one location on the display to another. In order to do this it finds equally spaced points along the line between the points representing where we are moving from and moving to. The target location tuple is a required argument. There are optional arguments&nbsp;`delay` and `step_size` which work together to control how fast the planchette will slide. Delay is the time it will wait between steps, and `step_size` is how big of a step it will take with each movement.

### Get Messages

`get_messages()` is responsible for getting the messages which will be displayed by the board. It uses two other functions descriptively named after the purpose they serve. It will first use `sync_with_io()` to attempt to fetch the messages from a "SpiritBoard" feed on AdafruitIO using the username and token stored in the&nbsp; **settings.toml** file. If that does not succeed then it will use `read_local_messages_file()` to fallback to looking for messages inside of a local file named **spirit\_messages.txt.&nbsp;** See the [Loading Messages](https://learn.adafruit.com/tft-spirit-board/loading-messages) page of this guide for instructions on how to load these messages.

Find the SpiritBoard class code file is embedded below. It is thoroughly commented with details explaining what each portion does.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/TFT_Spirit_Board/pyportal/spirit_board.py


## Featured Products

### Adafruit PyPortal Titano

[Adafruit PyPortal Titano](https://www.adafruit.com/product/4444)
The **PyPortal Titano** is the big sister to our [popular PyPortal](https://www.adafruit.com/product/4116) now with _twice as many pixels!_ The PyPortal is our easy-to-use IoT device that allows you to create all the things for the “Internet of...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4444)
[Related Guides to the Product](https://learn.adafruit.com/products/4444/guides)
### Adafruit PyPortal - CircuitPython Powered Internet Display

[Adafruit PyPortal - CircuitPython Powered Internet Display](https://www.adafruit.com/product/4116)
 **PyPortal** , our easy-to-use IoT device that allows you to create all the things for the “Internet of Things” in minutes. Make custom touch screen interface GUIs, all open-source, and Python-powered using&nbsp;tinyJSON / APIs to get news, stock, weather, cat photos,...

In Stock
[Buy Now](https://www.adafruit.com/product/4116)
[Related Guides to the Product](https://learn.adafruit.com/products/4116/guides)
### Adafruit TFT FeatherWing - 3.5" 480x320 Touchscreen for Feathers

[Adafruit TFT FeatherWing - 3.5" 480x320 Touchscreen for Feathers](https://www.adafruit.com/product/3651)
Spice up your Feather project with a beautiful 3.5" touchscreen display shield with built in microSD card socket. This TFT display is 3.5" diagonal with a bright 6 white-LED backlight. You get a massive 480x320 pixels with individual 16-bit color pixel control. It has way more...

In Stock
[Buy Now](https://www.adafruit.com/product/3651)
[Related Guides to the Product](https://learn.adafruit.com/products/3651/guides)
### Adafruit ESP32-S3 Feather with STEMMA QT / Qwiic

[Adafruit ESP32-S3 Feather with STEMMA QT / Qwiic](https://www.adafruit.com/product/5323)
The ESP32-S3 has arrived in Feather format - and what a great way to get started with this powerful new chip from Espressif! With dual 240 MHz cores, WiFi and BLE support, and native USB, this Feather is great for powering your IoT projects.

That's right - it's the new...

In Stock
[Buy Now](https://www.adafruit.com/product/5323)
[Related Guides to the Product](https://learn.adafruit.com/products/5323/guides)
### Adafruit ESP32-S2 Feather - 4 MB Flash + 2 MB PSRAM

[Adafruit ESP32-S2 Feather - 4 MB Flash + 2 MB PSRAM](https://www.adafruit.com/product/5000)
What's Feather-shaped and has an ESP32-S2 WiFi module? What has a STEMMA QT connector for I2C devices? What has your favorite Espressif WiFi microcontroller and lots of Flash and RAM memory for your next IoT project? What will make your next IoT project flyyyyy?

That's right -...

In Stock
[Buy Now](https://www.adafruit.com/product/5000)
[Related Guides to the Product](https://learn.adafruit.com/products/5000/guides)

## Related Guides

- [Adafruit 3.5" 480x320 TFT FeatherWing](https://learn.adafruit.com/adafruit-3-5-tft-featherwing.md)
- [Adafruit PyPortal - IoT for CircuitPython](https://learn.adafruit.com/adafruit-pyportal.md)
- [Adafruit PyPortal Titano](https://learn.adafruit.com/adafruit-pyportal-titano.md)
- [Adafruit ESP32-S2 Feather](https://learn.adafruit.com/adafruit-esp32-s2-feather.md)
- [Adafruit ESP32-S3 Feather](https://learn.adafruit.com/adafruit-esp32-s3-feather.md)
- [Karel The Robot In CircuitPython](https://learn.adafruit.com/karel-the-robot-in-circuitpython.md)
- [Pathfinder Robot Companion](https://learn.adafruit.com/pathfinder.md)
- [Infinite Text Adventure](https://learn.adafruit.com/infinite-text-adventure.md)
- [Playing Animated GIF Files in CircuitPython](https://learn.adafruit.com/using-animated-gif-files-in-circuitpython.md)
- [Cleveland Museum of Art PyPortal Frame](https://learn.adafruit.com/cleveland-museum-of-art-pyportal-frame.md)
- [Data Logging IoT Weight Scale](https://learn.adafruit.com/data-logging-iot-weight-scale.md)
- [PyPortal YouTube Views and Subscribers Display](https://learn.adafruit.com/pyportal-youtube-views-and-subscribers-display.md)
- [ESP32-S3 BLE RS-232 Controller](https://learn.adafruit.com/esp32-s3-ble-rs232-controller.md)
- [Where's My Friend? A Location-Aware Display with PyPortal and ItsASnap](https://learn.adafruit.com/where-s-my-friend-a-location-display-frame-with-pyportal.md)
- [How to Add a New Board to WipperSnapper](https://learn.adafruit.com/how-to-add-a-new-board-to-wippersnapper.md)
- [Quickstart: Adafruit IO WipperSnapper ](https://learn.adafruit.com/quickstart-adafruit-io-wippersnapper.md)
- [CircuitPython Display_Text Library](https://learn.adafruit.com/circuitpython-display-text-library.md)
- [PyPortal Wall Mount](https://learn.adafruit.com/pyportal-wall-mount.md)
- [PyPortal View Master](https://learn.adafruit.com/pyportal-view-master.md)
