A DIY digital photo frame using a Waveshare 7.3" ACeP (7-Color) E-Ink display and an Arduino R4 WiFi. The Arduino fetches images from a self-hosted Python server running in Docker, which automatically processes photo files into compatible BIN files as well as resizes your photos to fit the e-ink display’s resolution..
- 7-Color E-Ink Display: Vibrant, paper-like quality.
- WiFi Connected: Fetches new images wirelessly.
- Smart Processing: The server automatically resizes and formats images to fit the screen (no cropping!).
- Smart Shuffle: Remembers recent images to avoid repetition.
- Deep Sleep: The Arduino sleeps between updates to save power.
- Custom Splash Screen: Display your own logo or image on boot.
- Dockerized Server: Easy to deploy on any machine (Raspberry Pi, NAS, VPS).
- Microcontroller: Arduino R4 WiFi (or any ESP32-S3 board, code may need slight adaptation).
- Raspberry Pi Zero 2 W support coming in a future update
- Display: Waveshare 7.3inch ACeP e-Paper HAT (F).
- Connection: SPI Interface (7 wires).
| Display Pin | Arduino Pin | Function |
|---|---|---|
| VCC | 5V | Power |
| GND | GND | Ground |
| DIN | D11 | MOSI |
| CLK | D13 | SCK |
| CS | D10 | Chip Select |
| DC | D9 | Data/Command |
| RST | D8 | Reset |
| BUSY | D7 | Busy Signal |
Important
Ensure the display switch is set to "0" (if applicable) or 4-wire SPI. Waveshare recommends using 5V power for the display. The display also supports 3.3V logic, but 5V logic is fine for the R4 WiFi. Check Waveshare's documentation if you need help with wiring.
The server processes your images and serves them to the frame.
- Docker & Docker Compose installed.
-
Build and Run with Docker Compose: Use the docker-compose.yml file at the root of the repository to launch the Docker container using Compose.
docker-compose up --build
The server will start on port
8080.Note: The server generates a JSON index at
http://<server-ip>:8080/eink/eink_images.json. The image URLs in this JSON are relative paths (e.g.,/eink/image.bin). The Arduino firmware handles appending the server IP. -
Build and Run with Docker CLI: Instead of using Docker Compose, you can use Docker-CLI to launch the container. The container will be kept up to date on both Docker Hub as well as GitHub's Container Registry.
docker run -d --name eink-server -p 8080:8080 -v /path/to/your/gallery:/app/gallery -v /path/to/your/eink:/app/eink ghcr.io/pcamp96/epaper-gallery:latest
docker run -d --name eink-server -p 8080:8080 -v /path/to/your/gallery:/app/gallery -v /path/to/your/eink:/app/eink pcamp96/epaper-gallery:latest
The server is now running on port 8080.
- Image Index:
http://<server-ip>:8080/eink/eink_images.json - Processed Images:
http://<server-ip>:8080/eink/
-
Open
firmware_arduino/firmware_arduino.inoin the Arduino IDE. -
Install the required libraries via Library Manager:
Arduino_JSONWiFiS3(should be built-in for R4 WiFi)
-
Open
firmware_arduino/secrets.hand configure:const char ssid[] = "YOUR_WIFI_SSID"; const char pass[] = "YOUR_WIFI_PASSWORD"; const char server_ip[] = "YOUR_SERVER_IP"; // Your server's IP const int server_port = 8080; // Port from docker-compose
-
Upload the sketch to your Arduino R4 WiFi.
The code by default will only update the image very hour, but you can change this by modifying a single line in firmware_arduino/firmware_arduino.ino:
const unsigned long SLEEP_SECONDS = 3600; // 1 hourThere are suggested refresh times in the code, but you can use any value you want.
You can "bake" a custom splash screen into the firmware so it displays instantly on boot without WiFi.
-
Place a file named
splash.pngin yourgalleryfolder on the server. -
Let the server process it (it generates
splash.binin theeinkfolder). -
Run the generator script from the root of the repository to create a C header: This creates
firmware_arduino/splash.h.# Adjust path to where the processed splash.bin is python3 generate_splash_header.py /path/to/splash.bin -
Make sure in
firmware_arduino.inothat the following line is uncommented:#include "splash.h"
-
Re-upload the sketch.