บทเรียน ESP32 42/55 - ถ่ายภาพด้วยกล้องแล้วบันทึกลง Micro SD CAM-1 | ชุด ESP32 ของ SunFounder
ในบทช่วยสอนนี้ เราจะใช้ไมโครคอนโทรลเลอร์ ESP32 พร้อมกับบอร์ดขยายจาก SunFounder เพื่อถ่ายภาพด้วยกล้องและบันทึกลงในการ์ด micro SD โดยตรง โปรเจกต์นี้ใช้ความสามารถในตัวของ ESP32 รวมถึง Wi-Fi และ Bluetooth เพื่อสร้างอุปกรณ์ถ่ายภาพขนาดกะทัดรัด เมื่อจบบทช่วยสอนนี้ คุณจะได้ชุดอุปกรณ์ที่ใช้งานได้ซึ่งสามารถถ่ายและจัดเก็บภาพ ซึ่งสามารถเข้าถึงได้ในภายหลังบนคอมพิวเตอร์
สำหรับผู้ที่ยังใหม่กับระบบนิเวศ ESP32 ชุดอุปกรณ์นี้เป็นแพลตฟอร์มที่หลากหลายสำหรับโปรเจกต์ต่างๆ รวมถึงโปรเจกต์นี้ด้วย กล้องที่ใช้ในโปรเจกต์นี้คือ OV2640 ซึ่งมีความละเอียด 1600x1200 พิกเซล แม้ว่าอาจไม่เทียบเท่าคุณภาพของสมาร์ทโฟนสมัยใหม่ แต่ก็เพียงพอสำหรับงานถ่ายภาพพื้นฐาน เพื่อให้ขั้นตอนชัดเจนยิ่งขึ้น โปรดตรวจสอบวิดีโอที่มาพร้อมกับบทช่วยสอนนี้ (ในวิดีโอที่เวลา 00:00)
อธิบายฮาร์ดแวร์
ส่วนประกอบหลักในโปรเจกต์นี้ประกอบด้วยไมโครคอนโทรลเลอร์ ESP32 โมดูลกล้อง (OV2640) และการ์ด micro SD สำหรับจัดเก็บข้อมูล ESP32 เป็นไมโครคอนโทรลเลอร์ที่ทรงพลังพร้อมความสามารถ Wi-Fi และ Bluetooth ในตัว ทำให้เหมาะสำหรับแอปพลิเคชัน IoT โมดูลกล้องจะจับภาพ ซึ่งจากนั้น ESP32 จะประมวลผล
การ์ด 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 สามารถจ่ายไฟได้ด้วยแบตเตอรี่ที่รวมอยู่ในชุดอุปกรณ์ หลังจากเดินสายไฟแล้ว ตรวจสอบให้แน่ใจว่าการเชื่อมต่อแน่นหนาก่อนเปิดเครื่อง หากคุณปฏิบัติตามคำแนะนำอย่างใกล้ชิด คุณควรเห็นกล้องเริ่มทำงานอย่างถูกต้องเมื่อคุณอัปโหลดโค้ด
ตัวอย่างโค้ดและคำอธิบาย
ในโค้ด เราเริ่มต้นด้วยการรวมไลบรารีที่จำเป็นและกำหนดการกำหนดค่าพินกล้อง ตัวแปร 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 การถ่ายภาพทดสอบภายในและภายนอกอาคาร
/*********
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
}
Common Course Links
Common Course Files
แหล่งข้อมูลและเอกสารอ้างอิง
-
เอกสารESP32 Tutorial 42/55 - SunFounder doc page for taking photodocs.sunfounder.com
ไฟล์📁
ไม่มีไฟล์ที่พร้อมใช้งาน