Arduino DUEのCPUパワー(@84MHz)を最大限使って制御した、VGAカメラOV7670モジュール(下図、および記事)を、今度はCmod A7ボード(FPGA)を使って、サクッと、制御してみたいと思います。
「#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ビットカラーはオーバスペックだと感じます(下図、参考)。
データ量の削減を目的とするなら、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色)に減色させてシミュレーションしてみると、以下の様になりました。
→ |
※右の画像は、Olive+の画像処理でシミュレーションした物で、実際に撮影した物ではありません。
6ビットカラー(RGB222)を採用することで、一つ良いことがあります。6ビット値の範囲は0〜63なので、所謂BASE64符号化すると、テキスト1文字で表現可能なのです。シリアルモニタなどを通してテキスト通信する場合に有利です。
これに決めました。
本節では、Cmod A7ボードと接続すべき、OV7670のインターフェイス信号線の本数を削減して行きたいと思います。
OV7670のインターフェイスは18本です。2×9本の2列ピンヘッダなので、ブレッドボードに挿すこともできず、デュポンワイヤ18本で繋ぐしかありませんでした。DUEを使って制御した時は、下図の様な感じでしたね。
実験が終わって、回路を崩してしまったら、「さて、またOV7670を使って見ようか」なんて気には中々なりません。だって、18本も端子名や端子番号を確認しながら接続しないと使えないのだから。面倒極まりありません。
気軽に、「あ、カメラでデータ取り込んで使って見よう」と、使える様にするには、大きな障害なのです。
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の信号線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話)。