velxio/examples/esp32-cam-lcd-preview/README.md

109 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ESP32-CAM live preview on ILI9341 TFT
What this does in plain Spanish:
> El ESP32-CAM emulado captura tu webcam con `esp_camera_fb_get()`,
> decodifica cada JPEG a RGB565 con `jpg2rgb565()` y lo dibuja en una
> pantalla ILI9341 320×240 conectada por SPI. La pantalla muestra el
> stream en vivo + una barra de estado con fps, contador de frames
> y errores de decodificación.
## What you'll see
Top of TFT (status bar, refreshed every frame):
```
VELXIO ESP32-CAM live preview ● ← live dot
frame 142 8192 B decode OK
fps 9.8 fails 0 nulls 0
```
Bottom of TFT (160×120 preview, centered):
The contents of your laptop webcam, mirrored into the simulated
ESP32-CAM frame buffer, decoded from JPEG and rendered as RGB565
pixels.
## How to run
1. **Open Velxio**, select board **ESP32-CAM** in the picker.
2. **Paste** `esp32-cam-lcd-preview.ino` into the editor.
3. **Add an ILI9341** to the canvas via the component picker (search
"ILI9341"). Position it next to the ESP32-CAM board.
4. **Wire** the components according to the diagram below (the
simulator will let you click pin pairs to draw wires).
5. **Install libraries** — open the Library Manager (book icon in
the toolbar) and install:
- `Adafruit GFX Library`
- `Adafruit ILI9341`
6. **Compile****Run**.
7. **Click the Camera button** in the canvas header → grant webcam
permission → watch your face appear on the simulated TFT.
## Wiring
```
ILI9341 ESP32-CAM
─────── ─────────
VCC ──────── 3V3
GND ──────── GND
CS ──────── GPIO 15 (orange)
RST ──────── GPIO 2 (white)
D/C ──────── GPIO 14 (yellow)
MOSI ──────── GPIO 13 (blue)
SCK ──────── GPIO 12 (green)
LED ──────── 3V3 (backlight always on)
MISO ──────── (unused — display is write-only)
```
## Why these pins
The AI-Thinker ESP32-CAM has a tight pin budget: GPIOs 0, 5, 18, 19,
21, 22, 23, 25, 26, 27, 32, 34-39 are taken by the OV2640 camera.
The exposed header gives you 12, 13, 14, 15, 16 plus 0, 2, 4, RX, TX,
3V3, 5V, GND. This sketch uses 12-15 (perfect for VSPI without
reconfiguring) and steals GPIO 2 (the on-board blue LED) for RST.
GPIO 4 (the white flash LED) is left alone.
## Tuning
- **`PREVIEW_W` / `PREVIEW_H`** (line ~70 in the sketch) — change to
`320`/`240` with `JPG_SCALE_NONE` for full-resolution preview at
the cost of ~150 KiB of DRAM (won't fit without PSRAM).
- **`JPG_SCALE_2X` → `JPG_SCALE_4X`** for an 80×60 preview centered
in a frame border. Frees up 27 KiB of RAM.
- **`delay(20)`** in the loop — drop to `0` for max framerate, or
raise to throttle the SPI bus on slower setups.
## How this works under the hood
The interesting part: `jpg2rgb565()` is a function that lives inside
`libesp32-camera.a` (the precompiled archive shipped with arduino-esp32).
The Velxio compile template
([backend/app/services/esp-idf-template/main/CMakeLists.txt](../../backend/app/services/esp-idf-template/main/CMakeLists.txt))
adds the conversions/include directory to the include path
automatically — that's how `#include "img_converters.h"` resolves.
The `Adafruit_ILI9341` driver pushes pixels via `SPI` writes that hit
QEMU's emulated I/O bus. Velxio's frontend renders the resulting
framebuffer state into the on-screen TFT element in real time. None
of this needs PSRAM, networking, or any setup beyond the Library
Manager installs.
## Caveat
Real webcam JPEGs from `getUserMedia` at quality 0.6 are typically
~10 KiB. The Velxio QEMU emulation delivers up to ~9 KiB per frame
to the firmware, with the JPEG EOI marker (`FF D9`) injected in the
last samples to guarantee `cam_verify_jpeg_eoi` accepts the frame.
This means JPEGs are usually **truncated** before reaching the
decoder — `jpg2rgb565()` may fail on some frames, in which case the
sketch shows a red-X grey rectangle instead of an image. Lowering
the JPEG quality in the frontend (`JPEG_QUALITY = 0.3` in
`useWebcamFrames.ts`) makes frames small enough to fit entirely and
decode reliably.
See `test/test-esp32-cam/autosearch/14_complete_emulation.md` for
the full forensic trace of the 9 silent bugs that had to be fixed
to make `esp_camera_fb_get()` work in QEMU.