📷

Hands on: M5Stack CamS3 5MP Unit

に公開

みんな、こんにちは!今日はM5StackのWi-FiカメラユニットCamS3 5MPの使い方を見ていくよ。以前、Hands on: M5Stack CamS3 Unitという記事を書いたんだけど、この記事で扱っているCamS3は販売が終了しちゃったんだよね。だから、今回はその後継品であるCamS3 5MPの使い方をまとめているよ。以前のCamS3とCamS3 5MPは搭載しているカメラモジュールがOV2640からPY260という謎モジュールに変更になっていて、CamS3用に作成したソフトはそのままでは動かなくなっているよ。

CamS3/CamS3 5MPの最大の特徴はカメラとESP32マイコンのモジュールが一体で、別途マイコンを用意しなくても単体でプログラムを作成して色んなものが作れるところだね。CamS3 5MPの使い方の情報ってまだ少ないから、それだけで使うのを諦めるのは勿体無いよね。この記事ではカメラで画像をキャプチャするところまで説明しているから、ぜひ試してみてね!

https://ssci.to/9923

外観や付属品はCamS3と同じだから今回は詳しくは説明しないよ。外観が気になったら以前の記事を参照してみてね。

https://zenn.dev/nananauno/articles/cedc08e6110f09

こんな人にオススメ

  • CamS3 5MPの使い方を知りたい
  • Wi-Fiカメラを作ってみたい

やること

この記事ではCamS3 5MPの概要、環境セットアップ、プログラムの作成方法についてまとめているよ。プログラムの作成では以下の動作ができるようにするよ。

  • カメラの画像をmicroSDカードに保存

CamS3 5MP vs CamS3

プログラムを作成する前に、後継品のCamS3 5MPはCamS3から何が変わったのかをざっくりと見てみるよ。大きさは同じで5MPのボディの色が白になっているよ。頭のところに5MPと書かれたシールも貼り付けられているね。あとはカメラ周辺の形状が違うね。それ以外は特に見た目上の変更は無いみたい。GPIOのピンも同じ。


前面 左:CamS3 5MP, 右:CamS3


背面 左:CamS3 5MP, 右:CamS3

5MPの主な変更はカメラモジュールで、以前使われていたOV2640に代わってPY260というカメラモジュールが採用されているよ。ESP32は両方ともESP32-S3-WROOM-1-N16R8で変更なし。カメラモジュールの変更によってカメラで撮影できる最大解像度が2MP(1600x1200 pixels)から5MP(2592x1944 pixels)にアップしているよ。

Model SoC Camera MIC
CamS3 5MP ESP32-S3-WROOM-1-N16R8
16MB flash, 8MB PSRAM
PY260
2592x1944 pixels
MSM1261D4030HCPM
CamS3 ESP32-S3-WROOM-1-N16R8
16MB flash, 8MB PSRAM
OV2640
1600x1200 pixels
MSM1261D4030HCPM

環境

今回使った環境だよ。

  • Arduino IDE 2.x
  • Arduino-ESP v3.3.0
  • CamS3 5MP×1個
  • microSDカード×1枚

環境セットアップ
CamS3 5MPを使うための環境をArduino IDEで整えるよ。流れは以下の通り:

  1. Board Managerでesp32の最新版(v3.3.0以降)をインストール
  2. CamS3 5MPに使われているモジュールのバージョンを確認
  3. ESP32-camのモジュール入れ替え

この環境セットアップ手順はM5Stack公式のドキュメントを参考にしているよ。
https://docs.m5stack.com/ja/arduino/m5unitcams3_5mp/program

1.Board Managerでesp32の最新版(v3.3.0以降)をインストール
ArduinoIDEのBoard Managerでesp32と検索して、esp32 by Espressif Systemsでインストールされているバージョンを確認してね。これがv3.3.0かそれ以降ならこの手順はスキップしてね。
もし、v3.3.0未満のバージョンだったら、v3.3.0よりも新しいバージョンをインストールするよ。

2. CamS3 5MPに使われているモジュールのバージョンを確認
上のM5Stack公式のドキュメントを開いて「4. ハードウェアバージョンの確認」という箇所のコードをCamS3 5MPに書き込んでカメラモジュールのバージョンを確認するよ。このコードを実行するとシリアルコンソールに以下のようなログが出力されるよ。New versionかOld versionどちらなのかを確認してね。

ボクのCamS3 5MPは新しいバージョンだったよ。

