A 3D printed camera with an OLED display, saving to SD card and capacitive touch button controls.
This is a Robot Zero Plus tutorial. The full code and 3D models are only available for Plus members.
ButtonCam 3D Printed Model
I designed the camera in Tinkercad. The front and back look like this:
The 3D files need to flipped upside down in the slicer before printing:
The final 3D prints look like this:
In addition to the ESP32-CAM. The project requires a microSD card, an SSD1306 OLED, three TTP223 capacitive touch switches, 15 dupont cables, a voltage booster, a 18650 battery and holder.
The 18650 battery, holder and booster could be replaced with anything that can supply 5v to the ESP32-CAM.
This content is for Plus members only.
It should be easy to install all the components as shown in the video. If you use a different part or something doesn’t fit, you can snap off the clips and just glue or Blu Tack the part in place.
C++ Code on the ESP32
In the Arduino loop, frames are constantly requested from the camera. Each JPG frame is decoded and the pixels converted to grey scale while saving into an array. This array is then processed a second time to create to a dithered monochrome array that is output to the OLED screen.
While this camera data is being streamed to the OLED the ESP32 also listens for button presses from the three capacitive touch buttons. If the trigger button is pressed, the camera switches to a higher resolution, captures a frame and this is saved to the microSD card and also briefly shown on the OLED screen.
If the left or right buttons are pressed the ESP32 reads the files before or after the current image on the microSD card and again, shows this on the OLED.
Fully assembled the project looks and functions like this:
Dithering Video for Monochrome Displays
Video passed directly from a camera to a monochrome screen can be difficult to make out. It needs to be dithered using error diffusion to break up the solid black and white areas. The Arduino code processes the image using the Floyd-Steinburg dithering algorithm.
When the frame size is set to QQVGA2 it is easy to decode the top part of the 128×160 frame to give 128×64 pixels to display on the OLED screen. The problem is that only the top part of the camera frame is shown on the screen.
I wanted to use frames from the full sensor so I set the resolution to QQVGA (160 × 120) and resampled the camera frames to create an array with the same resolution as the screen. However I discovered later than the minimum resolution that the ov2640 sensor outputs at full frame is CIF (352 x 288 pixels). I need to investigate this further.
It’s easier to see how effective using dithering can be with monochrome screens in the video below which shows the same two resolutions as above but with a moving image.
Mark II of this project will have a power switch, the camera will be relocated and the code improved. The slide-show will probably be replaced with an image browser.
Code, 3D models, STL and Wiring Diagram
For full access to this tutorial including the code, 3D STL files and Tinkercad originals and the wiring diagram, please click here to subscribe to be a Plus member. More information about Plus membership can be found here.
Best guide to dithering I found – https://tannerhelland.com/2012/12/28/dithering-eleven-algorithms-source-code.html
Basic Floyd-Steinburg pseudocode – https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering