新しいものづくりがわかるメディア

RSS


月イチM5工作

月イチM5工作——CamS3でお手軽Wi-Fiカメラ&タイムラプス撮影を実践する

液晶ディスプレイを搭載し、ネットワーク接続の容易さが特徴のマイコンボード、M5Stack。2017年に中国・深圳(しんせん)でリリースされてからラインアップは増え続け、「1週間に一度は新製品がリリースされる」とまで言われる開発速度も大きな魅力です。電子工作やプロトタイピングの選択肢が増える喜びの一方で、全ての新製品に触れ続けるのはなかなか難しいかもしれません。

この連載ではM5Stackの国内販売をサポートするスイッチサイエンス協力のもと、次々とリリースされるM5Stackシリーズの新製品に触れ、その使い心地を確かめながら、特徴を生かした工作を実践していきます。

2000円台の「CamS3 Wi-Fiカメラユニット」

今回扱うアイテムは「M5Stack用CamS3 Wi-Fiカメラユニット (OV2640)」。国内では2024年2月5日に発売されました。ESP32S3モジュールをベースにしたカメラで、40×24×11mmというすし一貫ほどの小ぶりなサイズが特徴。Wi-Fi対応のカメラとして、リモートでの監視やタイムラプス撮影が想定されています。

photo
photo

2024年5月17日時点において、スイッチサイエンスでの販売価格は2530円(税込)。CamS3本体のほか、書き込み用のGrove2USB-Cアダプターなどが付属しており、給電さえすればすぐに利用開始できるようになっています。

あっという間の接続&デモンストレーション

photo

それでは早速使っていきましょう。CamS3本体のコネクターにケーブルを接続して給電すると、青色のLEDが点灯し、PCやスマートフォンのWi-Fiネットワークに「UnitCamS3-WiFi」が表示されました。

「UnitCamS3-Wifi」に接続した状態でWebブラウザーから「http://192.168.4.1/」にアクセスすると、CamS3のユーザーデモ画面が表示されます。

photo

最上段「Camera」メニューの「Capture」を押すと静止画が、「Stream」を押すとリアルタイムのプレビューが表示されます。

Captureを押すたび静止画が撮影される。 Captureを押すたび静止画が撮影される。
Streamの映像はガタつきも少ない。 Streamの映像はガタつきも少ない。

その他「Mic」メニューではCamS3の内蔵マイクが4秒間の音声データを録音し、ブラウザーで再生できるほか、「LED」メニューから本体LEDのON/OFFも制御が可能です。

ここまで一連のテストに要した時間は、開封から15分程度。Wi-Fi環境があればあっという間に検証できる手軽さに驚かされました。

Image Poster機能で撮影&遠隔モニタリング

CamS3自体をWi-Fiネットワークと接続すれば、撮影した写真を遠隔地からモニタリングすることもできます。先ほどと同様にユーザーデモ画面を開き、今度は画面下部にある「Image Poster」メニューから「Setup」を選択しましょう。

photo
photo

CamS3を接続するWi-FiのSSIDとパスワード、CamS3のニックネーム、撮影のインターバル(5秒、10秒、30秒、1分、5分、10分、30分から選択可能)、そしてタイムゾーンを設定します。

photo

すると、設定に応じて撮影された画像が表示されるURLとQRコードが発行されます。これはM5Stackの提供するIoTクラウドデータストレージサービス「EzData」を活用したもので、利用にユーザー登録などは不要。PCでもモバイルでも、指定されたURLにアクセスすれば、撮影された最新の画像が表示されます。

発行されたURLにアップロードされた筆者の画像。右上に撮影時間も記録されている。 発行されたURLにアップロードされた筆者の画像。右上に撮影時間も記録されている。
インターバルごとに更新されたものをキャプチャーし並べてみた。 インターバルごとに更新されたものをキャプチャーし並べてみた。

このURLにはどこからでもアクセスできるため、CamS3と離れた場所でも周辺の様子を確認できます。リアルタイムとまではいきませんが、その場所に異常がないかなどはチェックできそうですね。

なお、Image Posterモードの実行中に再設定を行うためには、Cam3を再起動してから10秒以内に「UnitCamS3-WiFi」に接続し、再びユーザーでも画面を開く必要があります。最初は戸惑うかもしれないので注意しましょう。

遠隔監視&ローカル保存を並行するデバイスを作る

筆者は自宅から少し離れた場所でファブ施設を運営しているのですが、たまに郵便物が扉の隙間に挟まれていたりするので、その様子のチェックにCamS3が役立ちそうです。また、日中どれくらいの人通りがあるのかも気になるので、後から写真で確認できるといいなと思い、こんな作品を作ってみました。

