Display smooth animations on a 128x64 OLED display connected to an ESP32 microcontroller using frame data extracted from video files.
- Python 3.7+
- OpenCV: Install with
pip install opencv-python - PlatformIO: Extension in VS Code or command-line tool
- ESP32 Board Support: Ensure ESP32 core is installed in PlatformIO
- ESP32 microcontroller (ESP32-WROOM-32 or similar)
- 128x64 OLED Display (SSD1306 controller)
- USB Cable for programming ESP32
- Breadboard & Jumper Wires
Connect your OLED display to the ESP32 with the following pin mapping:
| OLED Pin | ESP32 Pin | Description |
|---|---|---|
| GND | GND | Ground |
| VCC | 3V3 | Power Supply (3.3V) |
| SCL | GPIO 22 | I2C Clock |
| SDA | GPIO 21 | I2C Data |
OLED Display ESP32
| |
GND -------- GND ---------+
VCC -------- 3V3 ---------+
SCL -------- GPIO 22 -----+
SDA -------- GPIO 21 -----+
- Use a breadboard to organize connections
- Keep wire lengths short (< 10cm) for stable I2C communication
- Ensure proper power supply (3.3V recommended for OLED)
- Pull-up resistors may be needed if display is unstable (typically 4.7kΞ© on SCL/SDA to 3V3)
-
Aspect Ratio: Must be 2:1 (width:height)
- Example: 256Γ128, 512Γ256, 1024Γ512 pixels
- Common: 512Γ256 pixels (recommended)
-
Duration: Keep videos under 2-3 minutes (memory constraints on ESP32)
-
Format: MP4, AVI, MOV, or any format supported by OpenCV
If you have a video with a different aspect ratio, convert it first:
# Using FFmpeg - add black bars to create 2:1 aspect ratio
ffmpeg -i input_video.mp4 -vf "scale=512:256:force_original_aspect_ratio=decrease,pad=512:256:(ow-iw)/2:(oh-ih)/2" output_video.mp4
# Or crop to 2:1 ratio (removes content)
ffmpeg -i input_video.mp4 -vf "crop=512:256" output_video.mp4- Place your prepared video file in the project root directory
- Name it:
second_video.mp4(or updateVIDEO_PATHinvideo.py)
Open video.py and update if needed:
VIDEO_PATH = 'second_video.mp4' # Your input video file
OUTPUT_FILE = 'frames_data.h' # Generated output file
WIDTH = 128 # OLED width (do not change)
HEIGHT = 64 # OLED height (do not change)
FRAME_DELAY = 16 # Milliseconds between frames# From the project root directory
python video.pyWhat happens:
- Reads each frame from your video
- Resizes to 128Γ64 pixels
- Converts to grayscale
- Applies Otsu's thresholding (automatic black/white optimization)
- Converts binary image data to C++ hex format
- Generates
frames_data.hfile
Output:
Extracting and processing frames using Otsu's Algorithm...
Formatting 301 frames into flawless C++...
Success! Saved to frames_data.h. Ready to compile in PlatformIO.
- Open the generated
frames_data.hfile - Copy the entire
const unsigned char frames[][]...array - Open
src/main.cpp - REPLACE the existing frames array with your new one
- Keep everything else in main.cpp unchanged
Make sure your platformio.ini is configured for ESP32:
[env:esp32]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
monitor_speed = 115200- Plug ESP32 via USB cable
- Check COM port assignment in Device Manager (Windows) or
ls /dev/ttyUSB*(Linux)
Option A: Using PlatformIO in VS Code
- Click the PlatformIO icon in the sidebar
- Click Upload or press
Ctrl+Alt+U - Wait for compilation and upload to complete
Option B: Using Terminal
platformio run --target uploadplatformio device monitor --baud 115200You should see initialization messages on the serial monitor.
Once uploaded:
- Check OLED Display: Animation should play on your connected OLED
- Check Speed: If animation is too fast/slow, adjust
FRAME_DELAYinvideo.py - Check Quality: If image quality is poor, re-run
video.pyor adjust video lighting
- Check connections: Verify all 4 wires are firmly connected
- Test I2C address: Run an I2C scanner to confirm address is
0x3C - Check power: Ensure 3.3V is stable with a multimeter
- Enable pull-ups: If using long wires, add 4.7kΞ© pull-up resistors to SCL/SDA
- Re-run
video.pywith your video file - Verify video file is valid (try playing it)
- Ensure aspect ratio is exactly 2:1
- Check available ESP32 flash memory
- Update PlatformIO:
platformio update - Check USB cable (try different port)
- Try erasing ESP32:
platformio run --target erase - Verify board selection in
platformio.ini
# Install required Python packages
pip install opencv-python numpyIf you get "partition full" errors:
- Reduce video length
- Reduce FRAME_DELAY (skip frames)
- Use a lower resolution source video
| Resolution | Bytes/Frame | Max Frames * |
|---|---|---|
| 128Γ64 | 1024 bytes | ~3000-4000 |
*Depends on available flash memory and partition configuration
1. Prepare video (2:1 aspect ratio)
β
2. Run python video.py
β
3. Generated frames_data.h
β
4. Copy array to src/main.cpp
β
5. Upload to ESP32 via PlatformIO
β
6. Watch animation play on OLED!
- The OLED display uses I2C communication (SCL on GPIO 22, SDA on GPIO 21)
- Frames are stored in PROGMEM to save RAM
- Otsu's thresholding automatically optimizes black/white levels per frame
- Each frame is 1024 bytes (128Γ64 Γ· 8 bits)
Happy animating! π