XIAO ESP32 S3 Handheld Camera- Pocket Edition

by Arnov Sharma in Circuits > Microcontrollers

2858 Views, 16 Favorites, 0 Comments

XIAO ESP32 S3 Handheld Camera- Pocket Edition

18 (33).gif
15 (42).gif
IMG_20230728_001806.jpg

Greetings, So here's something interesting, a DIY point-and-shoot Camera Made completely from scratch using the new XIAO ESP32 S4 Board with Sense Camera Module and custom PCB.

The major objective was to create a small, portable point-and-shoot camera that was capable of taking pictures and saving them to an SD card.

An onboard lithium cell has been added to make this device truly portable and wireless, and appropriate circuitry has also been added to control the cell's charge-discharge cycle.

Check out the photographs that were clicked from this device at the end of the article.

Let's get started with the build.

Supplies

Following are the materials used in this built-

  • XIAO ESP32 S3 Module
  • XIAO OV2640 camera Module
  • Custom PCB
  • IP5303
  • 1uF 0805 Package Capacitor
  • 1uH Inductor
  • 10K Resistor 1206 Package
  • Header pins for XIAO male and female both
  • USB THT Port
  • Li-ion Cell Socket 18650 SMD
  • Li-ion Cell 3.7V 2200mAh

ESP32 S3 With CAM Module

02 (44).gif

The Seeed Studio XIAO Series is tiny development board with a thumb-sized size and a comparable hardware design.

Here, "Small" is the half of the feature specified by the codename "XIAO," and "Puissant" is the other half. The digital microphone, camera sensor, and SD card support are all built into the Seeed Studio XIAO ESP32S3 Sense.

This development board can be a great tool to start with intelligent voice and vision AI because it combines embedded ML computer power with photographic capacity.

https://www.seeedstudio.com/XIAO-ESP32S3-Sense-p-5639.html

Check out the well-written wiki provided by Seeed Studio at the link below to learn more about how to use this device.

https://wiki.seeedstudio.com/xiao_esp32s3_getting_started/

PCB Design

XIAO CAM_page-0001.jpg
Capture.JPG

The PCB Design for this project is a straightforward setup based on two primary sections: the power module section, which includes an IP5303 PM IC that boosts 3.7V of Li-ion Cell to 5V for any USB Device to work, in this case an XIAO Module, and the XIAO Breakout board, which essentially keeps XIAO in its place.

When the button is pressed, the power module starts to function and powers the XIAO Board. The power module output is connected to the XIAO's 5V and GND.

After the schematic is finished, we build the PCB file. First, we create a 95mm x 25mm outline and position the XIAO on top. We next add the power management IC setup to the lower region, and the lithium battery holder is placed on the bottom side.

Seeed Fusion Service

01 (40).gif
IMG_20230727_220144.jpg

The final PCB was sent to SEEED Studio for samples.

An order was placed for a White solder mask with Black silkscreen, and the PCBs arrived in less than a week, which was super fast.

The quality was very good considering the price, which was also pretty low.

Seeed Fusion one-stop shop offers one-stop prototyping for PCB manufacture and PCB assembly, and as a result, they produce superior quality PCBs and Fast Turnkey PCBA within 7 working days.

Seeed Studio Fusion PCB Assembly Service takes care of the entire fabrication process, from PCB manufacturing and parts sourcing to assembly and testing services, so you can be sure they are getting a quality product.

After gauging market interest and verifying a working prototype, Seeed Propagate Service can help you bring the product to market with professional guidance and a strong network of connections.

Next, we prepare for the PCB assembly process.

PCB Assembly Process

03 (43).gif
04 (43).gif
05 (44).gif
06 (46).gif
10 (41).gif
11 (42).gif

This project's PCB assembly process consists of two major steps: first, we add SMD components, and then we place THT components.

  • We begin by applying solder paste to each component pad individually using a solder paste dispensing syringe.
  • Next, we pick and place all the components in their proper places using ESD tweezers.
  • Following the pick and place process, we place this board on a mini reflow hotplate, which heats the PCB from the bottom up to the solder paste melting temperature.
  • Then we put all of the THT components in their proper places, such as the header pins in the XIAO pads, the USB Port, and the switch.
  • Finally, using a standard soldering iron, we attach the Lithium Cell Holder to the bottom side of the board, completing the assembly of the board.

Setting Up ESP32 S3 Sense

07 (46).gif
08 (46).gif
09 (45).gif

To place the XIAO Module on the circuit, header pins must be added to the pads before using it with the Sensing Module.

  • We use a breadboard to keep the xiao and header pin in place permanently after adding two CON7 Male header pins along both sides of the XIAO.
  • The SD Card is next prepared by being plugged into a PC and formatted in FAT32. This step is essential since an SD Card won't function if it hasn't been formatted in FAT32.
  • After formatting, we attach the sense module to the XIAO Board using the male and female B2B Connectors before sliding the SD Card into the SD Card slot on the sense module.

You can check out this wiki guide about using XIAO and the Sense module by clicking the link below. Seeed Studio has created a well-documented page with an elaborate starting guide and sample sketches.

https://wiki.seeedstudio.com/xiao_esp32s3_getting_started/

Power Source

12 (43).gif
13 (42).gif

A 3.7V 18650 Li-ion cell with a capacity of 2200 mAh, or 8.14 Wh, is used as the power supply, and it is enough to power the typically low-powered XIAO ESP32 S3 with sense module.

