Files
tarrot/README.md
2026-06-23 06:03:19 -07:00

4.1 KiB

ESP32-P4 Tarot Touchscreen App

ESP-IDF + LVGL tarot reading app for the Waveshare ESP32-P4-86-Panel-ETH-2RO. The first version is intentionally simple and stable: it draws unique tarot cards, renders card art on-device, persists settings in NVS, and does not require a microSD card.

What Is Included

  • ESP-IDF project scaffold
  • LVGL home, reading, and settings screens
  • Full 78-card tarot deck data structure
  • 3-card and 8-card spread support
  • esp_random() card drawing with duplicate prevention
  • Upright and reversed cards
  • On-device generated card art
  • NVS-backed settings
  • Waveshare BSP display, touch, and backlight integration

Project Layout

main/
  app_main.c
  card_assets.c
  card_assets.h
  tarot_deck.c
  tarot_deck.h
  tarot_logic.c
  tarot_logic.h
  ui_main.c
  ui_main.h
  ui_settings.c
  ui_settings.h
  settings.c
  settings.h

Target Hardware

This project targets the Waveshare ESP32-P4-86-Panel-ETH-2RO, part of the ESP32-P4 4-inch 86-panel family.

Hardware assumptions:

  • 4-inch 720 x 720 IPS display
  • MIPI-DSI display interface
  • ST7703 display driver through Waveshare BSP
  • GT911 capacitive touch
  • microSD/TF slot over SDMMC/SDIO, currently not required by this app
  • Onboard 32 MB flash and 32 MB PSRAM
  • Ethernet, RS485, and 2 relay outputs present but not used by this app yet

The board support is handled through the Waveshare ESP-IDF BSP component:

waveshare/esp32_p4_wifi6_touch_lcd_4b

The BSP initializes the MIPI display, GT911 touch, LVGL port, and backlight PWM.

Build

Install and export ESP-IDF first:

. $IDF_PATH/export.sh
idf.py set-target esp32p4
idf.py menuconfig
idf.py build

This project declares LVGL through main/idf_component.yml, so ESP-IDF's component manager will fetch it during build.

The Waveshare BSP is also declared there. It provides the display, touch, and backlight hardware integration for this panel.

Flash And Monitor

idf.py -p /dev/tty.usbmodemXXXX flash monitor

Replace the serial port with your board's port.

On-Device Card Art

No SD card is required. main/card_assets.c renders a compact tarot card visual directly with LVGL widgets using deck metadata compiled into firmware.

This is deliberate for the first device build:

  • No filesystem dependency
  • No JPEG decoder dependency
  • No missing-image crash path
  • Fast startup on the panel

The deck still keeps a filename-style asset key for each card. When you want full illustrated embedded artwork, replace card_assets_create_card_art() with a lookup table from card id to embedded LVGL image descriptors.

Embedded Asset Naming Convention

Major arcana:

00_fool.jpg
01_magician.jpg
02_high_priestess.jpg
03_empress.jpg
04_emperor.jpg
05_hierophant.jpg
06_lovers.jpg
07_chariot.jpg
08_strength.jpg
09_hermit.jpg
10_wheel_of_fortune.jpg
11_justice.jpg
12_hanged_man.jpg
13_death.jpg
14_temperance.jpg
15_devil.jpg
16_tower.jpg
17_star.jpg
18_moon.jpg
19_sun.jpg
20_judgement.jpg
21_world.jpg

Minor arcana:

wands_ace.jpg
wands_02.jpg
wands_03.jpg
wands_04.jpg
wands_05.jpg
wands_06.jpg
wands_07.jpg
wands_08.jpg
wands_09.jpg
wands_10.jpg
wands_page.jpg
wands_knight.jpg
wands_queen.jpg
wands_king.jpg

cups_ace.jpg
cups_02.jpg
cups_03.jpg
cups_04.jpg
cups_05.jpg
cups_06.jpg
cups_07.jpg
cups_08.jpg
cups_09.jpg
cups_10.jpg
cups_page.jpg
cups_knight.jpg
cups_queen.jpg
cups_king.jpg

swords_ace.jpg
swords_02.jpg
swords_03.jpg
swords_04.jpg
swords_05.jpg
swords_06.jpg
swords_07.jpg
swords_08.jpg
swords_09.jpg
swords_10.jpg
swords_page.jpg
swords_knight.jpg
swords_queen.jpg
swords_king.jpg

pentacles_ace.jpg
pentacles_02.jpg
pentacles_03.jpg
pentacles_04.jpg
pentacles_05.jpg
pentacles_06.jpg
pentacles_07.jpg
pentacles_08.jpg
pentacles_09.jpg
pentacles_10.jpg
pentacles_page.jpg
pentacles_knight.jpg
pentacles_queen.jpg
pentacles_king.jpg

Settings Saved In NVS

  • reversed_cards_enabled
  • save_readings_enabled
  • brightness
  • theme
  • selected_spread

The save_readings_enabled flag is persisted and exposed in UI. Actual reading history storage is intentionally left for the next version so this first build stays stable.