ค้นหาโค้ด

บทเรียน ESP32 42/55 - ถ่ายภาพด้วยกล้องแล้วบันทึกลง Micro SD CAM-1 | ชุด ESP32 ของ SunFounder

บทเรียน ESP32 42/55 - ถ่ายภาพด้วยกล้องแล้วบันทึกลง Micro SD CAM-1 | ชุด ESP32 ของ SunFounder

ในบทช่วยสอนนี้ เราจะใช้ไมโครคอนโทรลเลอร์ ESP32 พร้อมกับบอร์ดขยายจาก SunFounder เพื่อถ่ายภาพด้วยกล้องและบันทึกลงในการ์ด micro SD โดยตรง โปรเจกต์นี้ใช้ความสามารถในตัวของ ESP32 รวมถึง Wi-Fi และ Bluetooth เพื่อสร้างอุปกรณ์ถ่ายภาพขนาดกะทัดรัด เมื่อจบบทช่วยสอนนี้ คุณจะได้ชุดอุปกรณ์ที่ใช้งานได้ซึ่งสามารถถ่ายและจัดเก็บภาพ ซึ่งสามารถเข้าถึงได้ในภายหลังบนคอมพิวเตอร์

extension_bopard_camera

สำหรับผู้ที่ยังใหม่กับระบบนิเวศ ESP32 ชุดอุปกรณ์นี้เป็นแพลตฟอร์มที่หลากหลายสำหรับโปรเจกต์ต่างๆ รวมถึงโปรเจกต์นี้ด้วย กล้องที่ใช้ในโปรเจกต์นี้คือ OV2640 ซึ่งมีความละเอียด 1600x1200 พิกเซล แม้ว่าอาจไม่เทียบเท่าคุณภาพของสมาร์ทโฟนสมัยใหม่ แต่ก็เพียงพอสำหรับงานถ่ายภาพพื้นฐาน เพื่อให้ขั้นตอนชัดเจนยิ่งขึ้น โปรดตรวจสอบวิดีโอที่มาพร้อมกับบทช่วยสอนนี้ (ในวิดีโอที่เวลา 00:00)

20240103_163227858_iOS

อธิบายฮาร์ดแวร์

ส่วนประกอบหลักในโปรเจกต์นี้ประกอบด้วยไมโครคอนโทรลเลอร์ ESP32 โมดูลกล้อง (OV2640) และการ์ด micro SD สำหรับจัดเก็บข้อมูล ESP32 เป็นไมโครคอนโทรลเลอร์ที่ทรงพลังพร้อมความสามารถ Wi-Fi และ Bluetooth ในตัว ทำให้เหมาะสำหรับแอปพลิเคชัน IoT โมดูลกล้องจะจับภาพ ซึ่งจากนั้น ESP32 จะประมวลผล

esp32-41-setting-3

การ์ด micro SD ทำหน้าที่เป็นสื่อจัดเก็บข้อมูลสำหรับภาพที่ถ่ายได้ ในการตั้งค่านี้ ESP32 จะสื่อสารกับโมดูลกล้องโดยใช้พิน GPIO เฉพาะ และภาพจะถูกบันทึกในรูปแบบ JPEG บนการ์ด SD ซึ่งช่วยให้สามารถดึงข้อมูลและดูภาพถ่ายได้ง่ายในภายหลัง

  • ตรวจสอบให้แน่ใจว่ากล้องอยู่ในทิศทางที่ถูกต้องเมื่อเสียบเข้ากับบอร์ด ESP32
  • ใช้การ์ด micro SD ที่มีความจุ 32 GB หรือน้อยกว่าเพื่อหลีกเลี่ยงปัญหาความเข้ากันได้
  • เชื่อมต่อ GPIO 0 เข้ากับ GND สำหรับโหมดการเขียนโปรแกรม
  • ใส่ใจกับแหล่งจ่ายไฟเพื่อหลีกเลี่ยงปัญหาบราวน์เอาต์
  • ถือกล้องให้นิ่งขณะถ่ายภาพเพื่อหลีกเลี่ยงภาพเบลอ

คำแนะนำการเดินสายไฟ

ในการเดินสายไฟโมดูลกล้อง ESP32 ก่อนอื่นตรวจสอบให้แน่ใจว่า ESP32 ปิดอยู่ เชื่อมต่อโมดูลการ์ด micro SD เข้ากับ ESP32 โดยใช้พินต่อไปนี้: เชื่อมต่อพิน CS ของการ์ด SD เข้ากับ GPIO 5 ของ ESP32, MOSI เข้ากับ GPIO 23, MISO เข้ากับ GPIO 19 และ SCK เข้ากับ GPIO 18 จากนั้นเชื่อมต่อพินโมดูลกล้องดังนี้: PWDN เข้ากับ GPIO 32, XCLK เข้ากับ GPIO 0, SIOD เข้ากับ GPIO 26 และ SIOC เข้ากับ GPIO 27 พินข้อมูลพิกเซล Y2 ถึง Y9 ควรเชื่อมต่อกับ GPIO 5 ถึง GPIO 39 ตามที่กำหนดในโค้ดของคุณ

ตรวจสอบให้แน่ใจว่าได้เชื่อมต่อพินกราวด์และพินไฟอย่างเหมาะสม ESP32 สามารถจ่ายไฟได้ด้วยแบตเตอรี่ที่รวมอยู่ในชุดอุปกรณ์ หลังจากเดินสายไฟแล้ว ตรวจสอบให้แน่ใจว่าการเชื่อมต่อแน่นหนาก่อนเปิดเครื่อง หากคุณปฏิบัติตามคำแนะนำอย่างใกล้ชิด คุณควรเห็นกล้องเริ่มทำงานอย่างถูกต้องเมื่อคุณอัปโหลดโค้ด

