Flipper Zero Camera Suite title screen

Building a camera for Flipper Zero with an ESP32-CAM

You can use the Flipper Zero Camera Suite to make a cheap ESP32-CAM module work like it belongs on a Flipper Zero. The repository is split into two parts: firmware for the ESP32-CAM in firmware/, and the Flipper app in fap/. Together they let me stream a live preview to the Flipper screen, tweak a few image controls, and save captures from the device itself.

Why I made it

I liked the idea of giving the Flipper a camera without pretending it was going to become a polished photography device. The whole point of this project is that it stays small, cheap, and a little weird. At its core, this is about capturing live previews and saving those blocky little memories with an ESP32-CAM wired into the Flipper over GPIO.

That shaped the UX too. I wanted just enough control to make the feed usable on a Flipper screen, contrast up and down, invert, dithering on and off, rotation, flash, and a quick way to save a shot to the SD card. It is intentionally simple, and that simplicity is part of what makes it fun.

How the system works

On the firmware side, the ESP32-CAM starts a serial connection at 230400, initializes the camera, loads a default camera model, and then sits in a loop reading one-byte commands from serial. Those commands are small and direct. I use single characters to toggle streaming, flash, invert, dithering, brightness, contrast, and the selected dithering mode.

For the live feed, I keep the camera configured for PIXFORMAT_GRAYSCALE at FRAMESIZE_128X128. When streaming is enabled, the firmware can run error-diffusion dithering, then packs 8 pixels into a byte and sends each row with a tiny header: Y: plus the row number. On the Flipper side, a worker thread reads that serial stream into a buffer, checks the row header, reconstructs the image row by row, and redraws the screen.

Live preview running in Flipper Zero Camera Suite

When the camera view opens on the Flipper, the app sends S to start streaming, pushes the selected dithering mode, resets invert, and applies the current flash state. While the stream is running, the Flipper just keeps sending tiny one-character control messages back to the ESP32-CAM whenever I press a direction or toggle an option.

What is happening inside the Flipper app

The Flipper side is structured like a normal multi-scene app. There is a start screen, a main menu, a camera view, a guide view, camera settings, and application settings. The main menu branches through the scene manager and view dispatcher, and the app saves things like orientation, dithering, flash, haptics, speaker, and LED feedback to a config file so they persist between runs.

Hardware, flashing, and getting it running

ESP32-CAM to Flipper Zero pinout guide

The wiring is straightforward: VCC goes to 3V3, GND to GND, U0R to TX, and U0T to RX. For flashing, the ESP32-CAM also needs IO0 tied to GND so it boots into flash mode.

There are two installation paths by design. The easy firmware path is the Windows flashing script at the repo root, firmware-flash.bat. The manual path uses the Arduino IDE, the AI Thinker ESP32-CAM board profile, and the Flipper's GPIO > USB-UART Bridge mode. On the app side, the Flipper application can be installed from the Flipper app catalog, or you can manually copy the built camera_suite.fap into apps/gpio on the MicroSD card.

You can also check out my Flipper Zero Development Toolkit for a Visual Studio Code workflow.

Big thanks

This project also owes a lot to earlier work. It is based on Z4urce's Flipper Zero Camera Application, and I leaned on leedave's Flipper Zero FAP boilerplate to learn a cleaner app structure on the Flipper side. Big thanks to the community. I really enjoyed building this one.