Skip to content

aitjcize/esp32-photoframe

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

289 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

ESP32 PhotoFrame

A modern, feature-rich firmware for ESP32-based e-paper photo frames (currently supporting Waveshare PhotoPainter and Seeed Studio XIAO EE02). This firmware replaces stock firmware with a powerful RESTful API, web interface, and significantly better image quality.

PhotoFrame

🏠 Home Assistant Integration: ha-esp32-photoframe - Companion integration for comprehensive control and monitoring through Home Assistant

Key Features

  • 🎨 Superior Image Quality: Measured color palette with automatic calibration produces significantly better results than stock firmware
  • πŸ”‹ Smart Power Management: Deep sleep mode for weeks of battery life, or always-on for Home Assistant
  • πŸ“ Flexible Image Sources: SD card rotation, URL-based fetching (weather, news, random images from image server)
  • 🌐 Modern Web Interface: Drag-and-drop uploads, gallery view, real-time battery status
  • πŸ”Œ RESTful API: Full programmatic control (API docs)
  • πŸ–ΌοΈ Image Server: Companion server with Google Photos, Synology DS Photos, and Telegram Bot support
  • 🏠 Home Assistant Ready: Companion integration available

Ecosystem

This project has companion tools for different use cases:

Project Description
ha-esp32-photoframe Home Assistant integration for control, monitoring, and automation
esp32-photoframe-server Image server with text overlay, Google Photos, Synology DS Photos, and Telegram Bot integration. Can be run as a Home Assistant add-on.
epaper-image-convert CLI tool & npm library for e-paper image conversion with advanced dithering

Third Party Integrations

Project Description
puppet-homeassistant HA Puppet add-on. Generate image URL from Puppet dashboard and use it as the Auto Rotate URL in PhotoFrame settings.

Image Quality Comparison

🎨 Try the Interactive Demo - Drag the slider to compare algorithms in real-time with your own images!

Original Image Stock Algorithm
(on computer)
Stock Algorithm
(on device)
Our Algorithm
(on device)
Source JPEG Theoretical palette
(looks OK on screen)
Theoretical palette
(washed out on device)
Measured palette
(accurate colors)

Why Our Algorithm is Better:

  • βœ… Accurate Color Matching: Uses actual measured e-paper colors
  • βœ… Automatic Calibration: Built-in palette calibration tool adapts to your specific display
  • βœ… Better Dithering: Floyd-Steinberg algorithm with measured palette produces more natural color transitions
  • βœ… No Over-Saturation: Avoids the washed-out appearance of theoretical palette matching

The measured palette accounts for the fact that e-paper displays show darker, more muted colors than pure RGB values. By dithering with these actual colors, the firmware makes better decisions about which palette color to use for each pixel, resulting in images that look significantly better on the physical display. The automatic calibration feature allows you to measure and optimize the palette for your specific device.

πŸ“– Read the technical deep-dive on measured color palettes β†’

Power Management

Deep Sleep Enabled (Default):

  • Battery life: months
  • Wake via BOOT/KEY button or auto-rotate timer
  • Web interface accessible only when awake
  • Power: ~10ΞΌA in sleep

Deep Sleep Disabled (Always-On):

  • Best for Home Assistant integration
  • Web interface always accessible
  • Power: ~40-80mA with auto light sleep
  • Battery life: days to weeks depending on usage

Auto-Rotation: SD card (default) or URL-based (fetch from web)

Configure via web interface Settings section.

AI Image Generation πŸ€–

The web interface supports client-side AI image generation using OpenAI (GPT Image, DALL-E) or Google Gemini.

  • Generate on Demand: Create custom artwork directly from the web interface using text prompts
  • Multiple Providers: OpenAI and Google Gemini supported
  • Client-Side Processing: AI generation runs in your browser, then uploads to the device

Configure your API keys in Settings > AI Generation.

Supported Hardware

Waveshare ESP32-S3-PhotoPainter

  • Product: Waveshare Wiki
  • Board Name: waveshare_photopainter_73
  • Features: 7.3" 7-color e-paper, integrated ESP32-S3, SD card slot

