Tìm kiếm mã

Hướng dẫn ESP32 42/55 - Chụp ảnh bằng Camera lưu trên thẻ Micro SD CAM-1 | Bộ kit ESP32 của SunFounder

Hướng dẫn ESP32 42/55 - Chụp ảnh bằng Camera lưu trên thẻ Micro SD CAM-1 | Bộ kit ESP32 của SunFounder

Trong hướng dẫn này, chúng ta sẽ sử dụng vi điều khiển ESP32 cùng với bo mở rộng của nó từ SunFounder để chụp ảnh bằng camera và lưu trực tiếp lên thẻ micro SD. Dự án này tận dụng các khả năng tích hợp sẵn của ESP32, bao gồm Wi-Fi và Bluetooth, để tạo ra một thiết bị chụp ảnh nhỏ gọn. Kết thúc hướng dẫn này, bạn sẽ có một hệ thống hoạt động có thể chụp và lưu trữ hình ảnh, sau đó có thể truy cập trên máy tính.

extension_bopard_camera

Đối với những người mới làm quen với hệ sinh thái ESP32, bộ kit này cung cấp một nền tảng linh hoạt cho nhiều dự án khác nhau, bao gồm cả dự án này. Camera được sử dụng trong dự án là OV2640, có độ phân giải 1600x1200 pixel. Mặc dù chất lượng có thể không bằng điện thoại thông minh hiện đại, nhưng nó đủ cho các tác vụ chụp ảnh cơ bản. Để làm rõ bất kỳ bước nào, hãy xem video đi kèm với hướng dẫn này (trong video tại 00:00).

20240103_163227858_iOS

Phần cứng được giải thích

Các thành phần chính trong dự án này bao gồm vi điều khiển ESP32, mô-đun camera (OV2640) và thẻ micro SD để lưu trữ. ESP32 là một vi điều khiển mạnh mẽ với khả năng Wi-Fi và Bluetooth tích hợp, lý tưởng cho các ứng dụng IoT. Mô-đun camera chụp hình ảnh, sau đó được xử lý bởi ESP32.

esp32-41-setting-3

Thẻ micro SD đóng vai trò là phương tiện lưu trữ cho các hình ảnh đã chụp. Trong thiết lập này, ESP32 giao tiếp với mô-đun camera bằng các chân GPIO cụ thể, và hình ảnh được lưu ở định dạng JPEG trên thẻ SD. Điều này cho phép dễ dàng truy xuất và xem ảnh sau này.

  • Đảm bảo camera được định hướng chính xác khi cắm vào bo ESP32.
  • Sử dụng thẻ micro SD có dung lượng 32 GB hoặc nhỏ hơn để tránh các vấn đề tương thích.
  • Kết nối GPIO 0 với GND để vào chế độ lập trình.
  • Chú ý đến nguồn điện để tránh các sự cố sụt áp.
  • Giữ camera ổn định khi chụp ảnh để tránh hình ảnh bị mờ.

Hướng dẫn đấu dây

Để đấu dây mô-đun camera ESP32, trước tiên hãy đảm bảo ESP32 đã được tắt nguồn. Kết nối mô-đun thẻ micro SD với ESP32 bằng các chân sau: kết nối chân CS của thẻ SD với GPIO 5 của ESP32, MOSI với GPIO 23, MISO với GPIO 19SCK với GPIO 18. Tiếp theo, kết nối các chân của mô-đun camera như sau: PWDN với GPIO 32, XCLK với GPIO 0, SIOD với GPIO 26SIOC với GPIO 27. Các chân dữ liệu pixel Y2 đến Y9 nên được kết nối với GPIO 5 đến GPIO 39 như được định nghĩa trong mã của bạn.

Đảm bảo kết nối các chân nối đất và nguồn một cách phù hợp. ESP32 có thể được cấp nguồn bằng pin đi kèm trong bộ kit. Sau khi đấu dây, hãy đảm bảo các kết nối chắc chắn trước khi bật nguồn thiết bị. Nếu bạn làm theo hướng dẫn một cách chính xác, bạn sẽ thấy camera khởi tạo đúng cách khi tải mã lên.

Ví dụ mã & hướng dẫn chi tiết

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

Trong mã, chúng ta bắt đầu bằng việc bao gồm các thư viện cần thiết và định nghĩa cấu hình chân camera. Biến pictureNumber được khởi tạo để theo dõi số lượng ảnh đã chụp.

int pictureNumber = 0;

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);  // Vô hiệu hóa bộ phát hiện sụt áp
  Serial.begin(115200);
  camera_config_t config;
  // Cài đặt cấu hình cho camera
  config.ledc_channel = LEDC_CHANNEL_0;
  // Các cài đặt camera bổ sung...
}

Hàm setup khởi tạo giao tiếp nối tiếp và cấu hình các cài đặt camera. Cấu hình bao gồm các tham số như ledc_channel, pin_d0xclk_freq_hz để có hiệu suất tối ưu.

Tiếp theo, chúng ta xử lý quá trình chụp hình ảnh bằng cách sử dụng một vòng lặp để chụp nhiều ảnh. Dữ liệu hình ảnh được lưu vào thẻ SD với tên tệp dựa trên pictureNumber.

for (int shoot = 0; shoot < 5; shoot++) {
    camera_fb_t *fb = esp_camera_fb_get(); // Chụp ảnh
    String path = "/picture" + String(pictureNumber) + ".jpg"; // Đường dẫn tệp
    File file = fs.open(path.c_str(), FILE_WRITE); // Mở tệp để ghi
    // Ghi dữ liệu hình ảnh vào tệp
    file.write(fb->buf, fb->len);
    // Cập nhật số ảnh trong EEPROM
    EEPROM.write(0, pictureNumber);
}

Vòng lặp này chụp tối đa năm hình ảnh, mỗi hình ảnh được lưu với một tên tệp duy nhất. Việc sử dụng EEPROM cho phép chương trình ghi nhớ số ảnh cuối cùng, đảm bảo mỗi hình ảnh mới có một định danh duy nhất.

Trình diễn / Điều gì sẽ xảy ra

Khi bạn chạy mã, ESP32 sẽ khởi tạo camera và thẻ SD. Sau khi nhấn nút reset trên ESP32, nó sẽ chụp một loạt ảnh, được đánh số tuần tự từ 0 đến 255 dựa trên giá trị EEPROM. Sau khi chụp xong, bạn có thể tháo thẻ micro SD và xem các bức ảnh trên máy tính của mình.

Các lỗi thường gặp bao gồm đảm bảo thẻ micro SD được định dạng và cắm đúng cách, cũng như duy trì vị trí camera ổn định để tránh ảnh bị mờ. Nếu bạn gặp sự cố camera không chụp được ảnh, hãy kiểm tra lại dây nối và cấu hình được đặt trong mã (trong video tại 06:45).

Mốc thời gian video

  • 00:00 Bắt đầu
  • 1:39 Giới thiệu
  • 5:19 Giải thích mã ESP32 Camera
  • 11:10 Chọn bo mạch ESP32 và cổng COM trong Arduino IDE
  • 12:52 Chụp ảnh thử nghiệm trong nhà và ngoài trời

Hình ảnh

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
Ngôn ngữ: 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
}

Tài nguyên & tài liệu tham khảo

Tập tin📁

Không có tệp nào khả dụng.