OV2640のJPEG出力でM5CameraとM5StackのWiFi動画ストリーミング実験

M5CameraのOV2640からJPEG出力させ、M5StackへWiFi動画ストリーミングする実験。高フレームレートです。 M5Stack

こんばんは。

今回こそホントすごいですよ!
長い間取り組んでいた、M5Camera のイメージセンサOV2640からJPEG出力を検知できて、DMAで画像を抽出できて、しかもM5StackへWiFi転送して、高フレームレートのMotion JPEG (MJPEG)動画ストリーミングができるようになりました。
しかも、フレームサイズやJPEG画質をリアルタイムで切り替えることができたんです。
当然、露出もリアルタイムで切り替えられます。

スポンサーリンク

そして更に、OV2640のPCLK分周をM5Stackのボタンで切り替えられるようにしてみました。
まずは、以下の動画をご覧ください。

やったぜ!!!
って感じです。
これ、スゴいと思いませんか?!
今までのビットマップ(BMP)画像のストリーミングとは桁違いに高フレームレートです。
しかも、以前の 200 x 148 pixelよりも画角が大きくなり、240 x 176 pixel までできるようになりました。
PSRAMを使わず、フラッシュ設定もデフォルトのままでいけました。

この動画の以下の時間のところで、いろいろとチェックしています。

00:55~ 自動露出設定チェック
02:19~ フレームサイズ(画角)変更チェック
04:28~ PCLK クロック分周チェック
05:44~ フレームレートチェック
09:36~ JPEG画質(Quality scale factor) チェック

この中でも個人的なハイライトは、フレームサイズ(画角)をリアルタイムで変更できるようになった点です。
M5StackのLCDで制御しているのではなく、OV2640を制御してJPEGフレームサイズを決めているところがミソです。

そして、JPEG画質を変えられるので、通信状態によって画質を落とせばある程度ストリーミングが安定します。

更に、OV2640へのメインクロック周波数を下げずに、PCLKを分周してパラレルデータのパルス幅を変更することができるようになりました。
そして、M5Stack側のボタンでPCLK分周を切り替えられるようにしたことで、オシロスコープやロジックアナライザの実験が格段に捗り、さらに通信状態やデバイスの状況によってPCLK周波数を変えることができるようになりました。
自分的には今までにない取り組みがてんこ盛りです。

因みに、測定用回路として、ESP32-DevKitC と、Arducam B0011 (OV2640 モジュール)を使って実験もしてみました。
以下の動画をご覧ください。

やはりブレッドボード上では接触不良が多く、良く通信が途切れますが、概ね良好に動作しました。

そして、当然、M5Stackだけではなく、スマートフォンのブラウザ表示に切り替えて動画ストリーミングすることもできます。
以下の動画もご覧ください。

これは25fpsの速度が出ています。
メチャメチャスムースですね。
さすがブラウザです。

今回は以前のこちらの記事のように、ストップボタンを押さないでもハックできるようにはしませんでした。
ちゃんと、ストップボタンを押してからでないと切り替えられません。
これが正常ですね。
操作は多少面倒ですが、しっかり画角や画質が変えられていますね。

これで、M5CameraやOV2640の実験としては大満足です。

今まで、ビットマップデータのストリーミングしかやって来なかったのですが、さすがにWiFi通信では限界を感じたので、JPEG通信に挑戦してみたのです。
そしたら、こんなにも軽くなって速くなったんです。
もうビットマップには戻れませんね。

今回の大きなポイントは、M5Cameraのイメージセンサ OV2640 のJPEG出力モードを使ったことです。
実は、Arduino core for the ESP32 のサンプルスケッチ CameraWebServer では既にJPEG出力を扱っていますが、その仕組みはとっても難解で、私の様なアマチュア自作波には応用できなかなかったんです。

でも、今回、オシロスコープやロジックアナライザを使ったおかげで、ようやくある程度解明できたので、ライブラリを解体して、自分なりに意図通りに再構成できるようになりました。

というわけで、esp32-cameraライブラリからは数えきれないほどの多くを学ばせて頂きました。
このようなライブラリをオープンソースにしていただき、Espressif Systemsの開発者の方々に感謝したいと思います。
ありがとうございました。
m(_ _)m

