ESP32-CAM Take Photo and Save to MicroSD Card

Learn how to take photos with the ESP32-CAM board and save them to a microSD card using Arduino IDE. When you press the ESP32-CAM RESET button, it wakes up, takes a photo and saves it in the microSD card.

ESP32-CAM: Take Photo and Save to MicroSD Card

We’ll be using the ESP32-CAM board labelled as AI-Thinker module, but other modules should also work by making the correct pin assignment in the code.

The ESP32-CAM board is a $9 device (or less) that combines an ESP32-S chip, an OV2640 camera, a microSD card slot and several GPIO pins.

ESP32-CAM board is a $9 device with an OV2640 camera, microSD card slot and several GPIO pins

For an introduction to the ESP32-CAM, you can follow the next tutorials:

Watch the Video Tutorial

To learn how to take photos with the ESP32-CAM and save them in the microSD card, you can watch the following video tutorial or keep reading this page for the written instructions and all the resources.

Parts Required

To follow this tutorial you need the following components:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Project Overview

Here is a quick overview on how the project works.

take photo save to micro sd card ESP32-CAM
  • The ESP32-CAM is in deep sleep mode
  • Press the RESET button to wake up the board
  • The camera takes a photo
  • The photo is saved in the microSD card with the name: pictureX.jpg, where X corresponds to the picture number
  • The picture number will be saved in the ESP32 flash memory so that it is not erased during RESET and we can keep track of the number of photos taken.

Formatting MicroSD Card

The first thing we recommend doing is formatting your microSD card. You can use the Windows formatter tool or any other microSD formatter software.

1. Insert the microSD card in your computer. Go to My Computer and right click in the SD card. Select Format as shown in figure below.

Formatting your microSD card Windows

2. A new window pops up. Select FAT32, press Start to initialize the formatting process and follow the onscreen instructions.

Formatting your microSD card Windows

Note: according to the product specifications, the ESP32-CAM should only support 4 GB SD cards. However, we’ve tested with 16 GB SD card and it works well.

Installing the ESP32 add-on

We’ll program the ESP32 board using Arduino IDE. So you need the Arduino IDE installed as well as the ESP32 add-on. You can follow one of the next tutorials to install the ESP32 add-on, if you haven’t already:

Take and Save Photo Sketch

Copy the following code to your Arduino IDE.

/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-cam-take-photo-save-microsd-card
  
  IMPORTANT!!! 
   - Select Board "AI Thinker ESP32-CAM"
   - GPIO 0 must be connected to GND to upload a sketch
   - After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET button to put your board in flashing mode
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

#include "esp_camera.h"
#include "Arduino.h"
#include "FS.h"                // SD Card ESP32
#include "SD_MMC.h"            // SD Card ESP32
#include "soc/soc.h"           // Disable brownour problems
#include "soc/rtc_cntl_reg.h"  // Disable brownour problems
#include "driver/rtc_io.h"
#include <EEPROM.h>            // read and write from flash memory

// define the number of bytes you want to access
#define EEPROM_SIZE 1

// Pin definition for CAMERA_MODEL_AI_THINKER
#define PWDN_GPIO_NUM     32
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM      0
#define SIOD_GPIO_NUM     26
#define SIOC_GPIO_NUM     27

#define Y9_GPIO_NUM       35
#define Y8_GPIO_NUM       34
#define Y7_GPIO_NUM       39
#define Y6_GPIO_NUM       36
#define Y5_GPIO_NUM       21
#define Y4_GPIO_NUM       19
#define Y3_GPIO_NUM       18
#define Y2_GPIO_NUM        5
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     23
#define PCLK_GPIO_NUM     22

