1.はじめに USBインタフェースのWebCameraが世の中に出始めた頃は、接続プロトコルがメーカー独自のプロトコルであったために、 Linuxやマイコンに接続するには、ドライバーソフトが無く、難しかったが、Linuxにおいては、有志によりドライバーが順次開発され、今やほとんどのWebCameraを接続できるようになっている。 RXマイコンやFM3マイコンなどの高機能マイコンでは、SDRAMを適度に増設してやることで、Linuxそのものを走らせることができ、豊富なLinuxのドライバーによりUSBWebCameraを簡単に扱うことができる。 一方、PICにおいては、その貧弱な機能ゆえに、カメラドライバーが存在するとは思えず、USBカメラの接続は諦めていたのだが、 ネット検索を行ってみた所、PIC32を用いたドライバー製作記事が一つ見つかった。 この記事では、spca5xx のWebCameraドライバーを製作されており、Linuxのドライバーから情報を得て作られたようである。 ドライバーのソースファイルも公開されている。 その他には、もう一つ、PICの本家、Microchip社のForumにて、PIC32MXによるUVCクラスのカメラドライバーの製作に関するディスカッションを見つけた。こちらのForumでは、ソースファイルは公開されていなかったが、PIC32MXでドライバーが製作できるという事実だけは知ることが出来た。 UVCクラスのカメラは、安いものでは、500円ぐらいから手に入る。また、UVCクラスのプロトコルは、www.usb.org で公開されており、ドライバのサンプルソースとしてLinuxのドライバーソースは容易に入手できる。という訳で、PIC用のUVCドライバーの製作に挑戦して見ることにした。 2.ハードウェアの製作 PICは、当初、16ビットのPIC24FJ64GB002を採用した。PIC24FJ64GB002を搭載したミニBのUSBコネクタが付いたマイコンボードを ネットから入手した。このボードは、USBのバスパワーで動作する。 UVCのWebカメラを接続するには、USBのコネクタは、Aコネクタが必要だ。そこで、AコネクターBコネクタ変換基板を自作して、カメラとマイコンボードを接続することにした。 電源はACアダプタを使い、コネクタ変換基板からUSBコネクタを通してマイコンボードとWebカメラそれぞれに+5Vが供給できるようにした。 Webカメラからの画像を表示する表示装置は、共立電子にて購入したディスプレーコントローラーIC評価ボードを採用した。 この評価ボードでは、マイコンとの接続インタフェースが、ダイレクト接続・インダイレクト接続のパラレル接続とSPI接続の3つの中から選択することが出来る。 伝送速度の観点からは、パラレル接続の方が有利であるが、PIC24FJ64GB002では、I/Oピンが少ないのでSPI接続で接続することにした。 3.ソフトウェアーの製作 3−1.UVCクラスについて
www.usb.org にアクセスして、UVCクラスのドキュメントをダウンロードする。ダウンロードしたドキュメントは、以下のとおり。
(2) Universal Serial Bus Device Class Definition for Video Devices:Video Device Examples (3) Universal Serial Bus Device Class Definition for Video Devices:Frequentry Asked Questions (4) Universal Serial Bus Device Class Definition for Video Devices:Identifiers (5) Universal Serial Bus Device Class Definition for Video Devices:DV Payload (6) Universal Serial Bus Device Class Definition for Video Devices:Frame Based Payload (7) Universal Serial Bus Device Class Definition for Video Devices:Motion-JPEG Payload (8) Universal Serial Bus Device Class Definition for Video Devices:MPEG-2 TS Payload (9) Universal Serial Bus Device Class Definition for Video Devices:Stream Based Payload (10)Universal Serial Bus Device Class Definition for Video Devices:Uncompressed Payload ダウンロードしたドキュメントを読み、UVCクラスについて勉強する。
UVCクラスでは、カメラの ブライトネスやコントラスト、色相、彩度などを設定する Video Controle Interface と、カメラの画像を転送する Video Streaming Interface の2つのインターフェースがある。 画像転送は、転送方式に、アイソクロナス転送を使い、転送パケットサイズは、複数種類設定できる。画像フォーマットには、圧縮フォーマットや非圧縮フォーマットがあり、サポートされる画像フレームのサイズも複数設定できる。これらの情報は、カメラがホストに接続された時に、ディスクリプタにより通知される。 ブライトネスやコントラストの設定・取得は、Video Control Interface に対して、エンドポイント0を通じてリクエストを発行して行うが、カメラ毎に、サポートされる機能はそれぞれであり、設定可能な項目は、VC Processing Unit ディスクリプタのbmControls で知ることが出来る。 画像を取得する手順は、次のようだ。Video Streaming Interface に対して、Probe リクエストにより、画像フォーマットや画像フレームの大きさを指定して、ネゴシェーションを行う。その結果を Commit リクエストによりカメラに通知した後、希望する転送パケットサイズを持つ代替インタフェースへ切り替えを行い、ホスト側からINフレームを送出すると、INフレームに同期して、カメラから画像データが転送されてくる。 以上が、にわか仕込みで得たUVCクラスに関する概要である。 3−2. プログラムの作成 PICのUSBホストのプログラムは、Microchipから提供されているUSBフレームワークを使った。作成の元にしたのは、「Host-MCHPUSB-Generic Driver Demo」だ。MPLABで新規プロジェクトを作成し、プロジェクトフォルダーに必要なソースファイルやヘッダファイルをコピーした。作成したプロジェクト名は、「UVCwebcam」とした。 プロジェクトファイル一式:UVCwebcam.zip サンプルソースの usb_host_generic.c をまねて、usb_host_uvc.c というファイルを作成した。また、Microchipから提供される、USBのホスト機能を提供する usb_host.c については、USB割り込み処理の中の アイソクロナス転送に関する部分を一部修正した。 usb_host_uvc.c で提供する関数を呼び出せば、Webカメラを制御したり、カメラからの画像データを取得出来るようにした。つまり、usb_host_uvc.c がドライバーソフトという訳だ。プロジェクトファイルの main.c は、 これらの関数を呼び出すサンプルプログラムとなっている。 usb_host_c.c で提供する関数は、次のとおり。
4.UVCカメラを繋いで見る
UVCドライバーのテストを行うにあたり、次の4つのWebカメラを使った。いずれのカメラも、特別な、ドライバーソフト不要のUVCクラス対応のカメラである。
LOGICOOL HD Webcam C270(300万画素) BUFFALO BSW13K10H(130万画素) Etron Webcam(500万画素) カメラから通知されてくるディスクリプタの内容を以下の各ファイルに示す。これは、出来上がったドライバーのテストプログラムにて出力したものである。
"Etron Webcam"を除く3つのカメラは、USB-Audioの機能も併せ持った複合デバイスとなっている。
wait for Camera Attached. が表示される。カメラの接続を待っている状態である。
d:display Test Bar on LCD. c:List Camera Control current value. f:List supported Format. i:List supported Image Resolution. p:Set capture image Format & Resolution. e:execute frame capturing. => のような、テストメニューが表示される。ここで、DEBUGオプションを有効にしてコンパイルしてあると、先述のカメラのディスクリプタ情報がメニュー表示の前に表示される。 d を入力すると、LCDにカラーのテストバーを表示する。 c を入力すると、カメラのコントラストなどの現在値、最大値、最小値などを表示する。
Exposure Time(Absolute):
Min 1 Max 10000
Min 0 Max 255
Min 0 Max 255
Min 0 Max 255 f を入力すると、カメラのサポートする画像フォーマットを表示する。
Supported Format (Number is 0): YUY2 Supported Format (Number is 1): MJPEG i を入力すると、カメラのサポートする画像フォーマット毎に、画像サイズの一覧を、 320x240 や 160x120 のように表示する。
Supported Format (Number is 0): YUY2 Resolution:
Resolution:
320x176 320x240 352x288 432x240 544x288 640x360 752x416 800x448 800x600 p,e は、カメラから画像を取得してLCDに表示するものである。まず、pを入力すると、フォーマット番号や取得画像の大きさを質問されるので 次のように入力する。フォーマット指定は、予め f コマンドで出力されたフォーマット番号を入力する。
Format Number=>0 Resolution width=>160 Resolution height=>120 "Format and Resolution, Set ok." が表示されたら、次に e を入力する。 e の入力により、カメラから画像を取得し、LCDに表示する。何かキーが押されるまで、画像取得を連続して行う。 何かキーが押されると、 "Capture Stop!" を表示し、画像取得を停止し、再度、テストメニューを表示する。 4−2画像変換等 LCDへの書き込みは、RGB565フォーマットで行うようにしたので画像フォーマットの変換が必要になった。YUYVの場合には、 次の変換式を採用した。
G=1.000Y-0.344U-0.714V B=1.000Y+1.772U
G=16x(Y-0.344U-0.714V)/16=(16Y+6U-11V)/16 B=16x(Y+1.772U)/16=(16Y+28U)/16 その後、PIC32MXに対応させた時には、256倍して256で割るようにプログラムした。 LCDの表示をカラーではなくモノクロで行う場合には、輝度情報であるYのみ使えば良いので上記変換は不要である。 LOGICOOLのカメラがサポートしているMJPEGフォーマットで取得する場合には、JPEGからRGBへの変換処理が必要になる。 変換は、1フレームを受信してからとなり、1フレーム分の画像データを保存するメモリが必要になる。 メモリの小さなPICでは、これは無理であり、テストプログラムでは、MJPEGフォーマットを指定した時には、カメラから画像データを受信するものの、 その後の変換処理は行わずに直ちに破棄するようにプログラムした。 4−3 アイソクロナス転送
フルスピードのアイソクロナス転送では、一定のパケットサイズのデータを、1msec毎に受信することになる。これは、USBホストドライバにて、1msec毎のSOF割り込みにより実現されている。 選択した代替インタフェースによって、その転送パケットサイズは、小さいケースで160バイト程度、大きいものでは、1020バイト程度と、それぞれインタフェース毎に異なるが、受信したデータの処理は、 そのデータ転送時間も含めて1msec以内に完結しないと、次のデータの受信に間に合わないことになる。(受信オーバーフローが発生する) 1020バイトものパケットとなると、12MHzのフルスピードでは、転送だけで1msec近い時間を消費してしまうので、画像データ受信後のフォーマット変換やLCDへの転送をおこなう時間余裕は全くない。 そこで、受信用のバッファメモリを複数用意し、受信したデータの処理をしている間に、次の空いているバッファにデータを受信することで、この問題を解決することが出来る。 ただし、データ受信後の処理は、1msec以内に完結させないと、いずれオーバーフローをきたしてしまう。 転送パケットサイズが小さいと、データ受信後の処理に要する時間は短くて済むので、転送パケットサイズの小さい代替インタフェースを選択すれば有利であるが、それが必ずしも良い訳ではない。画像フォーマットには、それぞれフレームサイズに応じて、フレームレートが定まっており、1秒間に転送されるべきデータ量が決められている。このために、転送パケットサイズを小さくすると、 カメラ側でフレームレートを達成できなくなり、カメラ内部で転送オーバーフローが発生したり、うまく動作しないケースが発生する。 160x120のリゾリューションで、フレームレートが15fpsの場合、1秒間に転送されるデータ量は、160x120x2x15=576000バイト となり、 転送パケットサイズは、最小でも、576バイトでなければならない。 320x240のリゾリューションで、フレームレートが4fpsの場合では、320x240x2x4=614400バイトとなり、転送パケットサイズは、615バイト以上となる。 今回のプログラム作成にあたっては、SOFパケットの転送処理やペイロードヘッダなどのオーバーヘッドを考慮し、転送パケットサイズは、768バイト以上の 転送パケットサイズを持つ代替インタフェースを使用することとした。受信用のバッファメモリは、4バッファを確保した。 5.テスト結果等
EtronとBUFFALOのカメラは、全くもって駄目であった。ProbeからCommitまではうまく行くが、その後の代替インタフェースの切り替え処理でエラーが発生し、画像転送処理に進めない。 Etronのカメラチップをうまく制御するには、何かまだ不足しているものがあるのかもしれない。 LOGICOOLのHD Webcamでは、非圧縮フォーマットの他に、圧縮のMJPEGフォーマットがサポートされている。フルスピードでも最大 800x600 の リゾリューションが使える。なお、LCDへの表示のためには JPEG 圧縮を展開する必要があるが、JPEG展開をプログラムしていないので、 先述のようにデータを受信するだけでLCDへの表示確認は行っていない。 6.対応PICを増やす
PIC24FJ64GB002での動作を確認した後、PIC24FJ256GB106やPIC32MX696F512Hにも対応させた。 |