Files
sunflower-picture-app/README.md

5.3 KiB

ESP32-S3-LCD-1.47 Sound & Picture Player

This repository contains a responsive, dual-core firmware application developed for the Waveshare ESP32-S3-LCD-1.47 development board.

The application reads PNG images and uncompressed PCM WAV audio files from a microSD card, renders the images on the onboard ST7789 LCD display, and plays matching soundbites over an external I2S audio DAC when the onboard button is pressed.


🚀 Key Features

  • Alpha-Numeric Media Pairing: Scans the root of the microSD card for PNG and WAV files, sorting and matching them alphabetically (e.g., 01_image.png pairs with 01_sound.wav).
  • Background Multi-Threaded Audio: Spawns a dedicated FreeRTOS task pinned to Core 0 for I2S WAV streaming, preventing audio stutter and keeping the UI on Core 1 fully responsive.
  • Dual Operation Modes:
    • Manual Mode (Default): Advances slides and triggers soundbites on single-presses.
    • Autoplay (Slideshow) Mode: Long-pressing the button (>1.5s) toggles a hands-free slideshow. It automatically advances to the next slide 5 seconds after the previous audio track has finished playing.
  • WS2812 RGB LED Status Feedback: Utilizes the onboard RGB LED to output real-time visual feedback:
    • 🔵 Solid Blue: Idle, waiting for manual trigger.
    • 🟢 Pulsing Green: Audio is playing.
    • 🟣 Pulsing Purple: Autoplay/Slideshow mode is active.
    • 🔴 Blinking Red: Error state (microSD card failed to initialize, or no media files were found).

🔌 Hardware Connections (External I2S DAC)

Because the Waveshare ESP32-S3-LCD-1.47 does not have built-in audio amplification or a speaker, you must connect an external I2S DAC/Amplifier (e.g., MAX98357A or PCM5102) to the exposed headers.

Configure the pin connections as follows:

Board Pin (Header) ESP32-S3 GPIO Function
GPIO 1 1 I2S BCLK (Bit Clock)
GPIO 2 2 I2S LRCK / WS (Frame Clock)
GPIO 4 4 I2S DIN / SD (Data Out from ESP)
3V3 / VBUS (5V) VCC Power Supply
GND GND Ground Reference

Note: The physical BOOT button is permanently connected to GPIO 9 and acts as the input control.


📁 Repository Structure

├── sound_picture_app/         # Custom Application Source
│   ├── sound_picture_app.ino  # Main coordinator, button gestures, state machine
│   ├── Display_ST7789.h/.cpp  # Waveshare display initialization & backlight control
│   ├── Display_PNG.h/.cpp     # PNGdec utility for decoding and drawing images
│   ├── SD_Card.h/.cpp         # SD_MMC mount and folder retrieval helpers
│   └── Audio_Player.h/.cpp    # WAV parser and background I2S player thread
├── ESP32-S3-LCD-1.47-Demo/    # Waveshare Official Reference Demos
└── README.md                  # This file

💾 microSD Card Setup

  1. Format a microSD card to FAT32.
  2. Place your images in the root directory:
    • Extension: .png
    • Resolution: Sized to 172 x 320 pixels.
  3. Place your sound files in the root directory:
    • Extension: .wav
    • Format: Uncompressed PCM WAV (Supports Mono/Stereo, 8/16/24/32-bit depths).
  4. Ensure file names map alphabetically:
    • photo1.png <--> sound1.wav
    • photo2.png <--> sound2.wav

🛠️ Software Setup & Flashing (Arduino IDE)

1. Board Package Installation

Make sure you have the official Espressif board package installed:

  • Go to File > Preferences > Additional Boards Manager URLs and add: https://espressif.github.io/arduino-esp32/package_esp32_index.json
  • Go to Tools > Board > Boards Manager, search for esp32 (by Espressif Systems), and install version 3.0.2 or higher.

2. Install Required Libraries

  • Go to Sketch > Include Library > Manage Libraries...
  • Search for PNGdec (by Larry Bank) and click Install.

3. Select Board Configurations

Go to the Tools menu and set the following variables:

  • Board: ESP32S3 Dev Module
  • USB CDC On Boot: Enabled (Required to see print logs over the native USB port)
  • Upload Speed: 921600
  • Flash Size: 16MB (128Mb)
  • Partition Scheme: 16MB Flash (3MB APP/9.9MB FATFS)

4. Upload

  1. Connect your board to your computer via USB.
  2. Select the corresponding COM Port under Tools > Port.
  3. Click Upload (or press Ctrl+U).

🧠 Code Architecture & Multi-threading

Drawing to SPI displays and reading from SD cards are heavily blocking SPI transactions. To prevent audio dropouts and stutters while loading images, the firmware divides work across the ESP32-S3's dual cores:

  • Core 1 (Main Thread): Runs the standard Arduino loop(). It performs debounced button polling, updates the NeoPixel LED pulse timers, and controls the display state transitions.
  • Core 0 (Audio Thread): When a WAV file is selected, playWav() spawns a background thread pinned to Core 0. This thread handles:
    1. Opening the file handler.
    2. Parsing raw WAV headers dynamically (calculating sample rate, bit depth, channel configuration).
    3. Re-initializing the standard ESP32 ESP_I2S driver configuration.
    4. Streaming sample data chunks into I2S DMA buffers, pausing and yielding if the DMA buffer fills.