After correctly orienting the Li-ion cell in its holder, we press the switch to turn on the Power management IC. The device goes OFF when the switch is double-tapped.

Power management IC output is measured with a multimeter and is found to be 5.1 volts, indicating that the setup is working and that we can move on to the next phase.

CODE

IMG_20230727_231446.jpg

Here's the code that is used in this project; it was taken from the example sketches available in XIAO ESP32 Sense wiki.

#include "esp_camera.h"
#include "FS.h"
#include "SD.h"
#include "SPI.h"

#define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM

#include "camera_pins.h"

unsigned long lastCaptureTime = 0; // Last shooting time
int imageCount = 1; // File Counter
bool camera_sign = false; // Check camera status
bool sd_sign = false; // Check sd status

// Save pictures to SD card
void photo_save(const char * fileName) {
// Take a photo
camera_fb_t *fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Failed to get camera frame buffer");
return;
}
// Save photo to file
writeFile(SD, fileName, fb->buf, fb->len);

// Release image buffer
esp_camera_fb_return(fb);

Serial.println("Photo saved to file");
}

// SD card write file
void writeFile(fs::FS &fs, const char * path, uint8_t * data, size_t len){
Serial.printf("Writing file: %s\n", path);

File file = fs.open(path, FILE_WRITE);
if(!file){
Serial.println("Failed to open file for writing");
return;
}
if(file.write(data, len) == len){
Serial.println("File written");
} else {
Serial.println("Write failed");
}
file.close();
}

void setup() {
Serial.begin(115200);
while(!Serial); // When the serial monitor is turned on, the program starts to execute

camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.frame_size = FRAMESIZE_UXGA;
config.pixel_format = PIXFORMAT_JPEG; // for streaming
config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
config.fb_location = CAMERA_FB_IN_PSRAM;
config.jpeg_quality = 12;
config.fb_count = 1;

// if PSRAM IC present, init with UXGA resolution and higher JPEG quality
// for larger pre-allocated frame buffer.
if(config.pixel_format == PIXFORMAT_JPEG){
if(psramFound()){
config.jpeg_quality = 10;
config.fb_count = 2;
config.grab_mode = CAMERA_GRAB_LATEST;
} else {
// Limit the frame size when PSRAM is not available
config.frame_size = FRAMESIZE_SVGA;
config.fb_location = CAMERA_FB_IN_DRAM;
}
} else {
// Best option for face detection/recognition
config.frame_size = FRAMESIZE_240X240;
#if CONFIG_IDF_TARGET_ESP32S3
config.fb_count = 2;
#endif
}

// camera init
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}

camera_sign = true; // Camera initialization check passes

// Initialize SD card
if(!SD.begin(21)){
Serial.println("Card Mount Failed");
return;
}
uint8_t cardType = SD.cardType();

// Determine if the type of SD card is available
if(cardType == CARD_NONE){
Serial.println("No SD card attached");
return;
}

Serial.print("SD Card Type: ");
if(cardType == CARD_MMC){
Serial.println("MMC");
} else if(cardType == CARD_SD){
Serial.println("SDSC");
} else if(cardType == CARD_SDHC){
Serial.println("SDHC");
} else {
Serial.println("UNKNOWN");
}

sd_sign = true; // sd initialization check passes

Serial.println("Photos will begin in one minute, please be ready.");
}

void loop() {
// Camera & SD available, start taking pictures
if(camera_sign && sd_sign){
// Get the current time
unsigned long now = millis();

//If it has been more than 1 minute since the last shot, take a picture and save it to the SD card
if ((now - lastCaptureTime) >= 10000) {
char filename[32];
sprintf(filename, "/image%d.jpg", imageCount);
photo_save(filename);
Serial.printf("Saved picture:%s\n", filename);
Serial.println("Photos will begin in one minute, please be ready.");
imageCount++;
lastCaptureTime = now;
}
}
}


The code file that is attached contains two additional header files that are required to compile this sketch. All you have to do is upload the sketch and put the header files in the same folder as the main code.

The below line, which is located in the void loop section, needs to be changed in order to increase the image click rate.

Change 10000 in order to increase or decrease the click rate.

    if ((now - lastCaptureTime) >= 10000) { 

One more thing: do enable the PSRAM option, which is set as disabled.


Final Assembly

14 (46).gif
15 (42).gif

This project is now complete after the code was uploaded to the XIAO Board and placed in its proper location on the circuit.

The power management configuration is turned ON and XIAO receives 5V when the main button is pressed.

It will take a picture and save it to the SD card once every 10,000 milliseconds

Result

17 (36).gif
18 (33).gif
image1.jpg
image2.jpg
image3.jpg
image4.jpg
image5.jpg
image6.jpg
image7.jpg
image8.jpg
image9.jpg

So here's the final result of this project: a working Handy Point-and-Shoot camera made completely from scratch.

By turning ON this setup, XIAO clicks an Image and waits for a minute, then retakes an image again and saves them all on the SD Card.

The image quality is not the best, but it's pretty great considering the price and how well it can be used in many potential projects.

Overall, this project was successful. The next step is to take this device on vacation somewhere, take pictures, and test this concept in the real world.

Special thanks to Seeed Studio for providing the XIAO Board and PCBs for this project, Check them out if you want to purchase any type of electronic module or development board from their website, they also have PCB and PCBA services.

Leave a comment if you need any help regarding this project.

Peace.