CrowPanel-ESP32 Terminal — Touchscreen Pocket Photo Booth with OV2640 Camera

01 Overview

Portable, custom-built photo booths are traditionally bulky and rely on expensive computer hardware. This tutorial walks you through building an ultra-compact, touchscreen pocket photo booth using the CrowPanel ESP32 3.5 HMI Display module.

By combining an integrated ESP32 microcontroller, a high-resolution camera, and a local Wi-Fi web server, this system creates a self-contained photo-capturing device that lets users preview, capture, apply custom retro filters, and instantly download photos directly to their smartphones and computer.

Project Use Case

This project is built for makers, event hosts, and hobbyists who want a self-contained, battery-friendly photo booth without dragging along a laptop or DSLR rig. It is well suited for parties, small gatherings, or maker-fair demo booths, where guests can frame a shot, apply a retro filter, and pull the photo straight onto their phone over the device's own Wi-Fi network.

Core Technologies

  • ESP32 SoC — A low-cost, low-power system-on-a-chip with integrated Wi-Fi and dual-mode Bluetooth.
  • HMI Display — Human-Machine Interface screens designed to visualize data and accept user touch inputs.
  • CH340 USB-Serial Bridge — Converts USB signals to serial UART, allowing the computer to communicate with the ESP32.

Module Workflows

The ESP32 enters a serial bootloader mode upon reset if specific GPIO pins are pulled low, allowing new firmware to write to flash memory. Data travels asynchronously over TX (transmit) and RX (receive) lines at a matching baud rate.

02 Hardware and Software Components

Gather everything below before you start.

Hardware Components

Component Description
CrowPanel-ESP32 Terminal 3.5" Main controller and touchscreen display with built-in Wi-Fi
OV2640 Camera 2MP camera module for live preview and photo capture
MicroSD Card Local storage for saving photos and assets

Software Tools

Software Version / Details
Arduino IDE Latest stable release
LovyanGFX Fast graphics driver for ILI9488 LCD
WiFiManager Auto Wi-Fi configuration portal
esp_camera Official Espressif ESP32 camera driver

03 Application Discussion

Here is what each component does and why it is part of this project.

CrowPanel-ESP32 Terminal 3.5"

The CrowPanel-ESP32 Terminal 3.5" is the main brain and screen of the photo booth. It runs the software, registers screen touches, and displays the user menu. Its built-in Wi-Fi allows users to download photos directly to their phones using the device's IP address.

ESP32 Terminal board powered via 5V USB-C

OV2640 Camera

The OV2640 Camera takes the photos for the booth. It continuously streams a live video feed to the screen so users can frame their shots. When a user taps the screen, the camera instantly captures a clear, high-resolution picture.

OV2640 2MP Camera Module

MicroSD Card

The MicroSD Card acts as permanent storage memory. It saves all taken photos in organized folders so they are not lost when the device turns off. It also stores menu graphics and digital photo frames used to decorate pictures.

MicroSD Card local persistent photo storage

04 Hardware Setup

Wire the camera, storage, display, and feedback components to the board using the tables below.

Block Diagram

Full System Connection Details

Component Interface Purpose
OV2640 Camera 8-bit Parallel Bus + I²C/SCCB Live image streaming and camera settings
MicroSD Card Slot SPI / SDIO Save and store captured photos
Audible Buzzer Digital GPIO (NPN transistor) Shutter click sound feedback
3.5" TFT LCD Screen High-speed SPI / Parallel Bus Live camera preview and UI menus
Capacitive Touch Controller I²C (SCL/SDA) + INT line Finger tap detection and touch events
Type-C USB 5 V Power + USB-Serial Power supply and firmware flashing
Power Note: Always use the correct voltage on the USB-C port. Insufficient or excessive voltage can permanently damage internal components.

Pin Definitions

Signal GPIO Function
TOUCH_SDA 2 I²C data for touch controller
TOUCH_SCL 1 I²C clock for touch controller
LCD_MOSI 13 SPI data out to LCD
LCD_MISO 14 SPI data in from LCD
LCD_SCK 12 SPI clock
LCD_CS 3 LCD chip select
LCD_DC 42 Data/command select
LCD_BL 46 Backlight PWM control
SD_CS 10 MicroSD chip select (shared SPI bus)
BUZZER_PIN 45 NPN transistor shutter click
CAM_XCLK 7 Camera clock signal

Assembly Instructions

  1. Mount the OV2640 camera module to its parallel-bus and I²C/SCCB header on the back of the CrowPanel board.
  2. Insert a formatted MicroSD card into the onboard slot, which shares the SPI bus used for the display.
  3. Confirm the buzzer is connected through its NPN transistor stage to BUZZER_PIN (GPIO 45) for shutter-click feedback.
  4. Snap the acrylic shell into place once wiring is confirmed, leaving the USB-C port and camera lens accessible.
  5. Connect the board to your computer via USB-C for power and firmware flashing.
Note: The LCD and MicroSD card share the same SPI bus — double-check that LCD_CS and SD_CS are wired to separate, correctly defined chip-select pins to avoid bus conflicts.