では、これから説明していきますが、例のごとく、私は独学素人アマチュアです。
以下、間違えていたり、勘違いしていたり、想像で書いていることもあります。
もし、何かお気づきの点がありましたら、コメント投稿でご連絡いただけると助かります。

    【目次】

  1. 事前準備
  2. 送信側 M5Camera のスケッチ(プログラムソースコード)
  3. 受信側 M5Stack のスケッチ(プログラムソースコード)
  4. 操作方法
  5. OV2640のJPEG出力は、esp32-cameraライブラリやサンプルスケッチCameraWebServerを読み解くしかなかった
  6. VSYNC(垂直同期)信号の割り込み初期化はネガティブエッジに設定
  7. レジスタ直叩きdigitalWrite関数にIRAM_ATTR属性を付け、VSYNCやDMA,I2S割り込みのタイミングをロジアナやオシロで視覚化してみた
  8. イメージセンサOV2640からのJPEG出力を調べる
  9. DMA, FIFOメモリ初期化と自己参照構造体について
  10. DMAバッファサイズの謎
  11. PCLK clock divide (分周)について
  12. DMAによるI2S割り込みタイミングと、FIFOメモリ読み書きのタイミングをオシロで可視化してみた
  13. ESP32 のWiFiデータ送信間隔をオシロで可視化してみた
  14. DMA, FIFOメモリからの読み出しとWiFi通信はタスクを分けるべきか?
  15. JPEG開始マーカー FFD8 と終了マーカー FFD9 の検出方法
  16. Motion JPEG (MJPEG)送信データのchunk化について
  17. フレームサイズ(画角)設定
  18. 受信側 M5Stack のプログラミング
  19. DMA はFreeRTOS でキュー待ちした方が良い気がする
  20. まとめ

事前準備

使ったもの

M5Camera

Espressif Systems製のPSRAM付きESP32-WROVER搭載、OmniVision製イメージセンサOV2640を搭載し、GROVE端子も付いた、技適取得済みのM5Stack社製WiFiカメラモジュールです。
スイッチサイエンスさんで販売しています。

https://www.switch-science.com/catalog/5207/

M5Stack

Espressif Systems製のWiFi & BluetoothマイコンESP32を搭載し、LCDディスプレイ、micro SDカードスロット、ボタンスイッチ、スピーカー、GROVE端子付きで、M5Stack社製の技適取得済み全部入りマイコンモジュールです。
M5Stack Basic でも Gray でも良いと思います。

(追記)
M5Stack Basicは、この記事を書いた当時より格段にバージョンアップしております。
以下のスイッチサイエンスさんの公式サイトをご参照ください。
https://www.switch-science.com/collections/%E5%85%A8%E5%95%86%E5%93%81/products/9010

※M5Stack Gray(9軸IMU搭載)現在は販売終了しております

 

micro SDHC カード

micro SDHCカードは信頼性の高いものを選んだ方が良いです。
できるだけ大手メーカー製のものが良いと思います。
私は以下の物を使いました。



WiFi環境

2.4GHz帯のWiFiルーター環境が必要です。
事前にルーターの設定を確認して頂き、M5CameraやM5Stack内のマイコンESP32がWiFiに接続できるようにしておいてください。
例えば、MACアドレスフィルタリングやファイアウォール設定などです。

ESP32のMACアドレスが知りたければ以下の記事を参照してください。

ESP32-WROOM-32 チップ・メモリ・MACアドレス情報取得方法

また、WiFiルーターが無い場合は以下のホテル用ルーターでも実験できます。
ただ、電波の届く範囲は狭いです。

パソコンおよびUSBケーブル等

パソコンはWindows10環境で実験しました。
ESP32マイコンはWiFi使用時に大きな電流が流れるので、USBケーブルは良質なもので太く短いものを使った方が良いです。
そして、USBハブは使わない様にし、パソコンに直挿しして下さい。

測定用に別途使ったもの

Arducam B0011 (OV2640 モジュール)

OmniVision製イメージセンサ OV2640 を搭載したArduino用に構成されたカメラモジュールです。

http://akizukidenshi.com/catalog/g/gM-13197/

ESP32-DevKitC

Espressif Systems純正のESP32開発ボードです。
開発ボードには、ESPr Developer 32 もありますが、残念ながら使えるGPIO数が足りないので、ESP32-DevKitC が良いです。

waves ESP32 DevKitC V4 ESP-WROOM-32 ESP-32 WiFi BLE
waves
¥1,170(2024/12/12 08:50時点)

ブレッドボード SAD-101

ESP32-DevKitCを使っても、1列分余裕があって、おススメのブレッドボードです。

サンハヤト SAD-101 ニューブレッドボード
サンハヤト
¥590(2024/12/12 22:11時点)

ジャンパーワイヤー

Arducam B0011と接続するジャンパーワイヤーはオス-メスとオス-オスが必要です。
私はQIコネクタ(2550/デュポンコネクタ)を圧着して自作しましたが、Amazonで探せばいろいろありますよ。

測定用に ESP32-DevKitC と OV2640モジュールをブレッドボードで接続する

M5Cameraをロジックアナライザで解析するのは無理なので、以前のこちらの記事で取り上げたように、ESP32-DevKitC とArducam B0011 (OV2640 モジュール) をブレッドボードを使って接続していきます。

ただ、この場合は動作が不安定です。
接触不良もあるし、ジャンパーワイヤーのインピーダンスの問題で信号を認識しないことも多々ありました。
それに外来ノイズも受け易いです。
本来ならば、M5Camera基板のように最短経路で結線すべきだと思います。

接続は以下のようにしました。
M5Cameraのピンアサインとは少々異なります。