int pictureNumber = 0;

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
 
  Serial.begin(115200);
  //Serial.setDebugOutput(true);
  //Serial.println();
  
  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.pixel_format = PIXFORMAT_JPEG; 
  
  if(psramFound()){
    config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }
  
  // Init Camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }
  
  //Serial.println("Starting SD Card");
  if(!SD_MMC.begin()){
    Serial.println("SD Card Mount Failed");
    return;
  }
  
  uint8_t cardType = SD_MMC.cardType();
  if(cardType == CARD_NONE){
    Serial.println("No SD Card attached");
    return;
  }
    
  camera_fb_t * fb = NULL;
  
  // Take Picture with Camera
  fb = esp_camera_fb_get();  
  if(!fb) {
    Serial.println("Camera capture failed");
    return;
  }
  // initialize EEPROM with predefined size
  EEPROM.begin(EEPROM_SIZE);
  pictureNumber = EEPROM.read(0) + 1;

  // Path where new picture will be saved in SD Card
  String path = "/picture" + String(pictureNumber) +".jpg";

  fs::FS &fs = SD_MMC; 
  Serial.printf("Picture file name: %s\n", path.c_str());
  
  File file = fs.open(path.c_str(), FILE_WRITE);
  if(!file){
    Serial.println("Failed to open file in writing mode");
  } 
  else {
    file.write(fb->buf, fb->len); // payload (image), payload length
    Serial.printf("Saved file to path: %s\n", path.c_str());
    EEPROM.write(0, pictureNumber);
    EEPROM.commit();
  }
  file.close();
  esp_camera_fb_return(fb); 
  
  // Turns off the ESP32-CAM white on-board LED (flash) connected to GPIO 4
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);
  rtc_gpio_hold_en(GPIO_NUM_4);
  
  delay(2000);
  Serial.println("Going to sleep now");
  delay(2000);
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop() {
  
}

View raw code

The code starts by including the necessary libraries to use the camera. We also include the libraries needed to interact with the microSD card:

#include "esp_camera.h"
#include "Arduino.h"
#include "FS.h"                // SD Card ESP32
#include "SD_MMC.h"            // SD Card ESP32
#include "soc/soc.h"           // Disable brownour problems
#include "soc/rtc_cntl_reg.h"  // Disable brownour problems
#include "driver/rtc_io.h"
#include <EEPROM.h>            // read and write from flash memory

And the EEPROM library to save permanent data in the flash memory.

#include <EEPROM.h>

If you want to learn more about how to read and write data to the flash memory, you can follow the next tutorial:

Define the number of bytes you want to access in the flash memory. Here, we’ll only use one byte that allows us to generate up to 256 picture numbers.

#define EEPROM_SIZE 1

Then, define the pins for the AI-THINKER camera module.

// Pin definition for CAMERA_MODEL_AI_THINKER 
#define PWDN_GPIO_NUM     32
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM      0
#define SIOD_GPIO_NUM     26
#define SIOC_GPIO_NUM     27
  
#define Y9_GPIO_NUM       35
#define Y8_GPIO_NUM       34
#define Y7_GPIO_NUM       39
#define Y6_GPIO_NUM       36
#define Y5_GPIO_NUM       21
#define Y4_GPIO_NUM       19
#define Y3_GPIO_NUM       18
#define Y2_GPIO_NUM        5
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     23
#define PCLK_GPIO_NUM     22

Note: you might need to change the pin definition depending on the board you’re using. Wrong pin assignment will result in a failure to init the camera.

Initialize an int variable called pictureNumber that that will generate the photo name: picture1.jpg, picture2.jpg, and so on.

int pictureNumber = 0;

All our code is in the setup(). The code only runs once when the ESP32 wakes up (in this case when you press the on-board RESET button).

Define the camera settings:

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.pixel_format = PIXFORMAT_JPEG; 

Use the following settings for a camera with PSRAM (like the one we’re using in this tutorial).

if(psramFound()){
  config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
  config.jpeg_quality = 10;
  config.fb_count = 2;
}

If the board doesn’t have PSRAM, set the following:

else {
  config.frame_size = FRAMESIZE_SVGA;
  config.jpeg_quality = 12;
  config.fb_count = 1;
}

Initialize the camera:

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

Initialize the microSD card:

//Serial.println("Starting SD Card");
if(!SD_MMC.begin()){
  Serial.println("SD Card Mount Failed");
  return;
}
 
uint8_t cardType = SD_MMC.cardType();
if(cardType == CARD_NONE){
  Serial.println("No SD Card attached");
  return;
}

More information about how to use the microSD card can be found in the following project:

The following lines take a photo with the camera:

camera_fb_t * fb = NULL;

// Take Picture with Camera
fb = esp_camera_fb_get();  
if(!fb) {
  Serial.println("Camera capture failed");
  return;
}

After that, initialize the EEPROM with the size defined earlier:

EEPROM.begin(EEPROM_SIZE);

The picture number is generated by adding 1 to the current number saved in the flash memory.

pictureNumber = EEPROM.read(0) + 1;

To save the photo in the microSD card, create a path to your file. We’ll save the photo in the main directory of the microSD card and the file name is going to be (picture1.jpg, picture2.jpg, picture3.jpg, etc…).

String path = "/picture" + String(pictureNumber) +".jpg";

These next lines save the photo in the microSD card:

fs::FS &fs = SD_MMC; 
Serial.printf("Picture file name: %s\n", path.c_str());