ตัวอย่างโค้ดและคำอธิบาย

esp32-41-setting-2
esp32-41-setting-1

ในโค้ด เราเริ่มต้นด้วยการรวมไลบรารีที่จำเป็นและกำหนดการกำหนดค่าพินกล้อง ตัวแปร pictureNumber ถูกกำหนดค่าเริ่มต้นเพื่อติดตามจำนวนภาพถ่ายที่ถ่าย

int pictureNumber = 0;

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);  // ปิดการตรวจจับบราวน์เอาต์
  Serial.begin(115200);
  camera_config_t config;
  // การตั้งค่าคอนฟิกสำหรับกล้อง
  config.ledc_channel = LEDC_CHANNEL_0;
  // การตั้งค่ากล้องเพิ่มเติม...
}

ฟังก์ชัน setup เริ่มต้นการสื่อสารแบบอนุกรมและกำหนดค่าการตั้งค่ากล้อง การกำหนดค่าประกอบด้วยพารามิเตอร์เช่น ledc_channel, pin_d0 และ xclk_freq_hz เพื่อประสิทธิภาพที่ดีที่สุด

จากนั้น เราจัดการกระบวนการจับภาพโดยใช้ลูปเพื่อถ่ายภาพหลายภาพ ข้อมูลภาพจะถูกบันทึกลงในการ์ด SD ด้วยชื่อไฟล์ตาม pictureNumber

for (int shoot = 0; shoot < 5; shoot++) {
    camera_fb_t *fb = esp_camera_fb_get(); // ถ่ายภาพ
    String path = "/picture" + String(pictureNumber) + ".jpg"; // เส้นทางไฟล์
    File file = fs.open(path.c_str(), FILE_WRITE); // เปิดไฟล์เพื่อเขียน
    // เขียนข้อมูลภาพลงในไฟล์
    file.write(fb->buf, fb->len);
    // อัปเดตหมายเลขภาพใน EEPROM
    EEPROM.write(0, pictureNumber);
}

ลูปนี้ถ่ายภาพได้สูงสุดห้าภาพ โดยแต่ละภาพจะถูกบันทึกด้วยชื่อไฟล์ที่ไม่ซ้ำกัน การใช้ EEPROM ช่วยให้โปรแกรมจดจำหมายเลขภาพล่าสุดได้ เพื่อให้แน่ใจว่าภาพใหม่แต่ละภาพมีตัวระบุที่ไม่ซ้ำกัน

การสาธิต / สิ่งที่คาดหวัง

เมื่อคุณรันโค้ด ESP32 จะเริ่มต้นการทำงานของกล้องและการ์ด SD หลังจากกดปุ่มรีเซ็ตบน ESP32 มันจะถ่ายภาพชุดหนึ่ง ซึ่งจะถูกกำหนดหมายเลขตามลำดับตั้งแต่ 0 ถึง 255 โดยอ้างอิงจากค่า EEPROM หลังจากถ่ายภาพเสร็จ คุณสามารถถอดการ์ด micro SD ออกและดูภาพบนคอมพิวเตอร์ของคุณได้

ข้อผิดพลาดทั่วไปที่ควรระวัง ได้แก่ การตรวจสอบให้แน่ใจว่าการ์ด micro SD ถูกฟอร์แมตอย่างถูกต้องและเสียบอย่างถูกต้อง รวมถึงการรักษาตำแหน่งกล้องให้มั่นคงเพื่อหลีกเลี่ยงภาพเบลอ หากคุณพบปัญหาที่กล้องไม่สามารถถ่ายภาพได้ ให้ตรวจสอบการเดินสายไฟและการตั้งค่าในโค้ดอีกครั้ง (ในวิดีโอที่เวลา 06:45)

ไทม์สแตมป์ของวิดีโอ

  • 00:00 เริ่มต้น
  • 1:39 บทนำ
  • 5:19 อธิบายโค้ด ESP32 Camera
  • 11:10 การเลือกบอร์ด ESP32 และพอร์ต COM ใน Arduino IDE
  • 12:52 การถ่ายภาพทดสอบภายในและภายนอกอาคาร

ภาพ

esp32-41-setting-3
esp32-41-setting-3
extension_bopard_camera
extension_bopard_camera
20240103_163227858_iOS
20240103_163227858_iOS
esp32-41-setting-1
esp32-41-setting-1
esp32-41-setting-2
esp32-41-setting-2
843-ESP32 Tutorial 42/55- Arduino code for taking photo and saving it
ภาษา: C++
/*********
  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;
  }

  // initialize EEPROM with predefined size
  EEPROM.begin(EEPROM_SIZE);
  pictureNumber = EEPROM.read(0) + 1;

  for (int shoot = 0; shoot < 5; shoot++) {
    camera_fb_t *fb = NULL;

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

    // 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);  // Write image data to file
      if (shoot == 4) {
        Serial.printf("Saved file to path: %s\n", path.c_str());
      }else{
        Serial.printf("Shooting... \n");
      }
      EEPROM.write(0, pictureNumber);  // Update the picture number in EEPROM
      EEPROM.commit();
    }
    file.close();                      // Close the file
    esp_camera_fb_return(fb);          // Return the frame buffer back to the camera driver
    delay(200);                        // Short delay between shots
  }
  // 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);

  // Put the ESP32-CAM to deep sleep
  delay(2000);
  Serial.println("Going to sleep now");
  delay(2000);
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop() {
  // Empty loop as we are putting the ESP32-CAM to deep sleep
}

แหล่งข้อมูลและเอกสารอ้างอิง

ไฟล์📁

ไม่มีไฟล์ที่พร้อมใช้งาน