Seeed Studio XIAO EE02

  • Product: Seeed Studio XIAO EE02
  • Board Name: seeedstudio_xiao_ee02
  • Configuration: Setup using Seeed Studio XIAO EE02 + dedicated 13.3" ePaper display

Known Issues / Work in Progress 🚧

  • PhotoPainter Restarts: All existing Waveshare PhotoPainter boards on the market use the AXP2101 power management IC, which causes unexplained restarts when connected to both Type-C and a lithium battery simultaneously. Workaround: use either USB power only or battery only. Using both at the same time may cause frequent firmware restarts due to unstable power supply. Waveshare has confirmed this issue and future boards will ship with TG28 as a replacement, which will not have this problem. See waveshareteam/ESP32-S3-PhotoPainter#5 for details.
  • XIAO EE02 Charging: Battery charging functionality for the Seeed Studio XIAO EE02 board is currently WIP and not yet supported. Please power via USB-C or use an external charger for now.

Installation

Web Flasher (Easiest) ⚑

🌐 Flash from Browser - Chrome/Edge/Opera required

Manual Flash

Download from Releases:

esptool.py --chip esp32s3 --port /dev/ttyUSB0 --baud 921600 write_flash 0x0 photoframe-firmware-merged.bin

Device not detected? Hold BOOT button + press PWR to enter download mode.

Build from source:

We provide a build.py helper script to simplify building for different boards.

# Build for Waveshare PhotoPainter (default)
./build.py --board waveshare_photopainter_73

# Build for Seeed Studio XIAO EE02
./build.py --board seeedstudio_xiao_ee02

# Flash the firmware
idf.py -p /dev/ttyUSB0 flash monitor

For more details, see DEV.md

Setup

⚠️ Insert MicroSD card before first boot

WiFi Provisioning

The device supports two methods for WiFi provisioning:

Option 1: SD Card Provisioning (Easiest)

  1. Create a file named wifi.txt on your SD card with:

    YourWiFiSSID
    YourWiFiPassword
    
    • Line 1: WiFi SSID (network name)
    • Line 2: WiFi password
    • Use plain text, no quotes or extra formatting
  2. Insert SD card and power on the device

  3. Device automatically reads credentials, saves to memory, and connects

  4. The wifi.txt file is automatically deleted after reading (to prevent issues with invalid credentials)

Note: If credentials are invalid, the device will clear them and fall back to captive portal mode.

Option 2: Captive Portal

  1. Device creates PhotoFrame-Setup AP on first boot (if no credentials found)
  2. Connect to the AP and open http://192.168.4.1 (or use captive portal)
  3. Enter WiFi credentials (2.4GHz only)
  4. Device tests connection and saves if successful

Re-provision: Delete credentials with idf.py erase-flash or place new wifi.txt on SD card after clearing stored credentials

Usage

Web Interface: http://photoframe.local or device IP address

  • Gallery view with drag-and-drop uploads
  • Settings, battery status, display control

API: Full documentation in API.md

Troubleshooting

  • WiFi issues: Ensure 2.4GHz network, check serial monitor for IP
  • SD card not detected: Format as FAT32, try different card
  • Upload fails: Check file is valid JPEG, monitor serial output
  • Device not detected for flash: Hold BOOT + press PWR for download mode

Offline Image Processing

Node.js CLI tool for batch processing and image serving:

Batch Processing

cd process-cli && npm install
# Process to disk
node cli.js input.jpg --device-parameters -o /path/to/sdcard/images/

# Or upload directly to device
node cli.js ~/Photos/Albums --upload --device-parameters --host photoframe.local

Image Server Mode

Serve pre-processed images directly to your ESP32 over HTTP:

node cli.js --serve ~/Photos --serve-port 9000 --serve-format png --device-parameters --host photoframe.local

The ESP32 can fetch images from your computer instead of storing them on SD card. Supports BMP, PNG, and JPG formats with automatic thumbnail generation.

See process-cli/README.md for details.

License

This project is based on the ESP32-S3-PhotoPainter sample code. Please refer to the original project for licensing information.

Credits

  • Original PhotoPainter sample: Waveshare ESP32-S3-PhotoPainter
  • E-paper drivers: Waveshare
  • ESP-IDF: Espressif Systems