【ESP32-DevKitC と OV2640 CMOS カメラモジュール接続】
ESP32-DevKitC OV2640 Module(B0011)
3V3 VCC
GND GND
GND PWDN (Power Down Mode)
GPIO #17 RESET
GPIO #27 XCLK
GPIO #21 SDA (SIOD)
GPIO #22 SCL (SIOC)
GPIO #19 D7
GPIO #36(SVP) D6
GPIO #18 D5
GPIO #39(SVN) D4
GPIO #5 D3
GPIO #34 D2
GPIO #35 D1
GPIO #32 D0
GND Y1
GND Y0
GPIO #25 VSYNC
GPIO #26 HREF
GPIO #23 PCLK

そして、ロジックアナライザは ZEROPLUS LAP-C を使いました。

ZEROPLUS ロジックアナライザ LAP-C(16032)
ZEROPLUS
¥28,006(2024/12/12 08:09時点)

これについては過去の記事で紹介しています。
ロジックアナライザ ZEROPLUS LAP-C を使ってみた

接続すると下図のような感じになって、カオス状態です。

バス特性のプロトコルアナライザ設定はせずに、D0~D7をバス設定にして、あとはHREF、VSYNC、PCLK、XVCLK を結線しただけです。
ただ、後で述べますが、GPIO #4 を割り込み検知用に測定したりしています。

ところで、長い時間の挙動を見る場合、ロジックアナライザでは無理です。
例えば、VSYNCがHIGHレベルという長い区間のDMA割り込み回数を測定したい時は、オシロスコープで測定するしかありませんでした。

Arduino core for the ESP32 のインストール

プログラミングは Arduino IDE を使います。
ESP32 や M5Stack のプログラミングには Arduino core for the ESP32 のインストールが必要です。
動作確認しているバージョンは以下です。

Arduino IDE ver 1.8.12
Arduino core for the ESP32 ver 1.0.4

Arduino core for the ESP32 のインストール方法は以下の記事を参照してください。

Arduino core for the ESP32 のインストール方法

ボード設定は、以下のようにフラッシュはデフォルト設定のままでOKでした。
PSRAMは使いません。

ボード:  ESP32 Dev Module
Upload Speed:  921600
CPU Frequency:  240MHz (WiFi/BT)
Flash Frequency:  80MHz
Flash Mode:  QIO
Flash Size:  4MB (32Mb)
Partition Scheme:  Default 4MB width spiffs (1.2MB APP/1.5MB SPIFFS)
Core Debug Level:  なし
PSRAM:  Disabled
シリアルポート:  ※ご自分の M5Camera のUSBポート
————————————-
書込装置: USBasp

 

自作ライブラリをインストールする

今回は、M5Stackには私の自作ライブラリをインストールします。
動作確認しているのは以下のバージョンです。

ESP32_mgo_tec ver 1.0.71

GitHub の以下のリンクにありますので、ZIPファイルをダウンロードしてArduino IDE にインストールします。

https://github.com/mgo-tec/ESP32_mgo_tec

Arduino IDE へのZIPファイルからのライブラリインストール方法は以下の記事を参照してください。

GitHubにある ZIP形式ライブラリ のインストール方法 ( Arduino IDE )

因みに、このライブラリには、温湿度気圧センサBME280や空気質センサBME680用のヘッダも入っていて、Bosch製ドライバライブラリが入っていないとコンパイルエラーになります。
その場合は、ライブラリのSensorフォルダを削除してください。
Windows 10の場合、以下のパスになります。

C:\Users\ご自分のユーザー名\Documents\Arduino\libraries\ESP32_mgo_tec-master\src\ESP32_mgo_tec_bV1\Sensor

M5Stackライブラリで動作させることもいつか試してみたいのですが、リクエストが多かったら考えてみようと思います。

フォントファイルを micro SDHCカードにコピーしておく

M5Stackでは、4GB~16GB のmicro SDHCカードを使います。
現在販売されている micro SDHCカードの多くは予めフォーマット済みですが、フォーマットされていなければ FAT32で新たにフォーマットしておきます。
フォーマット方法は、以下の記事を参照してください。

micro SD 、micro SDHC カードの初期化(フォーマット)方法

ここではフリーの東雲フォントを使います。
micro SDHCカードのルートに/font フォルダを作成しておき、そこに以下のファイルをコピーしておきます。

Utf8Sjis.tbl (UTF8→Shift_JIS変換テーブル)
shnmk16.bdf (16×16 全角フォント)
shnm8x16.bdf  ( shnm8x16r.bdf のファイル名中の ’r’ 文字を削除しておく)

 

これらのファイルは以下の記事を参照すればダウンロードできると思います。
(※SPIFFSの項目の所は不要なので読み飛ばしてください。)

Arduino – ESP32 ( SPIFFS 又は micro SD ) 自作Fontライブラリインストール方法

では、次はM5CameraとM5Stackのスケッチ(プログラムソースコード)を紹介します。

コメント

タイトルとURLをコピーしました