{"id":125386,"date":"2023-03-09T14:59:26","date_gmt":"2023-03-09T14:59:26","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=125386"},"modified":"2024-06-16T15:03:29","modified_gmt":"2024-06-16T15:03:29","slug":"esp32-cam-photo-microsd-card-timestamp","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp32-cam-photo-microsd-card-timestamp\/","title":{"rendered":"ESP32-CAM Take Photo and Save to MicroSD Card with Date and Time (timestamp)"},"content":{"rendered":"\n<p>In this tutorial, you&#8217;ll learn to take a picture with the ESP32-CAM and save it to the microSD card.  We&#8217;ll include the current date and time on the filename. Including the date and time on the filename is useful because each picture will have a unique filename, which means no issues with overwriting existing files; you&#8217;ll know when each photo was taken; and it will be easier to organize or retrieve your files later on.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-CAM-Phot-MicroSD-Card-Data-Time.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM Take Photo and Save to MicroSD Card with Date and Time Timestamp\" class=\"wp-image-125444\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-CAM-Phot-MicroSD-Card-Data-Time.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-CAM-Phot-MicroSD-Card-Data-Time.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-CAM-Phot-MicroSD-Card-Data-Time.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-CAM-Phot-MicroSD-Card-Data-Time.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p class=\"rntbox rntclblue\"><strong>New to the ESP32-CAM? <\/strong>Check our eBook: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-projects-ebook\/\">Build ESP32-CAM Projects<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p>Before proceeding with this guide, check the following prerequisites.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>ESP32-CAM<\/strong><\/h3>\n\n\n\n<p>For this project, we&#8217;ll be using an ESP32-CAM AI-Thinker board.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/03\/ESP32-CAM-External-Antenna-connected.jpg?resize=1024%2C576&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM Board\" class=\"wp-image-94888\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/03\/ESP32-CAM-External-Antenna-connected.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/03\/ESP32-CAM-External-Antenna-connected.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/03\/ESP32-CAM-External-Antenna-connected.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/03\/ESP32-CAM-External-Antenna-connected.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n<p>If you&#8217;re not familiar with the ESP32-CAM, you can follow the next tutorials:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-video-streaming-face-recognition-arduino-ide\/\">ESP32-CAM Video Streaming and Face Recognition with Arduino IDE<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-ai-thinker-pinout\/\">ESP32-CAM AI-Thinker Pinout Guide: GPIOs Usage Explained<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/esp32-cam-ov2640-camera\/\" target=\"_blank\" rel=\"noopener\">ESP32-CAM with OV2640 Camera Review<\/a><\/li>\n<\/ul>\n\n\n\n<p>You can also use a different ESP32 Camera board, you just need to make sure it supports a microSD card and that you adjust the right pinout on the code. This is only compatible with OV2640 cameras.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Arduino IDE<\/h3>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/arduino-ide-2.jpg?quality=100&#038;strip=all&#038;ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"204\" height=\"204\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/arduino-ide-2.jpg?resize=204%2C204&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Arduino IDE 2 logo\" class=\"wp-image-159109\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/arduino-ide-2.jpg?w=204&amp;quality=100&amp;strip=all&amp;ssl=1 204w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/arduino-ide-2.jpg?resize=150%2C150&amp;quality=100&amp;strip=all&amp;ssl=1 150w\" sizes=\"(max-width: 204px) 100vw, 204px\" \/><\/a><\/figure><\/div>\n\n\n<p>We\u2019ll program the ESP32 board using Arduino IDE. So you need the Arduino IDE installed as well as the ESP32 add-on. You can follow the next tutorial to install the ESP32 add-on, if you haven\u2019t already:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/installing-esp32-arduino-ide-2-0\/\" title=\"\">Installing the ESP32 Board in Arduino IDE (Mac OS X and Linux instructions)<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">MicroSD Card<\/h3>\n\n\n\n<p>We&#8217;ll save the photos taken with the ESP32-CAM on the microSD card. <strong>Your microSD card must be formatted as FAT32<\/strong>.<\/p>\n\n\n\n<p>To get familiar with handling files with the microSD card and the ESP32, you can take a look at the following tutorial:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-microsd-card-arduino\/\" title=\"ESP32: Guide for MicroSD Card Module using Arduino IDE\">ESP32: Guide for MicroSD Card Module using Arduino IDE<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Getting Date and Time with the ESP32 (Accurate Timezone and Daylight Saving Time)<\/h3>\n\n\n\n<p>We&#8217;ll use the current date and time on the pictures&#8217; filenames. We have a detailed tutorial explaining how to set timezone and daylight saving time when getting time from an NTP server using the ESP32:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-ntp-timezones-daylight-saving\/\">ESP32 NTP Time \u2013 Setting Up Timezones and Daylight Saving Time<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Project Overview<\/h2>\n\n\n\n<p>The following diagram shows a high-level overview of the example we&#8217;ll build.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"412\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-CAM-Picture-Filename-Date-Time-Overview-01.png?resize=750%2C412&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM Take Photo and Save to MicroSD Card with Date and Time project overview\" class=\"wp-image-125451\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-CAM-Picture-Filename-Date-Time-Overview-01.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-CAM-Picture-Filename-Date-Time-Overview-01.png?resize=300%2C165&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>In this tutorial, we&#8217;ll show you a simple example that does the following:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>The ESP32-CAM connects to your router via Wi-Fi (this is needed so that we can get time from an NTP server);<\/li>\n\n\n\n<li>The ESP32 connects to an NTP server to initialize the date and time with the correct timezone;<\/li>\n\n\n\n<li>It initializes the camera and the microSD card;<\/li>\n\n\n\n<li>The camera takes a new picture;<\/li>\n\n\n\n<li>It gets the current date and time from the NTP server;<\/li>\n\n\n\n<li>The photo is saved to the microSD card \u2013 its filename contains the date and time<br>it was taken (it\u2019s a unique filename);<\/li>\n\n\n\n<li>Repeat steps 4 to 6 every 10 seconds. For demonstration purposes, the ESP32-CAM will do this task over and over again on the <span class=\"rnthl rntliteral\">loop()<\/span>. The idea is to apply the concepts you&#8217;ll learn with this example to your own projects.<\/li>\n<\/ol>\n\n\n\n<p>Using date and time on the picture filename has several advantages:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>all pictures will have a different filename\u2014you won&#8217;t have problems with overwriting previous files when the ESP32 resets;<\/li>\n\n\n\n<li>you&#8217;ll know when each picture was taken;<\/li>\n\n\n\n<li>it will be easier to organize your pictures later on.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Parts Required<\/h2>\n\n\n\n<p>To follow this tutorial you need an ESP32 camera module that supports a microSD card, the microSD card itself, and hardware to upload code to the board (it can be the ESP32-CAM MB programmer, or an FTDI programmer).<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/makeradvisor.com\/tools\/esp32-cam\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32-CAM with OV2640<\/a><\/strong>&nbsp;\u2013 read&nbsp;<a href=\"https:\/\/makeradvisor.com\/esp32-camera-cam-boards-review-comparison\/\" target=\"_blank\" rel=\"noreferrer noopener\">Best ESP32-CAM Dev Boards<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/microsd-card-raspberry-pi-16gb-class-10\/\" target=\"_blank\" rel=\"noreferrer noopener\">MicroSD card<\/a><\/li>\n\n\n\n<li>To upload code to the board:\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/upload-code-esp32-cam-mb-usb\/\">ESP32-CAM MB programmer<\/a><\/li>\n\n\n\n<li>Or <a href=\"https:\/\/makeradvisor.com\/tools\/ftdi-programmer-board\/\" target=\"_blank\" rel=\"noreferrer noopener\">FTDI programmer<\/a> and <a href=\"https:\/\/makeradvisor.com\/tools\/jumper-wires-kit-120-pieces\/\" target=\"_blank\" rel=\"noreferrer noopener\">female-to-female jumper wires<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n<p>You can use the preceding links or go directly to <a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\">MakerAdvisor.com\/tools<\/a> to find all the parts for your projects at the best price!<\/p><p style=\"text-align:center;\"><a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2017\/10\/header-200.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Code<\/h2>\n\n\n\n<p>Copy the following code to your Arduino IDE. Before uploading the code to your board, <strong>you need to insert your SSID and password, and timezone string<\/strong> to set the correct timezone for your location (<a href=\"#timezone-string\" title=\"\">more about setting the timezone string below<\/a>).<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*********\r\n  Rui Santos\r\n  Complete instructions at https:\/\/RandomNerdTutorials.com\/esp32-cam-photo-microsd-card-timestamp\r\n  \r\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.\r\n  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n*********\/\r\n\r\n#include &quot;esp_camera.h&quot;\r\n#include &quot;FS.h&quot;                \/\/ SD Card ESP32\r\n#include &quot;SD_MMC.h&quot;            \/\/ SD Card ESP32\r\n#include &quot;soc\/soc.h&quot;           \/\/ Disable brownout problems\r\n#include &quot;soc\/rtc_cntl_reg.h&quot;  \/\/ Disable brownout problems\r\n#include &quot;driver\/rtc_io.h&quot;\r\n#include &lt;WiFi.h&gt;\r\n#include &quot;time.h&quot;\r\n\r\n\/\/ REPLACE WITH YOUR NETWORK CREDENTIALS\r\nconst char* ssid = &quot;REPLACE_WITH_YOUR_SSID&quot;;\r\nconst char* password = &quot;REPLACE_WITH_YOUR_PASSWORD&quot;;\r\n\r\n\/\/ REPLACE WITH YOUR TIMEZONE STRING: https:\/\/github.com\/nayarsystems\/posix_tz_db\/blob\/master\/zones.csv\r\nString myTimezone =&quot;WET0WEST,M3.5.0\/1,M10.5.0&quot;;\r\n\r\n\/\/ Pin definition for CAMERA_MODEL_AI_THINKER\r\n\/\/ Change pin definition if you're using another ESP32 camera module\r\n#define PWDN_GPIO_NUM     32\r\n#define RESET_GPIO_NUM    -1\r\n#define XCLK_GPIO_NUM      0\r\n#define SIOD_GPIO_NUM     26\r\n#define SIOC_GPIO_NUM     27\r\n#define Y9_GPIO_NUM       35\r\n#define Y8_GPIO_NUM       34\r\n#define Y7_GPIO_NUM       39\r\n#define Y6_GPIO_NUM       36\r\n#define Y5_GPIO_NUM       21\r\n#define Y4_GPIO_NUM       19\r\n#define Y3_GPIO_NUM       18\r\n#define Y2_GPIO_NUM        5\r\n#define VSYNC_GPIO_NUM    25\r\n#define HREF_GPIO_NUM     23\r\n#define PCLK_GPIO_NUM     22\r\n\r\n\/\/ Stores the camera configuration parameters\r\ncamera_config_t config;\r\n\r\n\/\/ Initializes the camera\r\nvoid configInitCamera(){\r\n  config.ledc_channel = LEDC_CHANNEL_0;\r\n  config.ledc_timer = LEDC_TIMER_0;\r\n  config.pin_d0 = Y2_GPIO_NUM;\r\n  config.pin_d1 = Y3_GPIO_NUM;\r\n  config.pin_d2 = Y4_GPIO_NUM;\r\n  config.pin_d3 = Y5_GPIO_NUM;\r\n  config.pin_d4 = Y6_GPIO_NUM;\r\n  config.pin_d5 = Y7_GPIO_NUM;\r\n  config.pin_d6 = Y8_GPIO_NUM;\r\n  config.pin_d7 = Y9_GPIO_NUM;\r\n  config.pin_xclk = XCLK_GPIO_NUM;\r\n  config.pin_pclk = PCLK_GPIO_NUM;\r\n  config.pin_vsync = VSYNC_GPIO_NUM;\r\n  config.pin_href = HREF_GPIO_NUM;\r\n  config.pin_sccb_sda = SIOD_GPIO_NUM;\r\n  config.pin_sccb_scl = SIOC_GPIO_NUM;\r\n  config.pin_pwdn = PWDN_GPIO_NUM;\r\n  config.pin_reset = RESET_GPIO_NUM;\r\n  config.xclk_freq_hz = 20000000;\r\n  config.pixel_format = PIXFORMAT_JPEG; \/\/YUV422,GRAYSCALE,RGB565,JPEG\r\n  config.grab_mode = CAMERA_GRAB_LATEST;\r\n\r\n  \/\/ Select lower framesize if the camera doesn't support PSRAM\r\n  if(psramFound()){\r\n    config.frame_size = FRAMESIZE_UXGA; \/\/ FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA\r\n    config.jpeg_quality = 10; \/\/0-63 lower number means higher quality\r\n    config.fb_count = 1;\r\n  } else {\r\n    config.frame_size = FRAMESIZE_SVGA;\r\n    config.jpeg_quality = 12;\r\n    config.fb_count = 1;\r\n  }\r\n  \r\n  \/\/ Initialize the Camera\r\n  esp_err_t err = esp_camera_init(&amp;config);\r\n  if (err != ESP_OK) {\r\n    Serial.printf(&quot;Camera init failed with error 0x%x&quot;, err);\r\n    return;\r\n  }\r\n}\r\n\r\n\/\/ Connect to wifi\r\nvoid  initWiFi(){\r\n  WiFi.begin(ssid, password);\r\n  Serial.println(&quot;Connecting Wifi&quot;);\r\n  while (WiFi.status() != WL_CONNECTED) {\r\n    Serial.print(&quot;.&quot;);\r\n    delay(500);\r\n  }\r\n}\r\n\r\n\/\/ Function to set timezone\r\nvoid setTimezone(String timezone){\r\n  Serial.printf(&quot;  Setting Timezone to %s\\n&quot;,timezone.c_str());\r\n  setenv(&quot;TZ&quot;,timezone.c_str(),1);  \/\/  Now adjust the TZ.  Clock settings are adjusted to show the new local time\r\n  tzset();\r\n}\r\n\r\n\/\/ Connect to NTP server and adjust timezone\r\nvoid initTime(String timezone){\r\n  struct tm timeinfo;\r\n  Serial.println(&quot;Setting up time&quot;);\r\n  configTime(0, 0, &quot;pool.ntp.org&quot;);    \/\/ First connect to NTP server, with 0 TZ offset\r\n  if(!getLocalTime(&amp;timeinfo)){\r\n    Serial.println(&quot; Failed to obtain time&quot;);\r\n    return;\r\n  }\r\n  Serial.println(&quot;Got the time from NTP&quot;);\r\n  \/\/ Now we can set the real timezone\r\n  setTimezone(timezone);\r\n}\r\n\r\n\/\/ Get the picture filename based on the current ime\r\nString getPictureFilename(){\r\n  struct tm timeinfo;\r\n  if(!getLocalTime(&amp;timeinfo)){\r\n    Serial.println(&quot;Failed to obtain time&quot;);\r\n    return &quot;&quot;;\r\n  }\r\n  char timeString[20];\r\n  strftime(timeString, sizeof(timeString), &quot;%Y-%m-%d_%H-%M-%S&quot;, &amp;timeinfo);\r\n  Serial.println(timeString);\r\n  String filename = &quot;\/picture_&quot; + String(timeString) +&quot;.jpg&quot;;\r\n  return filename; \r\n}\r\n\r\n\/\/ Initialize the micro SD card\r\nvoid initMicroSDCard(){\r\n  \/\/ Start Micro SD card\r\n  Serial.println(&quot;Starting SD Card&quot;);\r\n  if(!SD_MMC.begin()){\r\n    Serial.println(&quot;SD Card Mount Failed&quot;);\r\n    return;\r\n  }\r\n  uint8_t cardType = SD_MMC.cardType();\r\n  if(cardType == CARD_NONE){\r\n    Serial.println(&quot;No SD Card attached&quot;);\r\n    return;\r\n  }\r\n}\r\n\r\n\/\/ Take photo and save to microSD card\r\nvoid takeSavePhoto(){\r\n  \/\/ Take Picture with Camera\r\n  camera_fb_t * fb = esp_camera_fb_get();\r\n \r\n  \/\/Uncomment the following lines if you're getting old pictures\r\n  \/\/esp_camera_fb_return(fb); \/\/ dispose the buffered image\r\n  \/\/fb = NULL; \/\/ reset to capture errors\r\n  \/\/fb = esp_camera_fb_get();\r\n  \r\n  if(!fb) {\r\n    Serial.println(&quot;Camera capture failed&quot;);\r\n    delay(1000);\r\n    ESP.restart();\r\n  }\r\n\r\n  \/\/ Path where new picture will be saved in SD Card\r\n  String path = getPictureFilename();\r\n  Serial.printf(&quot;Picture file name: %s\\n&quot;, path.c_str());\r\n  \r\n  \/\/ Save picture to microSD card\r\n  fs::FS &amp;fs = SD_MMC; \r\n  File file = fs.open(path.c_str(),FILE_WRITE);\r\n  if(!file){\r\n    Serial.printf(&quot;Failed to open file in writing mode&quot;);\r\n  } \r\n  else {\r\n    file.write(fb-&gt;buf, fb-&gt;len); \/\/ payload (image), payload length\r\n    Serial.printf(&quot;Saved: %s\\n&quot;, path.c_str());\r\n  }\r\n  file.close();\r\n  esp_camera_fb_return(fb); \r\n}\r\n\r\nvoid setup() {\r\n  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); \/\/ disable brownout detector\r\n\r\n  Serial.begin(115200);\r\n  delay(2000);\r\n\r\n  \/\/ Initialize Wi-Fi\r\n  initWiFi();\r\n  \/\/ Initialize time with timezone\r\n  initTime(myTimezone);    \r\n  \/\/ Initialize the camera  \r\n  Serial.print(&quot;Initializing the camera module...&quot;);\r\n  configInitCamera();\r\n  Serial.println(&quot;Ok!&quot;);\r\n  \/\/ Initialize MicroSD\r\n  Serial.print(&quot;Initializing the MicroSD card module... &quot;);\r\n  initMicroSDCard();\r\n}\r\n\r\nvoid loop() {    \r\n  \/\/ Take and Save Photo\r\n  takeSavePhoto();\r\n  delay(10000);\r\n}\r\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-CAM-Arduino-IDE\/raw\/master\/ESP32-CAM-Take-Photo-Date-Time-MicroSD-Card\/ESP32-CAM-Take-Photo-Date-Time-MicroSD-Card.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How the Code Works<\/h3>\n\n\n\n<p>Continue reading to learn how the code works, or skip to the <a href=\"#demonstration\">Demonstration <\/a>section.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Include Libraries<\/h4>\n\n\n\n<p>First, include the required libraries to handle the camera, microSD card, and time.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include \"esp_camera.h\"\n#include \"FS.h\"                \/\/ SD Card ESP32\n#include \"SD_MMC.h\"            \/\/ SD Card ESP32\n#include \"soc\/soc.h\"           \/\/ Disable brownout problems\n#include \"soc\/rtc_cntl_reg.h\"  \/\/ Disable brownout problems\n#include \"driver\/rtc_io.h\"\n#include &lt;WiFi.h&gt;\n#include \"time.h\"<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Network Credentials<\/h4>\n\n\n\n<p>Insert your network credentials on the following variables.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>const char* ssid = \"REPLACE_WITH_YOUR_SSID\";\nconst char* password = \"REPLACE_WITH_YOUR_PASSWORD\";<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"timezone-string\">Timezone String<\/h4>\n\n\n\n<p>Insert your timezone string on the <span class=\"rnthl rntliteral\">myTimezone<\/span> variable. You can check a <a href=\"https:\/\/github.com\/nayarsystems\/posix_tz_db\/blob\/master\/zones.csv\" target=\"_blank\" rel=\"noopener\">list of timezone string variables<\/a> here. For example, I live in Porto. The timezone is Europe\/Lisbon. From the list of timezone string variables, I see that the timezone string variable for my location is <span class=\"rnthl rntliteral\">WET0WEST,M3.5.0\/1,M10.5.0<\/span><\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/REPLACE WITH YOUR TIMEZONE STRING: https:\/\/github.com\/nayarsystems\/posix_tz_db\/blob\/master\/zones.csv\nString myTimezone =\"WET0WEST,M3.5.0\/1,M10.5.0\";<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Camera Pinout and Configurations<\/h4>\n\n\n\n<p>Then, include the pin definition for the camera model we\u2019re using. For the ESP32\u2011CAM AI-Thinker module, this is the pin definition (change it if you&#8217;re using a different ESP32 camera model):<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Pin definition for CAMERA_MODEL_AI_THINKER\n\/\/ Change pin definition if you're using another ESP32 camera module\n#define PWDN_GPIO_NUM     32\n#define RESET_GPIO_NUM    -1\n#define XCLK_GPIO_NUM      0\n#define SIOD_GPIO_NUM     26\n#define SIOC_GPIO_NUM     27\n#define Y9_GPIO_NUM       35\n#define Y8_GPIO_NUM       34\n#define Y7_GPIO_NUM       39\n#define Y6_GPIO_NUM       36\n#define Y5_GPIO_NUM       21\n#define Y4_GPIO_NUM       19\n#define Y3_GPIO_NUM       18\n#define Y2_GPIO_NUM        5\n#define VSYNC_GPIO_NUM    25\n#define HREF_GPIO_NUM     23\n#define PCLK_GPIO_NUM     22<\/code><\/pre>\n\n\n\n<p>You can find the pin definition for several different ESP32 camera boards here: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-camera-pin-gpios\/\">ESP32-CAM Camera Boards: Pin and GPIOs Assignment Guide<\/a>.<\/p>\n\n\n\n<p>The following line is needed to save the camera configurations. We&#8217;ll add the pin definition and the image settings later in the code.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Stores the camera configuration parameters\ncamera_config_t config;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Configure and Initialize the Camera<\/h4>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">configInitCamera()<\/span> function, starts by assigning the GPIOs you\u2019ve defined earlier as well as the picture format.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Initializes the camera\nvoid configInitCamera(){\n  config.ledc_channel = LEDC_CHANNEL_0;\n  config.ledc_timer = LEDC_TIMER_0;\n  config.pin_d0 = Y2_GPIO_NUM;\n  config.pin_d1 = Y3_GPIO_NUM;\n  config.pin_d2 = Y4_GPIO_NUM;\n  config.pin_d3 = Y5_GPIO_NUM;\n  config.pin_d4 = Y6_GPIO_NUM;\n  config.pin_d5 = Y7_GPIO_NUM;\n  config.pin_d6 = Y8_GPIO_NUM;\n  config.pin_d7 = Y9_GPIO_NUM;\n  config.pin_xclk = XCLK_GPIO_NUM;\n  config.pin_pclk = PCLK_GPIO_NUM;\n  config.pin_vsync = VSYNC_GPIO_NUM;\n  config.pin_href = HREF_GPIO_NUM;\n  config.pin_sscb_sda = SIOD_GPIO_NUM;\n  config.pin_sscb_scl = SIOC_GPIO_NUM;\n  config.pin_pwdn = PWDN_GPIO_NUM;\n  config.pin_reset = RESET_GPIO_NUM;\n  config.xclk_freq_hz = 20000000;\n  config.pixel_format = PIXFORMAT_JPEG; \/\/YUV422,GRAYSCALE,RGB565,JPEG\n  config.grab_mode = CAMERA_GRAB_LATEST;\n\n<\/code><\/pre>\n\n\n\n<p>The picture format is defined in the following line<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>config.pixel_format = PIXFORMAT_JPEG; \/\/YUV422,GRAYSCALE,RGB565,JPEG<\/code><\/pre>\n\n\n\n<p>It can be set to one of the following formats:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span class=\"rnthl rntliteral\">PIXFORMAT_JPEG<\/span><\/li>\n\n\n\n<li><span class=\"rnthl rntliteral\">PIXFORMAT_YUV422<\/span><\/li>\n\n\n\n<li><span class=\"rnthl rntliteral\">PIXFORMAT_GRAYSCALE<\/span><\/li>\n\n\n\n<li><span class=\"rnthl rntliteral\">PIXFORMAT_RGB565<\/span><\/li>\n\n\n\n<li><span class=\"rnthl rntliteral\">PIXFORMAT_JPEG<\/span> (format that we\u2019re using)<\/li>\n<\/ul>\n\n\n\n<p>Define the frame size, image quality, and the number of pictures saved in the frame buffer:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>  \/\/ Select lower framesize if the camera doesn't support PSRAM\n  if(psramFound()){\n    config.frame_size = FRAMESIZE_UXGA; \/\/ FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA\n    config.jpeg_quality = 10; \/\/0-63 lower number means higher quality\n    config.fb_count = 1;\n  } else {\n    config.frame_size = FRAMESIZE_SVGA;\n    config.jpeg_quality = 12;\n    config.fb_count = 1;\n  }<\/code><\/pre>\n\n\n\n<p>In case the camera model supports PSRAM, we set the frame size to UXGA (1600&#215;1200) and the image quality to 1.<\/p>\n\n\n\n<p>You can set the frame size to one of these options:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>FRAMESIZE_UXGA (1600 x 1200)<\/li>\n\n\n\n<li>FRAMESIZE_QVGA (320 x 240)<\/li>\n\n\n\n<li>FRAMESIZE_CIF (352 x 288)<\/li>\n\n\n\n<li>FRAMESIZE_VGA (640 x 480)<\/li>\n\n\n\n<li>FRAMESIZE_SVGA (800 x 600)<\/li>\n\n\n\n<li>FRAMESIZE_XGA (1024 x 768)<\/li>\n\n\n\n<li>FRAMESIZE_SXGA (1280 x 1024)<\/li>\n<\/ul>\n\n\n\n<p>The image quality can be a number between 0 and 63. A lower number means higher quality.<\/p>\n\n\n\n<p><strong>Important: <\/strong>very low numbers for image quality, especially at higher resolution, can make the ESP32-CAM crash, or it may not be able to take the photos correctly. So, if you notice that the images taken with the ESP32-CAM are cut in half or with strange colors, that&#8217;s probably a sign that you need to lower the quality (select a higher number like 10).<\/p>\n\n\n\n<p>The following lines initialize the camera with the configurations you\u2019ve set up previously. If the camera doesn\u2019t initialize successfully, this will return an error message.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>  \/\/ Initialize the Camera\n  esp_err_t err = esp_camera_init(&amp;config);\n  if (err != ESP_OK) {\n    Serial.printf(\"Camera init failed with error 0x%x\", err);\n    return;\n  }<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Initialize WiFi<\/h4>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">initWiFi()<\/span> function connects your board to your local network using the credentials you&#8217;ve set up previously.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Connect to wifi\nvoid  initWiFi(){\n  WiFi.begin(ssid, password);\n  Serial.println(\"Connecting Wifi\");\n  while (WiFi.status() != WL_CONNECTED) {\n    Serial.print(\".\");\n    delay(500);\n  }\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Initialize Time and Set the Timezone<\/h4>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">setTimezone()<\/span> function will set the <span class=\"rnthl rntliteral\">TZ<\/span> environmental variable with the correct timezone. call&nbsp;<span class=\"rnthl rntliteral\">setenv(\u201cTZ\u201d,&nbsp;<strong>timezone<\/strong>, 1)<\/span>, where&nbsp;<strong>timezone<\/strong>&nbsp;is one of the&nbsp;<a href=\"https:\/\/github.com\/nayarsystems\/posix_tz_db\/blob\/master\/zones.csv\" target=\"_blank\" rel=\"noreferrer noopener\">timezones listed here<\/a>. Then, call&nbsp;<span class=\"rnthl rntliteral\">tzset()<\/span>&nbsp;to update to that timezone. You should already have defined your timezone earlier in the code (<span class=\"rnthl rntliteral\">myTimezone<\/span> variable).<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Function to set timezone\nvoid setTimezone(String timezone){\n  Serial.printf(\"  Setting Timezone to %s\\n\",timezone.c_str());\n  setenv(\"TZ\",timezone.c_str(),1);  \/\/  Now adjust the TZ.  Clock settings are adjusted to show the new local time\n  tzset();\n}<\/code><\/pre>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">initTime()<\/span> function connects the ESP32-CAM to the NTP server and sets the correct timezone.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Connect to NTP server and adjust timezone\nvoid initTime(String timezone){\n  struct tm timeinfo;\n  Serial.println(\"Setting up time\");\n  configTime(0, 0, \"pool.ntp.org\");    \/\/ First connect to NTP server, with 0 TZ offset\n  if(!getLocalTime(&amp;timeinfo)){\n    Serial.println(\" Failed to obtain time\");\n    return;\n  }\n  Serial.println(\"Got the time from NTP\");\n  \/\/ Now we can set the real timezone\n  setTimezone(timezone);\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Get Current Time and Picture Filename<\/h4>\n\n\n\n<p>The whole purpose of this tutorial is to save pictures to the microSD card that include the date and time in the picture filename. The filename will be in the following format:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>picture_YYYY-MM-DD_HH-MM-SS.jpg<\/code><\/pre>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">getPictureFilename()<\/span> function gets the current date and time and outputs a string that can be used as a name for the picture filename.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String getPictureFilename(){<\/code><\/pre>\n\n\n\n<p>First, we get the date and time:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>struct tm timeinfo;\nif(!getLocalTime(&amp;timeinfo)){\n  Serial.println(\"Failed to obtain time\");\n  return \"\";\n}<\/code><\/pre>\n\n\n\n<p>Then, we convert the <span class=\"rnthl rntliteral\">timeinfo<\/span> variable to a String in the following format <span class=\"rnthl rntliteral\">Y-m-d_H-M-S<\/span> and print the result:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>strftime(timeString, sizeof(timeString), \"%Y-%m-%d_%H-%M-%S\", &amp;timeinfo);\nSerial.println(timeString);<\/code><\/pre>\n\n\n\n<p>After having the date and time in a String format, we can concatenate it with &#8220;picture&#8221; and &#8220;.jpg&#8221;, which is the picture format. <\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String filename = \"\/picture_\" + String(timeString) +\".jpg\";<\/code><\/pre>\n\n\n\n<p>Finally, we return the filename:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>return filename;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Initialize the microSD Card<\/h4>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">initMicroSDCard()<\/span> function initializes the microSD card. It returns an error message in case the initialization is not successful.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Start Micro SD card\nSerial.println(\"Starting SD Card\");\nif(!SD_MMC.begin()){\n  Serial.println(\"SD Card Mount Failed\");\n  return;\n}<\/code><\/pre>\n\n\n\n<p>The next lines return an error in case there isn\u2019t a microSD card attached.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>uint8_t cardType = SD_MMC.cardType();\nif(cardType == CARD_NONE){\n  Serial.println(\"No SD Card attached\");\n  return;\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Take and Save a Picture<\/h4>\n\n\n\n<p>To take and save a picture, we created the <span class=\"rnthl rntliteral\">takeSavePhoto()<\/span> function.<\/p>\n\n\n\n<p>First, it starts by taking a picture using the <span class=\"rnthl rntliteral\">esp_camera_fb_get()<\/span> function.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>camera_fb_t * fb = esp_camera_fb_get();<\/code><\/pre>\n\n\n\n<p>This previous line creates a frame buffer <span class=\"rnthl rntliteral\">fb<\/span> that contains the image. <\/p>\n\n\n\n<p>If you&#8217;re getting old pictures when you take a photo, it might mean that the picture buffer is saving more than one picture. To prevent that, you can uncomment the following lines in the code:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/esp_camera_fb_return(fb); \/\/ dispose the buffered image\n\/\/fb = NULL; \/\/ reset to capture errors\n\/\/fb = esp_camera_fb_get();<\/code><\/pre>\n\n\n\n<p>In case the capture fails, we print an error message and restart the board (restarting the board is optional, you can handle the error differently if you prefer, like trying to take another picture).<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if(!fb) {\n  Serial.println(\"Camera capture failed\");\n  delay(1000);\n  ESP.restart();\n}<\/code><\/pre>\n\n\n\n<p>After taking the picture, we&#8217;ll call the <span class=\"rnthl rntliteral\">getPictureFilename()<\/span> function to get a filename for the picture with the current timestamp.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>  \/\/ Path where new picture will be saved in SD Card\n  String path = getPictureFilename();\n  Serial.printf(\"Picture file name: %s\\n\", path.c_str());<\/code><\/pre>\n\n\n\n<p>Now that we have the picture (frame buffer <span class=\"rnthl rntliteral\">fb<\/span>), and the picture filename we can save it on the micro SD card.<\/p>\n\n\n\n<p>Open the microSD card in writing mode and create a file with the filename we&#8217;ve defined previously (it&#8217;s on the <span class=\"rnthl rntliteral\">path<\/span> variable):<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>fs::FS &amp;fs = SD_MMC; \nFile file = fs.open(path.c_str(),FILE_WRITE);<\/code><\/pre>\n\n\n\n<p>In case we&#8217;re not able the open the file (due to an error on the microSD card, or in creating the file), we print an error message.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if(!file){\n  Serial.printf(\"Failed to open file in writing mode\");\n} <\/code><\/pre>\n\n\n\n<p>Save the image by passing as arguments the frame buffer and its length to the <span class=\"rnthl rntliteral\">write()<\/span> method.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code> file.write(fb-&gt;buf, fb-&gt;len); \/\/ payload (image), payload length<\/code><\/pre>\n\n\n\n<p>After that, close the file:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>file.close();<\/code><\/pre>\n\n\n\n<p>Finally, call <span class=\"rnthl rntliteral\">esp_camera_fb_return(fb)<\/span> to clear the <span class=\"rnthl rntliteral\">fb<\/span> buffer, so that it\u2019s available to use for the next picture.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>esp_camera_fb_return(fb);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">setup()<\/h4>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">setup()<\/span>, initialize the Serial Monitor, initialize Wi-Fi, set the timezone, configure and initialize the camera, and initialize the microSD card.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void setup() {\n  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); \/\/ disable brownout detector\n\n  Serial.begin(115200);\n  delay(2000);\n\n  \/\/ Initialize Wi-Fi\n  initWiFi();\n  \/\/ Initialize time with timezone\n  initTime(myTimezone);    \n  \/\/ Initialize the camera  \n  Serial.print(\"Initializing the camera module...\");\n  configInitCamera();\n  Serial.println(\"Ok!\");\n  \/\/ Initialize MicroSD\n  Serial.print(\"Initializing the MicroSD card module... \");\n  initMicroSDCard();\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">loop()<\/h4>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">loop()<\/span>, call the <span class=\"rnthl rntliteral\">takeSavePhoto()<\/span> function to take a picture and save it on the microSD card. The picture name will already include the current timestamp.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void loop() {    \n  \/\/ Take and Save Photo\n  takeSavePhoto();\n  delay(10000);\n}<\/code><\/pre>\n\n\n\n<p>This function is called over and over again in the <span class=\"rnthl rntliteral\">loop()<\/span> every 10 seconds.<\/p>\n\n\n\n<p>We do this for demonstration purposes. Now, you should be able to use the <span class=\"rnthl rntliteral\">takeSavePhoto()<\/span> function in your own projects to take pictures with a unique filename.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Demonstration<\/h2>\n\n\n\n<p>After inserting your network credentials and timezone string, upload the code to your board.<\/p>\n\n\n\n<p>If you have an ESP32-CAM AI-Thinker, you should select <strong>AI Thinker ESP32-CAM<\/strong> in the <strong>Tools<\/strong>> <strong>Board <\/strong>menu.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"437\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/select-ESP32-CAM-Arduino-IDE.png?resize=750%2C437&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Selecting the ESP32-CAM Ai Thinker in the Arduino IDE\" class=\"wp-image-125435\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/select-ESP32-CAM-Arduino-IDE.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/select-ESP32-CAM-Arduino-IDE.png?resize=300%2C175&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>After that, select the <strong>COM <\/strong>port in <strong>Tools <\/strong>&gt; <strong>Port<\/strong>.<\/p>\n\n\n\n<p>Finally, upload the code.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"30\" height=\"30\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/05\/arduino-2-0-upload-button.png?resize=30%2C30&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Arduino 2.0 Upload Button\" class=\"wp-image-103678\"\/><\/figure><\/div>\n\n\n<p>If you&#8217;re having issues uploading the code, check our troubleshooting guide: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-troubleshooting-guide\/\">ESP32-CAM Troubleshooting Guide: Most Common Problems Fixed<\/a>.<\/p>\n\n\n\n<p>After successfully uploading the code to the board, open the Serial Monitor at a baud rate of 115200. Press the RST button so that it restarts the board and it starts running the code.<\/p>\n\n\n\n<p><strong>Don&#8217;tn forget to insert a microSD card on the ESP32-CAM microSD card slot.<\/strong><\/p>\n\n\n\n<p>Every 10 seconds, the flash will go on and it will save a picture to the microSD card. Let the code run for a while so that you get a considerable amount of pictures.<\/p>\n\n\n\n<p>In the Serial Monitor, you should get something as shown below.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"715\" height=\"436\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-CAM-Take-Pictur3e-microSD-card-date-time-serial-monitor.png?resize=715%2C436&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CMA Take Pictures with Timestamp Serial Monitor Demonstration\" class=\"wp-image-125437\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-CAM-Take-Pictur3e-microSD-card-date-time-serial-monitor.png?w=715&amp;quality=100&amp;strip=all&amp;ssl=1 715w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-CAM-Take-Pictur3e-microSD-card-date-time-serial-monitor.png?resize=300%2C183&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 715px) 100vw, 715px\" \/><\/figure><\/div>\n\n\n<p>Then, insert the microSD card into your computer to see the captured photos.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"505\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-CAM-Pictures-Saved-MicroSD-Card-Date-Time.jpg?resize=750%2C505&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM Pictures Folder on microSD Card\" class=\"wp-image-125440\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-CAM-Pictures-Saved-MicroSD-Card-Date-Time.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-CAM-Pictures-Saved-MicroSD-Card-Date-Time.jpg?resize=300%2C202&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>The photos should have the date and time in its name. For example:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">picture_2023-01-17_17-31-40.jpg<\/pre>\n\n\n\n<p>This means that this picture was taken on:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Year: 2023<\/li>\n\n\n\n<li>Month: 01 (January)<\/li>\n\n\n\n<li>Day: 17th<\/li>\n\n\n\n<li>Time: 17:31:40 (5:31:40 PM)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In this project, you learned how to request the date and time (with the correct timezone and daylight saving time) from the internet using the ESP32-CAM and use that information to name your pictures. This way, you know what time and date a certain picture was taken, and you don\u2019t have to worry about overwriting photos on the microSD card.<\/p>\n\n\n\n<p>For a detailed tutorial about getting date and time with the ESP32 and setting the timezone, we recommend the following tutorial:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-ntp-timezones-daylight-saving\/\">ESP32 NTP Time \u2013 Setting Up Timezones and Daylight Saving Time<\/a><\/li>\n<\/ul>\n\n\n\n<p>To learn more about the ESP32-CAM and build more projects, we take a look at our eBook:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-projects-ebook\/\">Build ESP32-CAM Projects eBook<\/a><\/li>\n<\/ul>\n\n\n\n<p>We hope you found this tutorial interesting.<\/p>\n\n\n\n<p>Thanks for reading.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you&#8217;ll learn to take a picture with the ESP32-CAM and save it to the microSD card. We&#8217;ll include the current date and time on the filename. Including &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"ESP32-CAM Take Photo and Save to MicroSD Card with Date and Time (timestamp)\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-photo-microsd-card-timestamp\/#more-125386\" aria-label=\"Read more about ESP32-CAM Take Photo and Save to MicroSD Card with Date and Time (timestamp)\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":125444,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[319],"tags":[],"class_list":["post-125386","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp32-cam"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-CAM-Phot-MicroSD-Card-Data-Time.jpg?fit=1280%2C720&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/125386","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=125386"}],"version-history":[{"count":12,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/125386\/revisions"}],"predecessor-version":[{"id":159111,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/125386\/revisions\/159111"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/125444"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=125386"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=125386"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=125386"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}