File file = fs.open(path.c_str(), FILE_WRITE);
if(!file){
  Serial.println("Failed to open file in writing mode");
} 
else {
  file.write(fb->buf, fb->len); // payload (image), payload length
  Serial.printf("Saved file to path: %s\n", path.c_str());
  EEPROM.write(0, pictureNumber);
  EEPROM.commit();
}
file.close();

After saving a photo, we save the current picture number in the flash memory to keep track of the number of photos taken.

EEPROM.write(0, pictureNumber);
EEPROM.commit();

When the ESP32-CAM takes a photo, it flashes the on-board LED. After taking the photo, the LED remains on, so we send instructions to turn it off. The LED is connected to GPIO 4.

pinMode(4, OUTPUT);
digitalWrite(4, LOW);
rtc_gpio_hold_en(GPIO_NUM_4);

Finally, we put the ESP32 in deep sleep.

esp_deep_sleep_start();

Because we don’t pass any argument to the deep sleep function, the ESP32 board will be sleeping indefinitely until RESET.

ESP32-CAM Upload Code

To upload code to the ESP32-CAM board, connect it to your computer using an FTDI programmer. Follow the next schematic diagram:

Many FTDI programmers have a jumper that allows you to select 3.3V or 5V. Make sure the jumper is in the right place to select 5V.

Important: GPIO 0 needs to be connected to GND so that you’re able to upload code.

ESP32-CAMFTDI Programmer
GNDGND
5VVCC (5V)
U0RTX
U0TRX
GPIO 0GND

To upload the code, follow the next steps:

1) Go to Tools > Board and select AI-Thinker ESP32-CAM.

2) Go to Tools > Port and select the COM port the ESP32 is connected to.

3) Then, click the upload button to upload the code.

4) When you start to see these dots on the debugging window as shown below, press the ESP32-CAM on-board RST button.

After a few seconds, the code should be successfully uploaded to your board.

Demonstration

After uploading the code, remove the jumper that connects GPIO 0 from GND.

Open the Serial Monitor at a baud rate of 115200. Press the ESP32-CAM reset button. It should initialize and take a photo. When it takes a photo it turns on the flash (GPIO 4).

ESP32-CAM Take Photo and Save to MicroSD Card Demonstration

Check the Arduino IDE Serial Monitor window to see if everything is working as expected. As you can see, the picture was successfully saved in the microSD card.

ESP32-CAM Take Photo and Save to MicroSD Card Arduino IDE Serial Monitor Demonstration

Note: if you’re having issues with the ESP32-CAM, take a look at our troubleshooting guide and see if it helps: ESP32-CAM Troubleshooting Guide: Most Common Problems Fixed

After making sure that everything is working as expected, you can disconnect the ESP32-CAM from the FTDI programmer and power it using an independent power supply.

ESP32-CAM powered with powerbank / independent power supply

To see the photos taken, remove the microSD card from the microSD card slot and insert it into your computer. You should have all the photos saved.

ESP32-CAM photo pictures examples saved in MicroSD Card

The quality of your photo depends on your lighting conditions. Too much light can ruin your photos and dark environments will result in many black pixels.

Troubleshooting

If you’re getting any of the following errors, read our ESP32-CAM Troubleshooting Guide: Most Common Problems Fixed

  • Failed to connect to ESP32: Timed out waiting for packet header
  • Camera init failed with error 0x20001 or similar
  • Brownout detector or Guru meditation error
  • Sketch too big error – Wrong partition scheme selected
  • Board at COMX is not available – COM Port Not Selected
  • Psram error: GPIO isr service is not installed
  • Weak Wi-Fi Signal
  • No IP Address in Arduino IDE Serial Monitor
  • Can’t open web server
  • The image lags/shows lots of latency

Wrapping Up

We hope you’ve found this tutorial useful and you are able to use it in your projects. If you don’t have an ESP32-CAM board, you can click here to get one.

As mentioned previously, we have other tutorials about the ESP32-CAM that you may like:

Learn more about the ESP32 with our “Learn ESP32 with Arduino IDE” course or check our ESP32 free resources.

Thank you for reading.


Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »

Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »


Enjoyed this project? Stay updated by subscribing our weekly newsletter!