05 Software Setup

Follow these steps in order to prepare the Arduino IDE before flashing the firmware.

Step 1 — Install the Arduino IDE and ESP32 Board Core

  1. Install the latest stable release of the Arduino IDE.
  2. Add the Espressif ESP32 board package through the Boards Manager so the IDE can compile for the Tensilica Xtensa processor used on the CrowPanel.

Step 2 — Board Settings

Use exactly these settings in your IDE. Wrong settings will cause upload failures.

Setting Value
Board ESP32 (match the CrowPanel's specific chip core — WROOM, WROVER, or S3)
PSRAM Enabled (QSPI or OPI, as required for the large LCD framebuffer)
Upload Driver CH340 USB-Serial driver installed on the host computer

Step 3 — Install Libraries

Install the following libraries via the Library Manager:

  • LovyanGFX — fast graphics driver for the ILI9488 LCD
  • WiFiManager — auto Wi-Fi configuration portal
  • esp_camera — official Espressif ESP32 camera driver
  • Wire, SPI, and SD — bundled with the ESP32 board core
Driver Note: Correct CH340 driver installation and matching baud rates are crucial to avoiding connection failures and corrupted serial output.

Step 4 — Upload the Code

  1. Connect the CrowPanel to your computer via USB-C.
  2. Select the correct COM port and the board settings from Step 2.
  3. Click Upload.

06 Code

The firmware is organized into logical blocks. Copy each block below into the correct location in your sketch, and read the Code Breakdown section to understand what each part does. The full code can be seen in number 6.

1 — Hardware & Pin Definitions

All pins and dimensions are defined in one place for easy reconfiguration.

Arduino / C++


#define TOUCH_SDA  2
#define TOUCH_SCL  1
#define TOUCH_ADDR 0x38

#define LCD_MOSI 13, LCD_MISO 14, LCD_SCK 12
#define LCD_CS 3,   LCD_DC 42,   LCD_BL 46

#define SD_CS      10
#define BUZZER_PIN 45

// Camera
#define CAM_XCLK 7, CAM_SIOD 2, CAM_SIOC 1
// ... all data & control pins

#define CAM_W 320, CAM_H 240
#define LCD_W 480, LCD_H 320

2 — UI & State Management

Defines the filter enum, a reusable button struct, and all program state flags.

Arduino / C++
enum FilterMode {
  FILTER_NONE, FILTER_GRAYSCALE,
  FILTER_SEPIA, FILTER_INVERT, FILTER_MIRROR
};

struct Button { int x, y, w, h; const char* label; };

// State variables
bool cameraRunning = false;
bool photoCaptured = false;
bool editingPhoto  = false;
int  editBrightness = 0, editContrast = 0, editHighlights = 0;

3 — Camera & Image Processing

Handles camera init, image buffers, filter application, and capture/reprocessing.

Arduino / C++
bool initCamera(pixformat_t fmt);

// Image buffers
uint16_t* rgbBuf;       // working buffer for processing
uint16_t* originalBuf;  // unmodified original (non-destructive edits)
uint8_t*  capturedJpeg; // final JPEG for display/saving

void applyFilter(uint16_t* buf, int w, int h);
void applyAdjustments(uint16_t* buf, int w, int h,
                      int brightness, int contrast, int highlights);
void swapAllBytes(uint16_t* buf, int count); // fixes byte order

bool capturePhoto();     // takes photo and saves original
bool reprocessCapture(); // re-applies filters/edits from original

4 — Storage & Web Server

Arduino / C++
// SD Card
bool mountSD();
bool saveToSD();

// Web server — serves HTML interface and JPEG image
void startPhotoServer();
static esp_err_t index_handler(httpd_req_t* req);
static esp_err_t photo_handler(httpd_req_t* req);

// Wi-Fi
bool connectWiFi();      // uses WiFiManager to auto-reconnect
void reconfigureWiFi();  // opens setup portal via button

5 — Display & UI Drawing

Arduino / C++
void drawHomeScreen();
void drawLiveUI();
void drawCaptureUI();
void drawEditScreen();
void drawButton(Button& b, uint16_t color);

6 — Full Code

The complete Arduino source code is provided as a separate file.

📥 Download FullCode.ino

07 Code Breakdown

Here is what each part of the code does. Read this after uploading.

Libraries

Library Purpose
LovyanGFX Fast graphics rendering for the ILI9488 LCD
Wire I²C communication for the touch controller
esp_camera Official ESP32 camera driver (Espressif)
WiFi + WiFiManager Auto-connect and on-demand Wi-Fi setup portal
SPI + SD SD card file system access
HTTP Server Serves the web interface and JPEG download endpoint

Key Functions

initCamera()

Configures the OV2640 sensor with the correct pin mapping, pixel format, frame size, and orientation. If initialization fails, an error is printed to Serial.

capturePhoto() / reprocessCapture()

capturePhoto() grabs a frame and stores the raw original. reprocessCapture() re-applies the current filter and brightness/contrast adjustments non-destructively from that saved original.

applyFilter() / applyAdjustments()

Operates on raw RGB565 pixel buffers. applyFilter() handles Grayscale, Sepia, Invert, and Mirror modes. applyAdjustments() modifies brightness, contrast, and highlights per pixel.

startPhotoServer()

Starts an HTTP server on the ESP32. index_handler serves the Photo Booth Viewer HTML page; photo_handler serves the latest JPEG as a binary response for download.

connectWiFi() / reconfigureWiFi()

connectWiFi() uses WiFiManager to auto-reconnect to saved credentials. reconfigureWiFi() opens the captive portal manually when the WIFI SETUP button is tapped.

General Program Workflow

  1. setup() — Initializes serial, pins, buffers, LCD, camera, and touch controller; shows the home screen.
  2. Home Screen — Waits for START or WIFI SETUP button tap.
  3. Live Preview — Streams camera frames to the LCD, applies the selected filter in real time.
  4. Capture Review — Displays the captured photo with SAVE WEB, EDIT, SAVE SD, HOME, and REDO options.
  5. Edit Mode — Adjusts brightness, contrast, and highlights; calls reprocessCapture() on each change.

08 Testing and Calibration

After uploading, verify each of the following to confirm the system is working correctly.

Home Screen Status Check

Power on the device and confirm the home screen reports Board Status: OK, Touch Status: OK, and Camera Status: READY. If any status fails, recheck the corresponding wiring from Section 04 before continuing.

Home Screen showing all statuses OK and READY

Wi-Fi Connection Test

Tap WIFI SETUP and confirm the device broadcasts a hotspot with on-device instructions for connecting your phone.

Wi-Fi Setup Screen with on-device instructions
Client Access Configuration: On your phone, connect to the Wi-Fi network PhotoBooth-Setup (password: 12345678). A setup page opens automatically. If not, browse to 192.168.4.1. Choose your network and enter its password.
WiFiManager portal on phone
WiFiManager portal — tap Configure WiFi
SSID and password entry screen
Enter SSID and password, then tap Save
Common Issue: If the setup page does not open automatically, manually browse to 192.168.4.1 from your phone's browser while still connected to the PhotoBooth-Setup hotspot.

Camera Preview and Filter Test

Confirm the live camera preview streams smoothly to the display and that all four filter buttons — GRAY, SEPIA, INV, and MIR — change the live image as expected.

Camera Preview Screen with GRAY, SEPIA, INV, MIR filter buttons

09 System Demonstration

The images below show the working system end-to-end, from capture to download. Use these to verify your output matches what is expected.

Captured Photo & Save Options

After tapping SHOT, the captured image is displayed with action buttons.

Captured Photo Screen with SAVE WEB, EDIT, SAVE SD buttons
Button Action
Save Web Pushes the photo to the built-in web server for download via browser
Edit Adjust contrast, brightness, and highlights before saving
Save SD Saves the photo directly to the MicroSD card
Home Return to the home screen
Redo Discard capture and return to live preview

Browser Web Interface

After tapping Save Web, open a browser on any device connected to the same Wi-Fi and navigate to the device's IP address. The Photo Booth Viewer page lets you load and download the latest captured photo.

Browser UI ready to load photo
Browser UI — tap Load Photo to fetch latest capture
Browser UI with photo loaded
Browser UI — photo loaded, tap Save to Device

Video Demonstration

10 Conclusion

This project shows that a fully self-contained, touchscreen photo booth can be built around a single ESP32 HMI module without any external computer. Pairing the OV2640 camera with non-destructive on-device filtering and a built-in Wi-Fi web server gives users an instant, phone-friendly way to capture and retrieve photos. The build highlights how carefully aligning chip core, drivers, and power supply is what separates a smooth bring-up from a frustrating one.

Findings

  • Setting up the CrowPanel requires aligning the specific ESP32 chip core (WROOM, WROVER, or S3) with the target screen hardware size.
  • Correct driver installation (CH340) and matching baud rates are crucial to avoiding connection failures and corrupted serial output.
  • Using correct and sufficient voltage on the power supply port is essential to avoid permanently damaging internal components.

Possible Improvements and Future Enhancements

  • Add a countdown timer mode for hands-free selfie captures.
  • Implement JPEG quality selection so users can choose file size vs. image quality.
  • Add an overlay / frame gallery stored on the MicroSD card for decorating photos.
  • Integrate cloud upload (e.g., Supabase or Google Drive) directly from the device.

11 References

  • ELECROW CrowPanel ESP32 Terminal Documentation — elecrow.com
  • Espressif ESP32 Arduino Core — github.com/espressif/arduino-esp32
  • LovyanGFX Library — github.com/lovyan03/LovyanGFX
  • WiFiManager Library — github.com/tzapu/WiFiManager
  • © Copyright 2012–2026 ELECROW

12 Project Authors

  • FRANZ ALDRICH P. CADUNGOG
  • JHOLAICA M. GUIAMAL
CrowPanel-ESP32 Pocket Photo Booth — CreateLabz

 

#crowpanel#esp32#ov2640 camera

Leave a comment

All comments are moderated before being published