photo

エジプト神話的な目を模したプレートに、CamS3ユニットを取り付け。ImagePoster機能でリアルタイムにモニタリングできるほか、microSDカードにも撮影された写真が保存されていく見守りデバイスです。

デフォルトで書き込まれたプログラムだけでもほぼ十分なのですが、microSDカードへの保存との並行利用に工夫が必要だったので、その内容をお伝えします。

microSDカードの確認

まず記録用のmicroSDカードを準備しましょう。手元に使用済みのmicroSDカードがあったので、macOS Sonoma 14.4.1のディスクユーティリティからフォーマットを行いました。microSDカードをCamS3に差し込んでから起動し、ユーザーデモ画面に接続したのち「SD Card」の「Update」を押すと状態を確認できます。

microSDカードは半分ほどはみ出す。 microSDカードは半分ほどはみ出す。
ユーザーデモ画面でSDカードの状態を確認。 ユーザーデモ画面でSDカードの状態を確認。

筆者の場合、「exFAT」でフォーマットした場合「SD Card Not Valid」と表示されてしまいましたが、「MS-DOS(FAT)」で実行すると無事認識されました。お使いのPCやmicroSDカードの仕様に合わせて調整してみてください。

Platform IOからプログラムを更新する

CamS3にデフォルトで書き込まれているファームウェアはGitHubで公開されているので、丸ごとダウンロードしておきましょう。更新や書き込みにはPlatform IOというIDEを利用するため、Visual Studio Codeの拡張パッケージとしてインストールしました。

※以降のプログラムはNANANA氏による「QUICK start: M5Stack CamS3 Unit」を参考にしています。

Platform IO IDE はVisual Studio CodeのExtensionsからインストールできる。 Platform IO IDE はVisual Studio CodeのExtensionsからインストールできる。

platform.iniの更新

CAMS3はesp32s3boxボード、Arduinoフレームワークとして定義されている。 CAMS3はesp32s3boxボード、Arduinoフレームワークとして定義されている。

Platform IOでデフォルトのコードを読み込んだら、firmware > platform.iniを開き、下記のように太字部分を変更、追記します。

[env:m5stack-unitcams3]
platform = espressif32@6.4.0
board = esp32s3box
framework = arduino

board_build.f_cpu = 240000000L
board_build.f_flash = 80000000L
board_build.flash_mode = qio
board_build.flash_size = 16MB

build_flags =
    -DCORE_DEBUG_LEVEL=3
    -DBOARD_HAS_PSRAM
    -DCONFIG_ARDUINO_LOOP_STACK_SIZE=16384
    -DCONFIG_SPIRAM_MODE_OCT=y
    -I./src/mooncake/src/spdlog/include
    -I./src/mooncake/src/
        -DARDUINO_USB_CDC_ON_BOOT=1 ; 0を1に変更
        -DARDUINO_USB_MODE=1 ; 0を1に変更

board_build.partitions = custom.csv
board_build.filesystem = littlefs

upload_protocol = esptool ; 追記

monitor_filters = esp32_exception_decoder
monitor_speed = 115200

lib_deps = 
    bblanchon/ArduinoJson @ ~6.21.3
    yoursunny/esp32cam @ ^0.0.20240110 ; 追記

platform.iniより一部抜粋。

  • 「-DARDUINO_USB_CDC_ON_BOOT=1」「-DARDUINO_USB_MODE=1」へと書き換え(シリアル通信を行うため)
  • 「upload_protocol = esptool」を追記(LittleFSのイメージをフラッシュに書き込むため)
  • 「yoursunny/esp32cam @ ^0.0.20240110」を追記(esp32camのライブラリを使用するため)
 

main.cppの更新

#include <mooncake.h>
#include <Arduino.h>
#include "hal/hal.h"
#include "servers/servers.h"


void setup() 
{
    // Init 
    HAL::hal::GetHal()->init();

    // Start server 
    if (HAL::hal::GetHal()->getConfig().start_poster == "yes")
        UserDemoServers::start_poster_server();
    else if (HAL::hal::GetHal()->getConfig().start_shooter == "yes")
        UserDemoServers::start_shooter_server();
    else 
        UserDemoServers::start_ap_server();
}


void loop() 
{
    delay(5000);
}

main.cppより一部抜粋。

srcディレクトリにあるmain.cppの中身は上記の通り。PosterImageモードなどが設定されていない場合、特にメインループでは何も実行されないようになっています。esp32camのライブラリを活用して、microSDカードへの画像保存を行いましょう。

#include <esp32cam.h> // esp32camのライブラリを追加