107 thoughts on “ESP32-CAM Take Photo and Save to MicroSD Card”

    • Hi dear;

      I would like access saved sd card photo by web browser.
      for example.
      I will connect button on board , press button take a photo save to sd card capture1.jpg, press again save second photo capture2.jpg. (only 2 photos record)

      will access http://ip address/capture1.jpg and http://ip address/capture2.jpg.

      how can I do it?

      thanks for your kind support.

      Reply
  1. Good! Congratulations!!
    I’m findig how to make this but instead using reset to take photo, program a time lapse photo, from 5 to 60 sec, storaging them in SDcard.
    Can you think about it?
    Thanks!

    Reply
    • Hi Frank.
      That’s a very interesting project.
      I think you just need to create a timer that triggers a function that takes the photo and saves to the microSD card. And put everything in the loop.
      I’ll think about your project, and maybe create a tutorial in the future.
      REgards,
      Sara

      Reply
  2. Rui,i m so sorry ,i m radio man no digital 🙂 when i try to compile this sketch ,arduino 1.8.5 tell me :
    Board esp32wrover (platform esp32, package esp32) is unknown

    Error compiling for board ESP32 Wrover Module.

    Reply
    • Hi Mikele.
      I’m sorry for the delay in my response.
      Were you able to fix this issue?
      What other information do you get in the serial monitor?
      Regards,
      Sara

      Reply
  3. Hello Rui,
    I’m a great fan of your blog, and bought several of your books and courses.
    I found this post if this can help for shutting down the LED :
    https://www.esp32.com/viewtopic.php?t=4040

    Also I would like to build a system that takes a picture of animal passing by a path. I was thinking to add an IR motion sensor or an external command by a light barrier to the SD card recording system you described.
    Could you please make a post of such a system ?
    Thanks in advance,
    Claude

    Reply
    • Thank you for sharing that solution.
      At the moment, we weren’t able to interface the PIR sensor with the EPS32-CAM. But we’ll try again and create a new tutorial about that if we succeed.
      Regards,
      Sara

      Reply
  4. LED pin output needs to be set LOW then HOLD to keep it off during sleep. Disable HOLD after wakeup to use the pin again.

    pinMode(4, OUTPUT);
    digitalWrite(4, LOW);
    rtc_gpio_hold_en(GPIO_NUM_4);
    delay(500);
    esp_deep_sleep_start();

    Reply
  5. rtc & digital io pin state can be maintained during hibernation with these two functions:
    rtc_gpio_hold_en
    rtc_cntl_dg_pad_force_hold

    More info:
    esp32.com/viewtopic.php?t=1966

    Reply
    • Thanks for sharing.
      I’ve included the following:
      #include “driver/rtc_io.h”

      Then, used:
      rtc_gpio_hold_en(GPIO_NUM_4);

      To keep GPIO LOW during deep sleep as you suggested in your previous comment.

      It worked! So, I updated the code!

      Thank you 😀

      Reply
  6. Very nice! Could the sketch be modified to be triggered by connecting one of the gpio pins to ground instead of pressing the reset button? This would make it useful in an application in which a remote switch is used to trigger.

    Reply
  7. I am struggling getting a PIR sensor to wake the esp32 from deep sleep. Is it possible the camera configuration is interfering with it?

    Reply
    • Thank you for your comment.
      We’ve tried interfacing the camera with the PIR motion sensor. But when using the SD card, there are almost no pins left to connect the PIR motion sensor. The pins left didn’t work with the sensor: the ESP-CAM crashed.
      So, we weren’t successful yet to interface a PIR. But will try again.
      Regards,
      Sara

      Reply
  8. Instead of pressing the reset button’ I owuld like to activate the camera by a movement sensor for example in order to watch the house…
    Thanks for an interesting project.

    Reply
  9. Good afternoon. Excellent example. But the author did not adjust the matrix OV2640. I added this code:

    // Set camera sensor
    sensor_t * s = esp_camera_sensor_get();

    s->set_framesize(s, MY_FRAMESIZE);
    s->set_quality(s, MY_QUALITY);
    s->set_contrast(s, 0);
    s->set_brightness(s, 0);
    s->set_saturation(s, 0);
    s->set_gainceiling(s, GAINCEILING_16X);
    s->set_colorbar(s, 0);
    s->set_whitebal(s, 0);
    s->set_hmirror(s, 0);
    s->set_vflip(s, 0);
    s->set_ae_level(s, 0);
    s->set_special_effect(s, 0);
    s->set_wb_mode(s, 2);
    s->set_awb_gain(s, 1);
    s->set_bpc(s, 1);
    s->set_wpc(s, 1);
    s->set_raw_gma(s, 1);
    s->set_lenc(s, 0);
    s->set_agc_gain(s, 1);
    s->set_aec_value(s, 600);
    s->set_gain_ctrl(s, 0);
    s->set_exposure_ctrl(s, 0);
    s->set_aec2(s, 1);
    s->set_dcw(s, 0);

    Reply
  10. Thanks for this great tutorial.
    Could you explain how to connect external spi device (ex: tft ST7735)
    I have tryied multiple pin conbinaison without success.

    Reply
    • Hi.
      You need to check what pins are being used by the camera. You can’t use those.
      Then, if you’re using the microSD card, you can’t also use those pins. So, there are little pins left to connect an external SPI device.
      Take a look at the pins used by the board and see if you have some left that can be used with your peripherals. Here are the pins (page 3): loboris.eu/ESP32/ESP32-CAM%20Product%20Specification.pdf
      Regards,
      Sara

      Reply
    • Please let me know if you figure out what pins to use that dont cause a crash. I am having trouble getting the SD card to mount after deep sleep.

      Reply
      • Hi. You need to add

        rtc_gpio_hold_dis(GPIO_NUM_4);

        before initializing the microSD card, to “unhold” the state of GPIO 4.

        Regards,
        Sara

        Reply
  11. Hello, very cool the design of the camera. Thank you for sharing another project and increasing our field of knowledge.

    Reply
  12. In regards to waking after deep sleep and the SD card not mounting:

    The code you have posted forces GPIO4 to hold its value in this line:

    rtc_gpio_hold_en(GPIO_NUM_4);

    This pin is used for SD card interface. You need to un-hold it after deep sleep wakeup if you want to use the pin again.

    Reply
    • I used gpio 13 pin D3 to make the PIR sensor work. I also removed the light hold.. I would like the light to be off during deep sleep. When I figure it out I will post some pictures of what I rigged up if people want. Thanks again.

      Reply
      • Hi David.
        Yes, please share your results with us.
        Were you able to use GPIO 13 as an interrupt without the ESP crashing?
        Regards,
        Sara

        Reply
        • bit.ly/2IZ7Kjz
          here is a schematic of what I did. I am new to schematics so I hope everything is right. Anyway, the board pin is pulled low instead of floating by this circuit. Although I’ve been told this is not a good pin to use because it is HIGH on boot. However it seems to work OK for me.

          then ofcourse I use this code before deep sleep:
          esp_sleep_enable_ext0_wakeup(GPIO_NUM_13,1);

          cheers,
          David

          Reply
        • bit.ly/2IZ7Kjz
          here is a schematic of what I did. I am new to schematics so I hope everything is right. Anyway, the board pin is pulled low instead of floating by this circuit. Although I’ve been told this is not a good pin to use because it is HIGH on boot. However it seems to work OK for me.

          then of course I use this code before deep sleep:
          esp_sleep_enable_ext0_wakeup(GPIO_NUM_13,1);

          cheers,
          David

          Reply
          • looking at it now I am not sure what the 10k resistor does. I have tested it multiple times and it is definitely how i have it wired up though…

          • Hi David.
            Thank you so much for sharing.
            I would like to give it a try and maybe create a tutorial about that.
            Can you share the code that you are running on the ESP32-CAM? You can use pastebin for example to share your code.
            Would you mind if we used that information to create a new tutorial?
            Regards,
            Sara

          • yes ofcourse make a tutorial if you want. Honestly though I was unable to get the PIR sensor to work well in sunlight but that may not be a problem for your project.

            Unfortunately I do not have the exact code on hand right now, but it is simply your code without the LED hold and with:
            esp_sleep_enable_ext0_wakeup(GPIO_NUM_13,1);

            I will make double sure that is right when I get home tomorrow morning. I was thinking of testing it again with a simple push button on the same pin just to be sure.

            Thanks,
            David

  13. Hello,
    I’ve succeed to compile successfuly the sketch in IDE following your instructions but I’m confused about loading in ESP32.
    How to power the ESP32 module please, because with the FTDI connected alone to USB, back pin 3.3V is around 4V and 5.0V is around 6V , Is the FTDI defective ?
    Or should the ESP32 powered with a separate power supply ?
    thanks for claryfying this point,
    Rgds,

    Reply
    • Hi.
      In our example, we’re powering the ESP32 using the 3.3V from the FTDI programmer connected to the 3.3V of the ESP32-CAM and it works well.
      Some people reported that the ESP32-CAM only worked well when powering with 5V through the 5V pin.
      You can also use a separated power supply up to 5V.
      Regards,
      Sara

      Reply
  14. Hi.. can you helpme? SD 2G . Fat32 formated. like tutorial. the board works ok with the proyect (ESP32-CAM Video Streaming and Face Recognition)

    18:57:51.475 -> Picture file name: /picture1.jpg
    18:57:51.475 -> E (2403) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0xffffffff
    18:57:51.475 -> E (2404) diskio_sdmmc: sdmmc_read_blocks failed (-1)
    18:57:52.500 -> E (3409) sdmmc_req: sdmmc_host_wait_for_event returned 0x107
    18:57:52.500 -> E (3409) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x107
    18:57:52.500 -> E (3410) diskio_sdmmc: sdmmc_read_blocks failed (263)

    Thanks.

    Reply
    • Hi Wido.
      That will be one of our next projects.
      But at the moment, we don’t have anything about that subject.
      Regards,
      Sara

      Reply
  15. The article says an a.i. thinker module is being used….but top of code say “Wrover”. Please explain?
    Thanks, Curt Wells

    Reply
    • Hi.
      In our first ESP32-CAM projects, the AI-thinker module wasn’t defined in the Boards menu at the time.
      Now, you should be able to find the AI-Thinker module on the Boards menu.
      However, you can select either board and it should work.
      Regards,
      Sara

      Reply
  16. I tried to make the ESP32-CAM to wake up after some time (1 minute), I upload the sketch and put it to work.
    The first picture is taken by the ESP32-CAM, then it goes to sleep. When it wakes up, the ESP32-CAM tries to access the MicroSD Card and returns the message:

    E (7143) sdmmc_sd: sdmmc_check_scr: send_scr returned 0xffffffff
    SD Card Mount Failed

    But if I press Reset, it works normally (the picture is taken).

    Reply
    • Hi Eduardo.
      Try to add the following at the beginning of the setup():
      pinMode(4, INPUT);
      digitalWrite(4, LOW);
      rtc_gpio_hold_dis(GPIO_NUM_4);
      Then, tell me if it solved your issue.
      Regards,
      Sara

      Reply
  17. In order to upload a photo to a server, how can a post request be added to one of the esp32-cam projects ?
    I know how to add a received file manager to the server, but all the examples I find with a google search use a client form to upload – which requires a human to select a file on the client.

    Reply
  18. I have the same doubt from Curt Wells. The solution which I figured myself was to save the picture taken by the camera in the SPIFFS and show the picture in the web server. I’m using Ngrok to publish my web server on the internet and so far it’s working.

    Reply
  19. I really sorry for doing that, but right now this is the only thing I can do…
    But by sunday or monday I can write some more neater and post on my github.

    I think that it won’t be difficult to get some help with the other guys in this weekend.

    Again, sorry for the mess. But I assure that it works (its working right now)

    Reply
      • Hi Curt! As I promissed, I made something much more neater and uploaded to a repo in my github. You can download, comment, ask change the code, or whaterever in it. Fell free to make you questions there, I will answer then.

        https://github.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT

        For Rui and Sara: PLEASE, ERASE THE OTHER POST WHICH I PUT A VERY LONG CODE. THAT CODE IS A REAL MESS.
        ALSO, YOU CAN USE THE CODE I UPLOADED TO GITHUB FOR WHATEVER YOU WANT. AS YOU GUYS CAN SEE, MANY YTHINGS ARE DERIVED FROM THE CODE SHOWN IN RUI’S BOIOK ‘LEARN ESP32 IN ARDUINO IDE’.

        Reply
        • Hi Eduardo.
          Thank you so much for sharing.
          We’ll take a look at your code and probably build a project about that.
          Regards,
          Sara

          Reply
    • try first putting the header (dl_lib.h) in brackets: #include “dl_lib.h” > #include . If that doesn’t work, try commenting the line: //#include “dl_lib.h”. For some people the first solution worked, for me, the second, without visible bad effects, the program work normally. I don’t know what function prototypes are in that header, since I don’t have it.

      Reply
  20. fail to compile with arduino 1.8.9 here is the error message I get:
    Arduino: 1.8.9 (Linux), Board: “ESP32 Wrover Module, Huge APP (3MB No OTA), QIO, 80MHz, 921600, None”

    Build options changed, rebuilding all
    /home/david/Arduino/espcam/espcam.ino: In function ‘void setup()’:
    espcam:130:28: error: ‘rtc_gpio_hold_en’ was not declared in this scope
    rtc_gpio_hold_en(GPIO_NUM_4);
    ^
    exit status 1
    ‘rtc_gpio_hold_en’ was not declared in this scope

    This report would have more information with
    “Show verbose output during compilation”
    option enabled in File -> Preferences.
    Arduino: 1.8.9 (Linux), Board: “ESP32 Wrover Module, Huge APP (3MB No OTA), QIO, 80MHz, 921600, Non
    I cannot find the problem. Can you help Thank you for any help David Nelson

    Reply
  21. Good afternoon, dear Sarah. Could you please tell me two main points to operate ESP32-CAM. I’m interested in how to lower the flash power or turn it off? It is not the best, but the energy demands and the problem I have is that the flash does not go off at all sometimes! Also you can show me how from *FB the picture to break into arrays on 10 bytes in order that I could send them on UART? Please help as soon as possible.

    Reply
    • Hi Dimka.
      To turn off the flash:
      include the following library:

      #include “driver/rtc_io.h”

      Then, add this in your setup():

      pinMode(4, INPUT);
      digitalWrite(4, LOW);
      rtc_gpio_hold_dis(GPIO_NUM_4);

      before going to sleep use to keep the LED off:

      pinMode(4, OUTPUT);
      digitalWrite(4, LOW);
      rtc_gpio_hold_en(GPIO_NUM_4);

      I hope this helps.
      At the moment I don’t have any example to break the picture into arrays.
      Regads,
      Sara

      Reply
  22. I know I can disable the library:
    #include “driver/rtc_io.h”
    And the led will not work.
    Another question is did photos 200 pictures become black with ripples, what to do?

    Reply
  23. Hi thanks a lot for spending time to complete this project and sharing it. I’m having an esp32 module an ov7670 module and an SD CARD MODULE. Can I connect all these three as per code and use your code. Or is this code only for esp32cam module?

    Reply
    • Hi.
      I believe that if you make the same connections between the camera and the sd card as they are in the ESP32-CAM, the code should work, but I haven’t tried it.
      Regards,
      Sara

      Reply
  24. Hi, I have a problem compiling the sketch which is the following: C: \ Users \ Joelon \ Documents \ Arduino \ libraries \ esp32cam-master \ src / dl_lib.h: In function ‘char * dstrdup (str_t)’:

    C: \ Users \ Joelon \ Documents \ Arduino \ libraries \ esp32cam-master \ src / dl_lib.h: 232: 11: error: expected unqualified-id before ‘new’

         str_t new = dalloc (len);

               ^

    C: \ Users \ Joelon \ Documents \ Arduino \ libraries \ esp32cam-master \ src / dl_lib.h: 233: 29: error: expected type-specifier before ‘,’ token

         return (str_t) memcpy (new, s, len);

    Could you help me with this library or with this problem

    Thanks in advance 🙂

    Reply
    • Hi Joel.
      Some readers suggested the following to solve that issue:
      “For dl_lib.h: No such file or directory is because ESP32 Board Version 1.03 does’nt seem to include this anymore. Downgrade your ESP32 Board Version down to 1.02 in Andruino IDE or comment that line using version 1.03”.
      I hope this helps.
      Regards,
      Sara

      Reply
      • This issue happened here a while ago, but I solved in a much faster way than downgrading the “ESP32 boards” library.

        I don’t know why but (at least in my Arduino IDE) the ESP32 boards list appears twice in the Tools>Board menu.

        When I chose the “AI Thinker ESP32-CAM” in the first menu, I got this error.
        Then, I chose this board in the second menu and, like magic, everything worked like a charm.

        Don’t ask me why, but it worked…

        Reply
  25. Hello, I would like to know if it is possible that after taking the photo do not send the esp32 to sleep, but the possibility of taking more photos without the need to restart the esp32

    Reply
    • Yes Joel, its possible!
      I already asked something like that and got anwered here.

      I encapsulated the lines which takes a picture in a function (see it below):

      void take_picture(){
      digitalWrite(4, HIGH); //Turn on the flash
      camera_fb_t * fb = NULL; // FB pointer

      if(!fb) {
      Serial.println(“Camera capture failed”);
      return;
      }
      // initialize EEPROM with predefined size
      EEPROM.begin(EEPROM_SIZE);
      pictureNumber = EEPROM.read(0) + 1;

      // Path where new picture will be saved in SD Card
      String path = “/foto_” + String(pictureNumber) +”.jpg”;

      fs::FS &fs = SD_MMC;
      Serial.printf(“Picture file name: %s\n”, path.c_str());

      File file = fs.open(path.c_str(), FILE_WRITE);
      if(!file){
      Serial.println(“Failed to open file in writing mode”);
      }
      else {
      file.write(fb->buf, fb->len); // payload (image), payload length
      Serial.printf(“Saved file to path: %s\n”, path.c_str());
      EEPROM.write(0, pictureNumber);
      EEPROM.commit();
      }
      file.close();
      esp_camera_fb_return(fb);

      // Turns off the flash
      pinMode(4, OUTPUT);
      digitalWrite(4, LOW);
      }

      Then, in the loop() fucntion, I asked it to call the take_picture() function every 60 seconds.

      void loop() {
      take_picture();

      // Wait 1 min
      delay(60000);
      }

      Reply
        • Hi Joel,
          You just need to copy the sketch presented in this tutorail here and delete the repeated lines which I encapsulated in the function.

          Also, in the setup() function, delete these lines below:

          “`
          rtc_gpio_hold_en(GPIO_NUM_4);
          delay(2000);
          Serial.println(“Going to sleep now”);
          delay(2000);
          esp_deep_sleep_start();
          Serial.println(“This will never be printed”);
          “`

          And nothing more! Rui and Sara did an excellent tutorial.
          Then you just need to upload the sketch and go ahead!

          Just let me know if you got any trouble.

          Reply
          • Hi Eduardo ;), when compiling the sketch it prints me on the serial port: “Camera capture failed” and does not save the photo in the sd, it is more I believe that it does not save it. I don’t know if you could help me with that ;).

          • Thank you friend, the esp32 cam already works and take the photos and save them :), I send you a hug and take care

          • You’re welcome!
            I’m glad that now it works.

            Any new ideias about how to extend this, feel free to ask or sugest. Just access the repo in the link that I sent before, and then open a new topic in the “issues tab” (the tab beside the selected tab, ” Code”);

            You don’t have to worry about it. New ideas are always welcome!

            Hugs for you too and take care!

    • Hi Joel,
      To access the pictures of the SDcard in a webpage, probably is the same way that you access in a web page a picture saved in the SPIFFS of the ESP32.

      I already made a web page which takes a picture every minute and saves it in the SPIFFS of the ESP32-CAM and shows it on the web page.
      When I buit it, I didn’t figured any solution to work with many names and, so, when the ESP32-CAM took a picture, it overwritten the last one and showed in the web page only the newest one.

      You can check this project here: https://github.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT

      Reply
      • I already reviewed your Eduardo project, but I don’t know if you know if there is any way to read the file in binary and send it to the server on request http and decode it and save it on the server.
        Or some other way to do the same, I would appreciate any suggestions 🙂

        Reply
        • Hi Joel,
          about reading the pictures in binary and sending/receiving it in http requests is a part beyond my knowledge… it is something in my wish list of next steps.
          If you know some place on web where teach this, I really will appreciate!
          Unfortunatelly this time I can’t help neither give any hints… but if you need anything else which I know or I which can find a solution more easily, don’t hesitate in asking me!

          Reply
      • Good afternoon.
        Very thank you for creating such a describe, am asking you suggest the what its feet on fare are free for organizations exchange data? “UnR” and “UOT” can not be used, since when the camera is working, so at 115200 speed technical information is sent to the port monitor, which makes the receiving side react to the data correctly. What two pins can I use to organize data transfer and how do I turn off the flash, since I do not need it, there is a sub-socket.

        Reply
  26. Good afternoon.
    Very thank you for creating such a describe, am asking you suggest the what its feet on fare are free for organizations exchange data? “UnR” and “UOT” can not be used, since when the camera is working, so at 115200 speed technical information is sent to the port monitor, which makes the receiving side react to the data correctly. What two pins can I use to organize data transfer and how do I turn off the flash, since I do not need it, there is a sub-socket.

    Reply
  27. Again, a Great tutorial! Code works fine…picture quality not the best, but, I bet soon they’ll come up with a camera with more megapixels.

    Reply
  28. Hi, I can’t include #include “esp_camera.h”, it tells me No such file or directory. What should I do? I’ve written to you several times. I use arduino 1.8.10 and can’t find it
    Huge App (3Mb no OTA), but no OTA (large APP) which one should I use? Thanks and congratulations for your wonderful and functional projects.

    Reply
  29. Bonjour,
    eh oui, un français ! (et en français)
    Tout d’abord MERCI pour vos très bons tutos !
    Petit problème sur la dl_lib.h … qui n’existe plus :
    https://forum.arduino.cc/index.php?topic=637231.0
    New ESP32 Arduino version (v 1.03) remove this file “dl_lib.h” (and some others). Depending the sketch, probabily you can just remove this line because in the examples I have been used this library is beeing included but no method or function from this files is used.

    Reply
  30. Thanks for the tutorial! I did have a little trouble uploading my code to the ESP32, but after checking everything including the connections, ports. Checked the voltage I checked it all! On the final check, I found it, sometime during all my checking, I crossed the TX & RX connections, I wouldn’t have found if not for that final check. Thanks for what you do!

    Reply

Leave a Reply to Mikele Cancel reply

Download our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.