3. ESP32-camのモジュール入れ替え
この手順は手順2でOld Versionと表示された場合のみ実施するよ。New Versionならスキップしてね。また上のM5Stack公式のドキュメントを開いて「2. 旧版ハードウェア互換処理」という箇所を参考にBoard Managerからesp32をダウングレードして、同じ箇所に貼り付けられたzipからモジュールを取り出して指定の場所にコピーしてね。

CamS3 5MPから画像をキャプチャしてみよう

準備はOKかな?ここからはCamS3 5MPのカメラから画像をキャプチャしてmicroSDカードに保存してみるよ。CamS3 5MPはボタンが付いて無いから、G0をGNDにジャンパワイヤーでショートさせた時にカメラから画像をキャプチャしてmicroSDに保存するようにしてみるよ。

以下にサンプルコードを載せておくから、コピペしてCamS3 5MPに書き込んでみてね。

ビルド時の設定:

  • Tools > Board > esp32 > M5UnitCAMS3
  • Tools > USB CDC On Boot: "Enabled"
  • Tools > PSRAM: "OPI PSRAM"
// CamS3-5MPCamera
// Short G0 to GND triggers taking a photo and save captured image to the microSD card.
// Board: esp32 by Espressif v3.3.0
// ** No need to install esp32-camera library. It's included in Arduino-esp32.**
// 
// Before the development, check the following document and identify your device version.
// https://docs.m5stack.com/ja/arduino/m5unitcams3_5mp/program
// https://docs.m5stack.com/en/arduino/m5unitcams3_5mp/program
//
// Check options if correct:
//  - Tools > Board > esp32 > M5UnitCAMS3
//  - Tools > USB CDC On Boot: "Enabled"
//  - Tools > PSRAM: "OPI PSRAM" 
//

#include <Arduino.h>
#include "esp_camera.h"

// For debug
static const char *TAG = "CamS3-5MP demo";

// For SD card
#include <SPI.h>
#include <SD.h>

// Pin setup for SD card
enum {
    sd_ss = 9,
    sd_mosi = 38,
    sd_miso = 40,
    sd_sck = 39
};

// For trigger pin
#define PIN_TRIGGER 0

// For CamS3-5MP
#define CAM_PIN_PWDN -1  //power down is not used
#define CAM_PIN_RESET 21 //software reset will be performed
#define CAM_PIN_XCLK 11
#define CAM_PIN_SIOD 17
#define CAM_PIN_SIOC 41

#define CAM_PIN_D7 13
#define CAM_PIN_D6 4
#define CAM_PIN_D5 10
#define CAM_PIN_D4 5
#define CAM_PIN_D3 7
#define CAM_PIN_D2 16
#define CAM_PIN_D1 15
#define CAM_PIN_D0 6
#define CAM_PIN_VSYNC 42
#define CAM_PIN_HREF 18
#define CAM_PIN_PCLK 12

// Camera config
static camera_config_t camera_config = {
    .pin_pwdn = CAM_PIN_PWDN,
    .pin_reset = CAM_PIN_RESET,
    .pin_xclk = CAM_PIN_XCLK,
    .pin_sccb_sda = CAM_PIN_SIOD,
    .pin_sccb_scl = CAM_PIN_SIOC,

    .pin_d7 = CAM_PIN_D7,
    .pin_d6 = CAM_PIN_D6,
    .pin_d5 = CAM_PIN_D5,
    .pin_d4 = CAM_PIN_D4,
    .pin_d3 = CAM_PIN_D3,
    .pin_d2 = CAM_PIN_D2,
    .pin_d1 = CAM_PIN_D1,
    .pin_d0 = CAM_PIN_D0,
    .pin_vsync = CAM_PIN_VSYNC,
    .pin_href = CAM_PIN_HREF,
    .pin_pclk = CAM_PIN_PCLK,

    //XCLK 20MHz or 10MHz for OV2640 double FPS (Experimental)
    .xclk_freq_hz = 20000000,
    .ledc_timer = LEDC_TIMER_0,
    .ledc_channel = LEDC_CHANNEL_0,

    .pixel_format = PIXFORMAT_JPEG, //YUV422,GRAYSCALE,RGB565,JPEG
    .frame_size = FRAMESIZE_5MP,    //QQVGA-UXGA, For ESP32, do not use sizes above QVGA when not JPEG. The performance of the ESP32-S series has improved a lot, but JPEG mode always gives better frame rates.

    .jpeg_quality = 10, //0-63, for OV series camera sensors, lower number means higher quality
    .fb_count = 1,       //When jpeg mode is used, if fb_count more than one, the driver will work in continuous mode.
    .grab_mode = CAMERA_GRAB_LATEST,
};