// esp32camのピン割り当て
esp32cam::Resolution initialResolution;
constexpr esp32cam::Pins UnitCamS3{
   D0 : 6,
   D1 : 15,
   D2 : 16,
   D3 : 7,
   D4 : 5,
   D5 : 10,
   D6 : 4,
   D7 : 13,
   XCLK : 11,
   PCLK : 12,
   VSYNC : 42,
   HREF : 18,
   SDA : 17,
   SCL : 41,
   RESET : 21,
   PWDN : -1,
};

セットアップとメインループの外でesp32camのライブラリを読み込み、camS3のピンを割り当てていきます。

void loop()
{
   delay(5000);

   // 画像データを取得
   auto frame = esp32cam::capture();
   uint8_t *image_data = frame->data();
   size_t image_size = frame->size();

   // SDカードに画像を保存する処理
   if (HAL::hal::GetHal()->isSdCardValid())
       if (HAL::hal::GetHal()->saveImage(image_data, image_size))
           Serial.println("Image saved successfully!");
       else
           Serial.println("Failed to save Image.");
   else
       Serial.println("SD card is invalid.");
}

メインループの中で5秒に一度、esp32camから画像をキャプチャーし、SDカードに保存する処理を追加しました。SDカードが有効である場合、src > sd > hal_sd.cpp内で定義されたsaveImage関数を利用して、連番を付けて画像が保存されるように設定されています。

書き込みと動作確認

photo

CamS3とPCを接続し、Platform IO のUploadからプログラムを書き込みます。製品ページでは「Grove2USB-C を使用してダウンロードする場合は、通電前に付属のオス-オス間ジャンパー線を使用してメスヘッダーのG0ピンとGNDピンを短絡し、ダウンロードモードに移行します。その後、Grove2USB-Cに接続してダウンロードを行います」と表記がありますが、短絡を行わずとも書き込みできました。環境によって異なるのかもしれません。

photo

プログラムを書き込むと、SDカードの /captured/ディレクトリに画像が連番で保存されていく様子がシリアルモニターに表示されました。ある程度時間が経ったら、SDカードを取り出し中身を見てみましょう。

photo

おぉ、無事に筆者がユラユラしている様子が記録されていますね! 静止画をストックしておいて、後から見返すような使い方ができるようになりました。タイムラプス動画のように編集しても面白そうですね。

ImagePosterとローカル保存の併用は要対策

前述のプログラムを書き込んだ状態でImagePosterを開始すると、次のようなエラーメッセージが表示され、SDカードへの画像保存に失敗するようになりました。

photo

どうやらImagePosterを始める際のSDカードの初期化あたりで失敗しているようです。今回の用途ではローカルに保存さえされればいいので、src > apis > poster > api_poster.cpp の43-51行にあるSDカードに関するコードをコメントアウトすることで対応できました。

struct PostCallback_SaveSdCard_t : public PostCallback_t
{
   // 下記をコメントアウト
   // void imageCaptured(camera_fb_t* frameBuffer) override
   // {
   //     if (HAL::hal::GetHal()->isSdCardValid())
   //         HAL::hal::GetHal()->saveImage(frameBuffer->buf, frameBuffer->len);
   // }
};

api_poster.cppより一部抜粋。

変更を加えたプログラムはこちらのURLにアップロードしたので、気になる方は確認してみてください。

コンパクトな見守り装置ができた!

photo
photo

プログラムが完成したので、最後に簡単な外装を作ってあげましょう。CamS3には背面にLEGOブロック用のマウントがあるので、その形を生かしたマウントを制作。エジプト神話をモチーフにした、いかにも見守ってくれそうな意匠を施しました。夕方から夜にかけて電源をONにしておくと、次のような成果が得られました。

ImagePoster機能でオンラインモニタリング。 ImagePoster機能でオンラインモニタリング。
SDカードにも静止画が保存されていく。 SDカードにも静止画が保存されていく。
静止画を並べたタイムラプス。途中で誰かが前を通りがかっている様子もうかがえる。 静止画を並べたタイムラプス。途中で誰かが前を通りがかっている様子もうかがえる。

こうして、遠隔モニタリングとローカルの画像保存を並行した見守りデバイスが完成しました! 世の中には多くのネットワークカメラが市販されていますが、「M5Stack用CamS3 Wi-Fiカメラユニット(OV2640)」は自分の用途に応じてカスタムできることが魅力の一つ。コンパクトなサイズ感も相まって、いろいろな用途に使えそうです。ぜひ皆さんも、電子工作の選択肢に加えてみてください。

それでは、また次回!

取材協力:スイッチサイエンス

おすすめ記事

 

コメント

ニュース

編集部のおすすめ

連載・シリーズ

注目のキーワード

もっと見る