公開日:2024/06/05
title.png

30th Season


#30-5 VGAカメラ再び

 Arduino DUEのCPUパワー(@84MHz)を最大限使って制御した、VGAカメラOV7670モジュール(下図、および記事)を、今度はCmod A7ボード(FPGA)を使って、サクッと、制御してみたいと思います。

a141_ov7670.jpg

  「#14-1 はい、チーズ(OV7670)
  「#14-2 いちたすいちは?に〜(OV7670)
  「#14-3 最後にもう一枚撮りま〜す(OV7670)

 上の写真から判る様に、このカメラ📷モジュールは、8ビットデータバスでデータをやり取りするため、電源・GNDを含めて18本もの信号線を接続しなくてはなりません。
 画質は、VGA(640×480[ドット])、16ビットカラー(65,536色)と、決して高画質ではありません。それにもかかわらず、非圧縮だと、1フレーム(画面)当たり600Kバイトもの巨大なデータ領域を占めることになります。
 DUEのCPUパワーをもってしても、QVGAサイズに縮小した上で、1.26[s/フレーム]という取り込み・表示速度がやっと、でした。Arduino UNO @16MHzでハンドリングするのは、まず、不可能ですし、それは、動作クロック24MHzのオリジナル16ビットCPUコアMoscoviumであっても同じ事です。

 OV7670モジュールを、「再び、三度、四度、……」と、もっと気軽にサクッと使える様にハードウェア(FPGA)の底力を存分に発揮しようとするのが、今回のテーマです。

データ量の削減

 VGAサイズ600Kバイトなんて巨大なデータは、数10MHz程度のマイコンボードで扱いきれる物ではありません。まともなストレージを持っている訳でもないし、と言って、UARTで送信するとなったら、何秒かかるのよ?

  例)UARTでVGA(640×480[ドット])、16ビットカラー(65,536色)画像データを送信

 撮影したVGAサイズの画像データを送信するのに、50s以上も待ちますか?って事です。データ量の削減は、現実的な処理に落とし込むための必須条件なのです。

解像度を落とす

 まず思い当たるのは、解像度を落とす(画像サイズを縮小する)事です。
 OV7670には、VGA(640×480[ドット])から間引いて、QVGA(320×240[ドット])やQQVGA(160×120[ドット])サイズで取り込むオプションがあります。実際、DUEを使って制御した時は、QVGAサイズで取り込んで、TFTディスプレイへ表示しました(下表)。

解像度 フレームサイズ データ容量
16ビットカラー 8ビットカラー
VGA 640×480[ドット] 600Kバイト 300Kバイト
QVGA 320×240[ドット] 150Kバイト 75Kバイト
QQVGA 160×120[ドット] 約38Kバイト 約19Kバイト
QQQVGA 80×60[ドット] 約9Kバイト 約5Kバイト

 上表の範囲なら、OV7670のI/Oレジスタ設定にて、対処可能です。でも、UNOやMoscoviumにとっては、QQQVGAサイズでも、まだ大きいのです。もっと小さくして、ハンドリングし易くしなくては……。

 例えば、8×8ドットの赤外線アレイセンサなんて物があります。10数MHz動作のマイコンで処理するなら、この程度の解像度だって、十分では、ないでしょうか?

 解像度を落とす(画像サイズを縮小する)試みは、また別なテーマとしますので、ここでは一旦、忘れて先へ進みます。

色数を落とす

 次に考えつくのは、色数の削減です。
 OV7670はRGB565と言うフォーマットで16ビットカラー(65,536色)を表現することができます。元々、それほど画質の高いカメラではないので、16ビットカラーはオーバスペックだと感じます(下図、参考)。

a143_vgacam.jpg

 データ量の削減を目的とするなら、3ビットカラー(8色)でも良いくらいですが、さすがにそこまで削減するのは、ちょっとやりすぎかな??落としどころを探っていきましょう。


 色数を議論する前に、OV7670と接続すべき信号線数の削減を考えたいと思います。
 OV7670のデータバスは8ビットなのですが、1ピクセル(画素)のデータ量は16ビット(RGB565)なので、2サイクルかけて1ピクセルのデータを転送しています。接続すべきデータバスの本数に着目して、OV7670が対応しているピクセルフォーマットを以下に示し、考察を続けます。