// Init Camera
static esp_err_t init_camera(void)
{
    //initialize the camera
    esp_err_t err = esp_camera_init(&camera_config);
    if (err != ESP_OK)
    {
        ESP_LOGE(TAG, "Camera Init Failed");
        return err;
    }

    return ESP_OK;
}

// Function to save image to SD card
static int pictureNumber = 0; // Counter for image filenames
bool save_image_to_sd(camera_fb_t *fb)
{
    // Create unique filename
    char filename[32];
    snprintf(filename, sizeof(filename), "/image_%04d.jpg", pictureNumber++);

    // Open file for writing
    File file = SD.open(filename, FILE_WRITE);
    if (!file) {
        ESP_LOGE(TAG, "Failed to open file %s for writing", filename);
        return false;
    }

    // Write image data
    file.write(fb->buf, fb->len);
    file.close();
    
    ESP_LOGI(TAG, "Saved image: %s, Size: %zu bytes", filename, fb->len);
    return true;
}

void setup() {
  Serial.begin(115200);

  // Setup trigger pin
  pinMode(PIN_TRIGGER, INPUT_PULLUP);

  // Initialize SD card
  SPI.end();
  SPI.begin(sd_sck, sd_miso, sd_mosi, sd_ss);
  if(!SD.begin(sd_ss,SPI,24000000)){
    Serial.println("An Error has occurred while mounting SD card");
    delay(3000);
    ESP.restart();
  }
  
  // Initialize Camera
  while(ESP_OK != init_camera()) {
    delay(1000);
  }
  ESP_LOGI(TAG, "Camera Init Succeeded");
}

void loop() {
  // Check if trigger pin is LOW
  if (digitalRead(PIN_TRIGGER) == LOW) {
      ESP_LOGI(TAG, "Trigger activated, taking picture...");
      
      // Capture image
      camera_fb_t *pic = esp_camera_fb_get();
      if (!pic) {
          ESP_LOGE(TAG, "Camera capture failed");
          delay(1000);
          return;
      }

      // Save to SD card
      if (save_image_to_sd(pic)) {
          ESP_LOGI(TAG, "Picture saved successfully");
      } else {
          ESP_LOGE(TAG, "Failed to save picture");
      }

      // Return frame buffer
      esp_camera_fb_return(pic);

      // Debounce delay to prevent multiple captures
      delay(500);
      
      // Wait until trigger is released
      while (digitalRead(PIN_TRIGGER) == LOW) {
          delay(10);
      }
  }
  delay(100);
}

ソースコードのポイントを説明しておくよ。

.pixel_format = PIXFORMAT_JPEG
キャプチャした画像の形式を指定しているよ。今回はJPEG形式を指定しているよ。この設定でキャプチャされたデータはそのままファイルに保存することで、JPEGファイルとして開くことができるよ。

.jpeg_quality = 10
JPEG画像の品質を変更することができるよ。

.frame_size = FRAMESIZE_5MP
キャプチャする画像の解像度を指定しているよ。5MPはCamS3 5MPの最大解像度2592x1944になるよ。指定可能な解像度はESP32-camの以下のヘッダで定義されているよ。

https://github.com/espressif/esp32-camera/blob/master/driver/include/sensor.h

動作確認

さっきのソースコードをArduino IDEでビルドしてCamS3 5MPに書き込んだら動作確認をしてみるよ。microSDカードをCamS3 5MPに刺して、電源ON、カメラの初期化に成功していたらシリアルコンソールにCamera Init Succeededと出力されるよ。初期化が成功していたら、CamS3 5MPに付属のジャンパワイヤーでG0とGNDをショートさせてみてね。

シリアルコンソールにPicture saved successfullyと出力されていたらmicroSDカードにJPEG画像が保存されているよ。PCで画像を読み込んでみてね。

まとめ

M5StackのWi-FiカメラユニットCamS3の後継品であるCamS3 5MPの使い方を説明してきたよ。CamS3 5MPはCamS3のソフトと互換性は無いんだけど、カメラの解像度が5MPにアップしていて、CamS3よりも大きな画像をキャプチャすることができるようになっているよ。

今回は画像のキャプチャ方法について説明したけど、これを応用して映像も録画できるはずだから、ぜひ挑戦してみてね。ESP32の低消費電力を利用して電池だけで定点観測したり、Wi-Fiに繋いで映像を遠隔で確認したり、色々と応用ができそうだね。この記事が役に立ったらバッジとX(@nananauno)のフォローもよろしくね!じゃあ、またね!

Discussion