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_enabledsave_readings_enabledbrightnessthemeselected_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.