pixel 15 14 13 12 11 10 9 8   7 6 5 4 3 2 1 0 memo
(busを4本以下に集約したい)
bus 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
RGB565 R4 R3 R2 R1 R0 G5 G4 G3   G2 G1 G0 B4 B3 B2 B1 B0 bus[7,4,2]の3ビットカラー+1本bus[1]が関の山。
RGB555 x0 R4 R3 R2 R1 R0 G4 G3 G2 G1 G0 B4 B3 B2 B1 B0 bus[6,4,1]の3ビットカラー+1本bus[0]が関の山。
RGB444 x3 x2 x1 x0 R3 R2 R1 R0 G3 G2 G1 G0 B3 B2 B1 B0 bus[7:6,3:2]の4本で6ビットカラーに集約可能。

 例えば、3ビットカラー(8色)データを取り込むためには、RGB各最上位ビットだけを接続すれば良いのです。もし、RGB各2ビットづつ、上位ビットを接続すると、合わせて6ビットカラー(64色)を表現することができます(濃く着色したセル)。

 問題は、上表の様に8ビットデータバス×2サイクルに分割して転送されてくるため、データバスのビット位置に注目すると、バラバラなビット位置に分散していて、必要な信号線数が増大してしまうことです。目標としては、データバスの信号線数を4本以下に集約したいと思っています。
 ここで、RGB444フォーマットに注目してください。2冪数である4の倍数でデータが整列しているので、8ビットデータバスのbus[7:6]とbus[3:2]、計4本を接続すると、6ビットカラー(64色)を取り込むことができ、効率が高い事に気が付きます。

 Olive+を使って、先程のサンプル画像を6ビットカラー(64色)に減色させてシミュレーションしてみると、以下の様になりました。

a143_vgacam.jpg a305_rgb222sim.png

※右の画像は、Olive+の画像処理でシミュレーョンした物で、実際に撮影した物ではありません。

 6ビットカラー(RGB222)を採用することで、一つ良いことがあります。6ビット値の範囲は0〜63なので、所謂BASE64符号化すると、テキスト1文字で表現可能なのです。シリアルモニタなどを通してテキスト通信する場合に有利です。

 これに決めました。

信号線数の削減

 本節では、Cmod A7ボードと接続すべき、OV7670のインターフェイス信号線の本数を削減して行きたいと思います。

 OV7670のインターフェイスは18本です。2×9本の2列ピンヘッダなので、ブレッドボードに挿すこともできず、デュポンワイヤ18本で繋ぐしかありませんでした。DUEを使って制御した時は、下図の様な感じでしたね。

a142_expr.jpg

 実験が終わって、回路を崩してしまったら、「さて、またOV7670を使って見ようか」なんて気には中々なりません。だって、18本も端子名や端子番号を確認しながら接続しないと使えないのだから。面倒極まりありません。

 気軽に、「あ、カメラでデータ取り込んで使って見よう」と、使える様にするには、大きな障害なのです。

PMODコネクタ

 Cmod A7ボード(FPGA)には、PMODコネクタと言う、2×6ピン(12ピン)の2列ピンソケットが備わっています。コネクタのサイズも配列も合わないので、PMODコネクタにOV7670を直結するのは無理です。
 ですが、うまく信号線数を削減して、OV7670をPMODコネクタと接続可能なアダプタボードを作って(工作)おけば、気軽に「OV7670使って見るか〜」って、使える様になるのではないでしょうか?

 PMODコネクタは、12本(2列×6本)のピンソケットで、内、電源(3.3V)出力2本、GND×2本が割り当たっており、残り8本がFPGAの端子と接続されています。つまり、OV7670の端子18本から、PMODコネクタと接続すべき信号線数を8本まで削減できれば良いのです。

OV7670の端子数削減検討

 早速、OV7670の信号線18本各々について、PMODコネクタ12本への割り当てについて検討してみましょう。以下表を参照してください。

OV7670 検討結果 PMOD
割り当て
端子名 用途
3.3V 電源 PMODに引き出された電源端子と
接続。
2本
GND 2本
SCL I2C通信 MoscoviumのSTWSERユニット
接続のため、PMOD外で接続する。
SDA
VSYNC(VS) 垂直同期 OV7670制御の肝となる信号線。
PMODに引き充てる。
1本
HREF(HS) 水平同期 1本
PCLK(PLK) ピクセルクロック(出力) 1本
XCLK(CLK) クロック入力 1本
D[7:0] データバス こちらで検討した通り、
4本を選択して、PMODに引き
充てる。
4本
RET リセット PMODコネクタ数不足。
普通のI/Oポートで良い為、
PMOD外で接続する。
PWDN 低消費電力モード

※OV7670の端子名で、()内はシルクに記された端子名。

 検討内容は表中に記載した通りで、必要な信号線は、大方PMODコネクタに割り当てることができました。PMOD以外に、4本のI/Oポートと接続する必要が残りますが、許容範囲でしょう。理由は以下の通りです。

  PMOD外で接続が必要な信号線:


 動作周波数10数MHzの組み込みマイコンシステムに於いて、カメラ画像の取り込みは、相当にハードルが高いのです。色数や接続信号線数の削減に加え、ハードウェア(FPGA)を活用することで、手軽に使える様にするテーマの第1話でした(全4話)。


btn_arduino.png

btn_prev.png btn_next.png

home