ESP32 チュートリアル 42/55 - カメラで写真を撮影し、マイクロSDに保存 CAM-1 | SunFounder の ESP32 キット
このチュートリアルでは、ESP32マイクロコントローラーとSunFounderの拡張ボードを使用して、カメラで写真を撮影し、それを直接マイクロSDカードに保存します。このプロジェクトは、Wi-FiやBluetoothを含むESP32の内蔵機能を活用して、コンパクトな写真撮影デバイスを作成します。このチュートリアルの終わりまでに、画像を撮影して保存できる作業セットアップが完成し、その後コンピュータでアクセスできるようになります。
ESP32エコシステムに不慣れな方のために、このキットはさまざまなプロジェクトに対応した多用途のプラットフォームを提供します。このプロジェクトで使用されるカメラはOV2640で、解像度は1600x1200ピクセルです。最新のスマートフォンと同等の品質ではないかもしれませんが、基本的な画像キャプチャ作業には十分です。手順を明確にするために、このチュートリアルに付随するビデオ(00:00のビデオ)を必ず確認してください。
ハードウェアの解説
このプロジェクトの主なコンポーネントには、ESP32マイクロコントローラー、カメラモジュール(OV2640)、およびストレージ用のマイクロSDカードが含まれます。ESP32は、Wi-FiおよびBluetooth機能を統合した強力なマイクロコントローラーで、IoTアプリケーションに最適です。カメラモジュールは画像をキャプチャし、それをESP32が処理します。
マイクロSDカードは、キャプチャされた画像のストレージ媒体として機能します。この設定では、ESP32は特定のGPIOピンを使用してカメラモジュールと通信し、画像はSDカード上にJPEG形式で保存されます。これにより、後で写真を容易に取得して表示することができます。
- ESP32ボードに挿入する際は、カメラが正しく向いていることを確認してください。
- 互換性の問題を避けるためには、容量が32 GB以下のマイクロSDカードを使用してください。
- GPIO 0をGNDに接続してプログラミングモードにします。
- 電源に注意して、褐色化の問題を避けてください。
- 写真を撮る際は、カメラをしっかりと固定して、ぼやけた画像を避けてください。
配線指示書
ESP32カメラモジュールを配線するには、まずESP32の電源をオフにします。次に、以下のピンを使用してESP32にマイクロSDカードモジュールを接続します:接続するCSESP32のSDカードのピンにGPIO 5,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); // Disable brownout detector
Serial.begin(115200);
camera_config_t config;
// Configuration settings for the camera
config.ledc_channel = LEDC_CHANNEL_0;
// Additional camera settings...
}セットアップ関数はシリアル通信を初期化し、カメラ設定を構成します。構成には、次のようなパラメータが含まれます。ledc_channel,pin_d0, とxclk_freq_hz最適なパフォーマンスのために。
次に、ループを使用して複数の画像を撮影することで、画像キャプチャプロセスを処理します。画像データは、ファイル名に基づいてSDカードに保存されます。pictureNumber.
for (int shoot = 0; shoot < 5; shoot++) {
camera_fb_t *fb = esp_camera_fb_get(); // Take Picture
String path = "/picture" + String(pictureNumber) + ".jpg"; // File path
File file = fs.open(path.c_str(), FILE_WRITE); // Open file to write
// Write image data to file
file.write(fb->buf, fb->len);
// Update picture number in EEPROM
EEPROM.write(0, pictureNumber);
}このループは最大5つの画像をキャプチャし、それぞれの画像はユニークなファイル名で保存されます。EEPROMを使用することで、プログラムは最後の画像番号を記憶し、新しい画像がユニークな識別子を持つことを保証します。
デモンストレーション / 予想されること
コードを実行すると、ESP32はカメラとSDカードを初期化します。ESP32のリセットボタンを押した後、EEPROMの値に基づいて、0から255まで連番で番号付けされた一連の画像を撮影します。画像をキャプチャした後は、マイクロSDカードを取り外して、コンピュータで写真を表示できます。
一般的な落とし穴には、マイクロSDカードが正しくフォーマットされ挿入されていることを確認することや、ぼやけた画像を避けるためにカメラの位置を安定させることが含まれます。カメラが画像をキャプチャしていない場合は、配線とコードに設定した構成を再確認してください(ビデオの06:45にて)。
ビデオのタイムスタンプ
- 00:00 開始
- 1:39 イントロダクション
- 5:19 ESP32カメラコードの説明
- 11:10 Arduino IDEでESP32ボードとCOMポートを選択する
- 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 チュートリアル 42/55 - SunFounder ドキュメントページ 写真撮影docs.sunfounder.com
ファイル📁
ファイルは利用できません。