Masao_Tsukamoto DigiKey Employee
概要
M5StackのUnit CamS3-5MP(メーカー品番:U174-B、DigiKey品番:2221-U174-B-ND)は32ビットMCU( ESP32-S3 )を内蔵し、最大500万画素の超小型・高精細のIoTインテリジェントカメラです。応用分野はつぎのとおりです。
- セキュリティ分野:防犯カメラやタイムラプス
- 情報収集分野:物流や交通量の定点観測
- 産業分野:生産ラインの監視、生産ロボットへの組み込み
- 教育分野:プログラミング技術の習得、ロボット教材に活用
図1: Unit CamS3-5MPを壁に取り付け
この記事では、応用事例を中心に説明します。工場出荷時にプリインストールされているファームウェアの機能とセットアップについてはUnit CamS3-5MPの始め方/セットアップ手順の紹介をご覧ください。
機能・特長
Unit CamS3-5MPはWi-Fi通信機能を備え、エッジ処理を可能とし、ホスト側の負担を軽減する高精細IoTカメラです。仕様・付属品についてはUnit CamS3-5MPを参照してください。
- カメラモジュールPY260
- 最大2592 × 1944ピクセル、アスクペクト比4:3
- カメラフォーカス:単焦点(焦点距離0.6m)
- 対角視野角:DFoV 88°(比較的広角)
- 画像出力フォーマット:JPEG静止画
- MCU(ESP32-S3-WROOM-1-N16R8):エッジ処理とWi-Fi通信が可能
- PDMマイク(MSM1261D4030HCPM):異常音(騒音、破裂音)の検知や音声認識
- インターフェース
- マイクロSDカードスロット:画像の保存、タイムラプスへの応用が可能
- HY2.0-4P Grove端子:Grove2USB-Cアダプタボード経由でパソコンに接続
プロジェクト活用例
UnitCamS3-5MPのプロジェクト活用例として、和歌山県立桐蔭高等学校の文化祭での「混雑状況自動取得プロジェクト」を紹介します。各会場の混雑状況の把握を、Unit CamS3-5MPを使用して自動で集計を行い、モニタで可視化するものです。具体的には、各会場にUnit CamS3-5MPを配置し、所定の時間間隔で撮影を行い、撮影した画像をWi-Fi経由でサーバにアップロードします。サーバ側では画像をPythonでAI処理して人数を推計し、混雑状況を自動的に把握し、WEBページに表示します。この記事では、鍵となるUnit CamS3-5MPの画像撮影、圧縮処理およびサーバへのアップロード処理のプログラムブロックにのみ焦点を当てて説明します。また、サーバでのAI処理およびそれ以降のプロセスには言及していません。なお、この記事に掲載しているコードのスニペットおよびノウハウは、同校から提供して頂いたものです。
Arduino IDEの設定
この記事では、プログラム開発をArduino IDEで行います。以下の設定はUnit CamS3-5MP Arduino サンプルプログラムのコンパイルと書き込み、およびUnit CamS3-5MP 使用マニュアルを参照してください。
- Arduino IDEを開きます。「ツール > ボード > ボードマネージャ」を選択し、検索欄に「esp32」と入力します。「esp32 by Espressif Systems」が表示されたら、バージョン3.1.0を選択し、「インストール」をクリックします(図2)。
図2: ボードマネージャのesp32 by Espressif Systems
- 「ファイル > 基本設定 > 追加のボードマネージャのURL」に以下のURLを入力し、「OK」をクリックします(複数のURLがある場合には、右端のアイコンでURLを選択します)(図3)。https://espressif.github.io/arduino-esp32/package_esp32_index.json
図3:「追加のボードマネージャのURL」に、Espressifのボード情報(.json)のURLを入力
注: Unit CamS3-5MPには2つのバージョンがあります。バージョンの確認はハードウェアバージョンの確認で行ってください。旧バージョンの場合、2. 旧版ハードウェア互換処理が必要です(新バージョンの場合はこの手順をスキップしてください)。
① Unit CamS3-5MP Arduino Program Compilation & Uploadをダウンロードし、解凍しま
す。libespressif__esp32-camera.aが得られます。
② C:Users<user名>\AppData\Local\Arduino15\packages\esp32\tools\esp32-arduino-libs\idf-
release_v5.3-083aad99-v2\esp32s3\lib\のディレクトリにあるlibespressif__esp32-
を探します(ファイル名は同じです)。
③ 上記の②のファイル(.a)を削除し、①のファイル(.a)に差し替えます。
図4 :旧バージョンの場合、libespressif__esp32-camera.aを差し替えます。
- 「ツール > ボード > esp32」を開き、「ESP32S3 Dev Module」を選択します。
- 「ツール > ポート」を開き、「COM」ポートを選びます。COMポート番号は「デバイスマネージャ > ポート(COMとLPT)」で確認してください。
- 「ツール > USB CDC On Boot」を「Enabled」に設定します。
- 「ツール > PSRAM」を「OPI PSRAM」に設定します。
- 「ツール > シリアルモニタ」に設定します。
プログラム開発
プログラム開発はパソコン(Arduino IDE)で行います。手順は以下のとおりです。
- Unit CamS3-5MPの背面左のヘッダピン(メス)のG0とGNDをジャンパ線でショートし、パソコンに接続にします(図5)。ダウンロードモード(書き込みモード)となります。USBケーブル(Type-A to Type-C)は付属されていませんので別途準備してください 。
- Arduino IDEでプログラム(C++)を作成します。スケッチ(.ino)をArduino IDE でコンパイルします。エラーが出れば修正します。
- コンパイルが完了すれば、Arduino IDEからUnit CamS3-5MPにバイナリファイルを書き込みます。
- Arduino IDEを閉じ、ハードウェアを安全に取り外す処理を行い、Unit CamS3-5MPをパソコンから取り外します。G0とGNDのジャンパ線を取り外し、再びパソコンに接続し、Arduino IDEを開きます。
- エラーがなければ、Unit CamS3-5MPは電源(5V DC)が供給されている限り、スタンドアロンで動作します。エラーが出た場合はデバッグを行います。
図5: ダウンロードモード(書き込みモード)の設定
ピンレイアウトの定義
ピンレイアウトは、ハードウェア(M5Stack公式Unit CamS3-5MPの回路図)と一致させることが必要です。ピンレイアウトに間違いがあれば、損傷する可能性があります。図6は、UnitCamS3-5MPのピンレイアウトを定義しているヘッダファイル(.h)です。
// UnitCamS3-5MPのピンレイアウトの定義
#define PWDN_GPIO_NUM -1 // 未使用(GNDに接続)
#define RESET_GPIO_NUM 21 // カメラリセット
#define XCLK_GPIO_NUM 11 // クロック出力
#define SIOD_GPIO_NUM 17 // SCCBデータライン
#define SIOC_GPIO_NUM 41 // SCCBクロックライン
// D0~D7(8ビット)は画像データバス。RGB各色に8ビットの深度。約1677万色の色再現
#define Y9_GPIO_NUM 13 // D7
#define Y8_GPIO_NUM 4 // D6
#define Y7_GPIO_NUM 10 // D5
#define Y6_GPIO_NUM 5 // D4
#define Y5_GPIO_NUM 7 // D3
#define Y4_GPIO_NUM 16 // D2
#define Y3_GPIO_NUM 15 // D1
#define Y2_GPIO_NUM 6 // D0
#define VSYNC_GPIO_NUM 42 // 垂直同期信号
#define HREF_GPIO_NUM 18 // 水平同期信号
#define PCLK_GPIO_NUM 12 // ピクセルクロック
#define LED_GPIO_NUM 14 // 動作確認用LED制御
図6: UnitCamS3-5MPのピンレイアウトの定義
画像データの取得
ここではイメージセンサからの画像取得を行います。図7はloop()のコードです。プリインストールファームウェアではVGA(640 × 480)の解像度ですが、解像度を上げてSVGA(800 × 600)にしています。
void loop() {
// 画像を取得
camera_fb_t *fb = esp_camera_fb_get(); // esp_camera_fb_get()は画像取得の関数
// camera_fb_tはesp_camera.hで定義されている構造体
// この構造体のメンバにはlen(サイズ)、width(幅)、height(高さ)、format(e.g. JPEG)など
if (!fb) { // fbがNULL(画像取得失敗)の場合の処理
Serial.println("画像取得失敗");
delay(10000); // 画像取得に失敗したら10秒待つ
return; // loop()処理を中断
}else{
Serial.printf("画像取得成功 サイズ: %d バイト\n", fb->len); // fbは構造体へのポインタ
//->lenは構造体のメンバにアクセス
sendJpeg(fb); // 取得した画像を送信する関数。この関数は関数領域で定義されている。
}
// フレームバッファ開放
esp_camera_fb_return(fb); // フレームバッファを解放
// delay(10000); // タイムインターバル調整用(現在は無効)
}
図7: イメージセンサからの画像取得
Wi-Fi経由でサーバにアップロード
ここでは、取得した画像データを指定のサーバ(upload_url)にアップロードを行います。図8のコードはJPEG 画像をupload_urlにHTTP POSTで送信するsendJpeg()関数です。この関数は、図7のloop()の中でsendJpeg(fb)の形で呼び出されます。
bool sendJpeg(camera_fb_t* fb) {
if (!fb || fb->format != PIXFORMAT_JPEG) { // JPEG形式でない場合は送信不可
Serial.println("Invalid frame buffer");
return false;
}
HTTPClient http; // HTTPClientとはESP32に含まれるクラス
http.begin(upload_url); // HTTP接続を初期化し、アップロード先URLを指定
http.addHeader("Content-Type", "image/jpeg"); // JPEG形式で送信
int httpResponseCode = http.POST(fb->buf, fb->len);
// フレームバッファの内容をPOSTメソッドで送信
// PUTは上書き、POSTは処理の規定なし
if (httpResponseCode > 0) {
String response = http.getString(); // サーバからの応答を取得
Serial.println("Server Response:");
Serial.println(response);
} else {
Serial.printf("POST failed, error: %s\n",
http.errorToString(httpResponseCode).c_str());
}
http.end(); // 接続終了
return httpResponseCode == 200; // HTTPステータスコードが200(成功)ならtrueを返す。
}
図8: sendJpeg()関数の定義
関連情報
- M5Stack公式Unit CamS3-5MP
- M5Stack公式Unit CamS3/Unit CamS3-5MPスタートガイド
- M5Stack公式Grove to USBC
- MPUのデータシート
- PDMマイクのデータシート
- Unit CamS3-5MPの始め方/セットアップ手順の紹介
まとめ
Unit CamS3-5MPはESP32-S3 MCUを搭載した超小型インテリジェントIoT高精細カメラです。この記事ではひとつの応用事例について説明し、MCU(ESP32-S3)のプログラム開発について説明しました。Unit CamS3-5MPはWi-Fiによる通信機能を備えていますので、ユーザー独自のソフトウェア開発によりさまざまなエッジ処理が可能となります。それにより、超小型インテリジェントIoTカメラとしてのアプリケーションが広がります。