I’ve always wanted to DIY a camera, but due to my limited skills, I couldn’t make full use of the powerful chips available. Later, I tried ESP32, but the image quality was not very satisfying, so the idea was shelved.
Then I saw Ai-Thinker’s newly released BW21, which supports cameras, 1080p video recording, SD card storage, and most importantly, Arduino programming. This made my camera project quickly feasible.
1. Hardware Preparation
Once the idea and a suitable platform were ready, I started building. Considering my limited hardware skills, I directly used the BW21-CBV-KIT development board as the core.
To implement the camera functions, external components were also required: power supply, screen, flash, timer, and buttons. Although the board has a built-in analog microphone, its performance was unsatisfactory, so I added a digital microphone as well.
Based on the BW21-CBV-KIT, I designed two expansion boards:
- One carries the screen, buttons, and BW21-CBV-KIT.
- The other integrates charging, RTC, flash, and the digital microphone.
Since I don’t know 3D design, I used LCSC EDA’s enclosure design function to quickly create a simple case for the large expansion board.
During initial testing, I encountered two issues:
- I accidentally chose SWD pins, causing I²C communication failure.
- The board holes didn’t align with the enclosure.
I had to redo it, but fortunately, the second version worked fine, and the board fit the case properly.
2. Software
The board already provides many Arduino examples, so I just needed to combine them logically.
The core examples used were:
- Camera_2_LCD → Display camera output on screen.
- SingleVideoWithAudio → Record MP4 video with audio to SD card.
- SDCARDsaveJPG → Save captured images to SD card.
- Time setting
- Screen brightness adjustment
- Flash toggle
- Photo browsing
- Bluetooth remote control
These represent the three core camera functions. I used RTOS in Arduino to build three tasks, each controlled by dedicated buttons to start or stop them.
Besides core functions, I also added basic settings and display features:I built a simple bare-metal UI menu controlled by buttons, allowing browsing, brightness adjustment, and Bluetooth toggling.
For Bluetooth remote control, instead of relying on smartphones (since phone cameras are better anyway), I used an AI-M61-32S development board as a dedicated BLE remote. The BW21-CBV acts as the host, scanning and connecting to the remote device. However, phones can also control it by sending a “Snapshot” command via BLE.
Since the board is enclosed, it’s inconvenient to remove the SD card directly. Inspired by the official examples, I implemented USB mass storage, allowing photos and videos to be read from the camera via USB. The feature is toggled by a button.
For power, I used an integrated charge/discharge chip. However, it doesn’t support shutdown during charging, meaning the camera stays on while charging. To handle this, I used ADC to monitor voltage: when above 4.2V, the system enters sleep mode to simulate shutdown.
3. Code
Below is the BW21 development board code (reference only, quite messy).
#include "StreamIO.h"
#include "VideoStream.h"
#include "AudioStream.h"
#include "AudioEncoder.h"
#include "MP4Recording.h"
#include "AmebaFatFS.h"
#include "AmebaST7789.h"
#include "TJpg_Decoder.h"
#include "USBMassStorage.h" // USB Storage
#include "sys_api.h" // System Calls
#include "BLEDevice.h"
#include "PowerMode.h"
// Wake up sources
// wake up by AON timer : 0
// wake up by AON GPIO : 1
// wake up by eRtc : 2
#define WAKEUP_SOURCE 1
#define RETENTION 0
// Set wake up AON GPIO pin : 21 / 22
#define WAKEUP_SETTING 21
...
Read more »
Ai-Thinker