Rough English Here
 
 
CMOSカメラユニット「Treva」の解析
2/15, 2003: ジャックのピン配置に関する注意書きを追加.
2/6, 2003: PCのシリアルポートに接続する方法を追加(下の方).「Linux Zaurus C700 に Treva を接続」へのリンクを追加.
11/25, 2002: 「Treva on Linux (Xilinx-JTAG-Writer)」「AVR STK500」「TINIでライブカメラ」へのリンクを追加.
7/17, 2002: コネクタを売ってる「CUI」へのリンクを修正.
6/12, 2002: へッダ情報を更新.「Serial Camera」へのリンクを追加.
4/2, 2002: 「カシオペアとトレバを接続」へのリンクを追加.
3/25, 2002: 「Treva基板キット」の紹介を追加.
3/22, 2002: 「TrevaをZaurusに接続しよう」へのリンクを追加.消費電流についての記述を修正しました.
3/8, 2002: 僕の書いたTrevaの記事がトラ技に掲載されました.
3/4, 2002: 「Treva on TINI とればで遊ぼう」へのリンクを追加.10件目です! 「トレQ」へのリンクを修正しました.
2/22, 2002: 「TrevaをaJileに繋ぐ」へのリンクを追加.
2/10, 2002: 「Treva-GBC Camera」へのリンクを追加.
1/20, 2002: 「Treva on TINI」「P/ECEにTreva」へのリンクを追加.
1/13, 2002: 「Treva(トレバ)で撮れるんです」へのリンクを追加. 12/20, 2001: 「feelH”用デジタルカメラユニットTrevaをVisorにつなぐ」へのリンクを追加.
11/14, 2001: ジャックの入手情報・リンクを追加.
9/29, 2001: 「USBにTrevaをつなぐ」へのリンクを追加.
9/18, 2001: jellyfishさんの情報を基にへッダ,画像フォーマットに関する説明を修正. より美しく撮影できるようになりました! コネクタに関する情報も追加.
9/16, 2001: コネクタに関する情報を追加.
9/10, 2001: 画像フォーマットの説明中のサンプルプログラムを修正.PPM形式 画像に関する説明を追加.
9/8, 2001: ページ公開
[]

feel H”用イメージキャプチャユニット Treva を自作の回路に接続してしまおう,という企画です.
TrevaにはCMOSイメージセンサが使われていて,小型・軽量・低消費電力でしかも 大量生産のため安価です(2000円〜3000円台).ネットオークションでも安く出回ってますよ.

ぱ研では いしかわきょーすけ氏とのコラボレーションプロジェクトでTrevaの インターフェース部の解析に取り組み,MPUのパラレルポートに接続して 画像を取り込むことに成功しました.

← Trevaで撮影した画像

MPUに接続したTrevaで撮影したデータをシリアルポート経由でPCに取り込み, RGBに変換しました.原サイズ(96 X 72 pixel)です.

トランジスタ技術2002年4月号に 記事を書かせてもらいました.PCのシリアルポートと接続するというだけの内容ですが,Trevaに興味を持ってもらえる人が増えるきっかけになればと思います.
Trevaの仕様
カタログスペックおよび実際に測定・解析したデータです.

本体サイズ,重量 幅30 X 厚さ32 X 高さ16(mm), 約10g
撮像素子 1/4型,10万画素 CMOSイメージセンサ OV6630 (OmniVision社製) (データシート)
出力画像解像度 96 X 72 pixel
レンズ 固定焦点(30cm〜∞) 画角:水平46°垂直37°(実測値)
露出 自動制御(室内・室外の撮影に対応)
ホワイトバランス 自動調整
接続プラグ φ2.5mm 4ピンプラグ (イヤホンマイク端子)
電源 3V単一(3.3Vでの動作も確認済) 15〜20mA程度(*1)
フレームレート 標準:約3フレーム/秒,最大:約7.7フレーム/秒
画像フォーマット 16bit YUV形式 (「画像フォーマット」の項を参照)
価格 新品実売3500円程度,中古2000円程度(2001年9月現在)

(*1) 当初10mA程度と書いていましたが,かなりいい加減な値でした.改めて測定してみたところ,15mA@3.3Vでした.電源電圧が変わったり,高速なクロックを与えると変動すると思います.いしかわさんの測定によるとクロックを与えたときに20mAくらいになることもあるようです.

分解写真はいしかわさんの 「分解くん」へGo!

MPUとの接続
とりあえず分解して線を引っ張り出すことにします.プラスチックのツメを折ら ないように気をつけてこじ開けると,プラグに接続された4本の線がでてきます.


プラグから4色の線がのびて,基板上のパッドに接続されています. これらの線を,それぞれDOUT(黄),CLK_IN(ピンク),GND(黒),Vcc(赤)と 呼ぶことにします.

DOUT Trevaからのシリアルデータ出力です.CPUの入力ポートに 接続します.
CLK_IN CPUからTrevaに与えるクロック入力です.CPUの出力ポートに 接続します.
Vcc 3V(3.3Vでも問題なく動作しました)の電源を供給します
GND 電源GND

ここで接続するCPUが3Vまたは3.3V動作の場合は直結可能ですが,5V動作の 場合は信号レベルの変換をしなければなりません.Treva→CPU方向(DOUT)は Trevaが3Vを出力するため,CPUのポートがTTLレベルであれば直結可能です. そうでない場合は入力がTTLレベルのゲートICを挿入するといいでしょう.

CPU→Treva方向(CLK_IN)については必ず5V→3Vのレベル変換が必要です. オープンコレクタタイプのゲートを挿入して出力を3Vでプルアップするのが 簡単だと思います.あとは定電圧ダイオードを使ったり,トランジスタ2つで Push-Pull回路を組むという手もあります.

また,3V(3.3V)の電源を作るには三端子レギュレータを使うと簡単です.
おすすめはuPC29M03 (3V用), uPC29M33(3.3V用)
共立エレショップ電源用ICのコーナーで購入できます. 70〜80円と安価ですよ.

←Trevaの出力はイヤホンマイク4極ピンプラグ端子です.これに適合する ジャックが入手できればいいのですが,単体では入手が困難と思われます.

ところが,Panasonic製のfeel H”のモックアップにはなぜかジャックがついていて, ジャンク扱いで非常に安く購入できます. ぱ研では"KX-HS100"のモックアップを近所のヨドバシカメラで1個100円で 購入しましたが,2001年9月現在,店頭には"KX-HF300" "KX-HS110"のモックアッ プが展示されていますので(ジャックが付いているのを確認済み),しばらくは 入手可能な状況が続くものと思われます.

←モックアップは簡単に分解できますが,コネクタはプラ板に接着 されていて,カッターやペンチを使って根気よくはがす必要がありました. 接着剤のはがし液などを使うといいかもしれません.

←ジャックのピン配置は図のようになっています(上から見た図).

ジャックは表面実装型です.基板に接着するなどして使うといいと思います.

コネクタによってはピン配置が異なる場合もあるよう です。念のため確認するようにしてください。 (thanks → 丸猫さん)

ジャックに関する情報をいくつかいただきましたので,まとめて紹介します. 情報を提供していただいた方々,どうもありがとうございました.

さて,ここまではけっこう簡単でしたね?ここから先も難しくありませんよ.

データの取り込み
データを取り込むにはCPUからCLK_INに101010...というクロックを与えます (左図の上の波形).そうするとDOUTからシリアルデータが出力されます (左図の下の波形).この図から分かるように,「立ち上がり」のエッジで DOUTのデータを1bitずつ読みこめばOKです.

クロックの周波数は標準(feel H”からの出力)で約500HKzですが, 1.7MHz程度までは正常に動作することが確認できています.また遅い分にはいく ら遅くても構いません(10kHzでも動作することを確認しています).

送られてくるデータのフォーマットを解析したところ, 以下のようになっていることが判明しました.
(jellyfishさん, 山さんより詳細なデータをご提供いただきました.感謝ですm(..)m)

以上より,次のような手順で画像を読み込めばいいことになります.
  1. しばらく連続して'1'が来るのを待つ
  2. マジックナンバ '0xaa55ff'を確認し,続く29byte分のデータを無視する
  3. (または2の代りに,65bit連続して'0'が来るのを待ち,続く2byte分のデータを無視する)
  4. 96 X 72 X 16bit分の画像データを読み出す

500kHZのクロックを与えると秒3枚弱の画像を撮影できます.クロック周波数を 高くすると最大1.6MHzくらいまで正常に動作し,このとき秒7枚程度の画像を 撮影することが可能です.

プログラム例を以下に示します.

/* 1bit読み出し処理 */
int
read_bit ()
{
  int i, a;

  PDTRA = PDTRA & ~0x0040;  /* CLK = 0 */
  for(i=0; i<42; i++);      /* Wait; 42 for 500kHz  */
  a = PDTRA & 0x0080;       /* 立ち上がりでDOUTを読み込み */
  PDTRA = PDTRA | 0x0040;   /* CLK = 1 */
  for(i=0; i<42; i++);      /* Wait; 42 for 500kHz  */
  if(a)
    return 1;
  else
    return 0;
}

/* メインの処理 */
void
start_main (void)
{ 
  unsigned char data[96*72*2+100];
  .....

  while(1){
    /* PCから文字's'が送られてきたら,画像取り込みスタート */
    while( scif_getc() != 's' )
      read_bit();
    /* 100bit連続して'1'が来るのを待つ */
    i = 0;
    while(i<100){
      if( read_bit() == 1) i++;
      else i = 0;
    }

    /* 連続65bit分の'0'を検出 */
    i = 0;
    while(i<65){
      if( read_bit() == 0) i++;
      else i = 0;
    }

    /* 続く2byte分のデータは無視 */
    for( i=0; i<2*8; i++ )
      read_bit();
    
    /* ここから画像データ取得開始 */
    for( k=0; k < 96*72*2; k++){
      d = 0;
      for (i=0; i<8; i++){
	d <<= 1;
	if(read_bit())
	  d |= 0x1;
      }
      data[k] = d;
    }
    /* 取得したデータをPCに転送 */
    for( k=0; k < 96*72*2; k++){
      scif_putc(data[k]);
    }
  } 
}

magic numberを見た方がカッコイイぞ,っていう場合はこんな感じですね.

    .....
    /* マジックナンバ'0xaa55ff'を待つ */
    magic = 0;
    while((magic & 0xffffff) != 0xaa55ff){
      magic <<= 1;
      if(read_bit())
        magic |= 0x1;
    }
    /* 続く29byte分のデータは無視 */
    for( i=0; i<29*8; i++ )
      read_bit();
    .....

画像フォーマット
さて,読み出した画像データを解析したところ,変則的なYUV形式の フォーマットでした (OV6630のデータシートを参照).

先に述べたように,1画素あたり16bitのデータで構成されていますが,

1ピクセル分のデータ構成(16bit)
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
色情報UまたはV 輝度値Y

このため,グレイスケールの画像は96 X 72 pixelの解像度を持っていますが, カラー情報については48 X 72 pixel分の解像度しかないと言えます.

以下の式でYUVからRGBへの変換を行うことができます.

 R = (U - 128) + Y
 G = 0.98*Y - 0.53*(U - 128) - 0.19*(V - 128)
 B = (V - 128) + Y

または

 R = 1.40*(U - 128) + Y
 G = 1.02*Y - 0.750*(U - 128) - 0.336*(V - 128)
 B = 1.77*(V - 128) + Y

どちらの式を使うかによって色合いが変わります.1番目の式が正解だと 思ってるんですが,ただ,2番目の式の方が周囲が暗いときでも キレイに撮れるような感じ(?)です.

これもプログラム例を示しておきます.

  .....
  unsigned char img[96*72*2];
  .....
  /* PPM形式(UNIXでよく使われる)画像のへッダ情報を出力 */
  printf( "P6\n" );
  printf( "96 72 255 " );

  .....(img[]に画像データを格納する).....

  for(i=0; i<72; i++){
    for(j=0; j<96; j++){
      p = (i*96 + j)*2;
      Y =  img[p+1];
      if( j % 2 == 0){
	V =  img[p];
	U =  img[p+2];
      }else{
	V =  img[p-2];
	U =  img[p];
      }

      U = U - 128.0;
      V = V - 128.0;

      red = U + Y ;
      green = 0.98*Y - 0.53*U - 0.19*V;
      blue = V + Y;

      if( red > 255 ) red = 255;
      if( red < 0 ) red = 0;
      if( green > 255 ) green = 255;
      if( green < 0 ) green = 0;
      if( blue > 255 ) blue = 255;
      if( blue < 0 ) blue = 0;

      /* RGB画像を出力 */
      printf( "%c",  (unsigned char)red );
      printf( "%c",  (unsigned char)green );
      printf( "%c",  (unsigned char)blue );
    }
  }

上記サンプルプログラムではUNIXでよく使われる"PPMフォーマット"の画像を 出力しています.非常に簡単なフォーマットで,Windowsでも読み書きできる ソフトがいくつかあると思います.このフォーマットに関しては PPM/PGM/PBM形式の画像について をご覧下さい.


PCのシリアルポートに接続
トランジスタ技術2002年4月号 に書かせてもらった,PCのシリアルポートと接続する方法です. Trevaを手っ取り早く試すにはいいかもしれません.詳細は記事を参照してください.

右に回路図を示します. 電源をUSBコネクタから取り,三端子レギュレータで3.3Vに変換しています.

画像を取り込むためのサンプルプログラムを置いておきますので,参考にしてみてください.


制限事項(というかちょっと不満な点)
このように極めて簡単に画像を取り込むことができます(世界一シンプルな イメージデバイスかも).しかしながら画像認識などに使うにはちょっと 物足りない点もあります.以下の点も考慮した上で,採用するかどうか 決めるといいんじゃないかと思います. まあ,これらの制限を差し引いても十分魅力的だとは思います;-)
最後に
いかがでしょうか?来年のロボットコンテストで早速使いたくなった人も いるのでは(^^;

どこにでも簡単に接続できるので,ロボットに搭載したり,Webカメラにしたり, 手持ちのPDAに接続するなど,応用範囲は広いと思います.
説明で足りないところ・分かりにくいところがありましたら, ご指摘いただければ幸いです.また応用例のレポートや追加情報も大歓迎です. メールや掲示板をご利用ください.

最後に,解析が可能かどうか未知数なうちからTrevaを入手して基礎データを とっていただいた いしかわきょーすけ氏に改めて感謝します.いしかわさんのデータが なければそもそも解析に着手することすらできませんでした!
また,へッダに関する情報をお寄せくださいました, jellyfishさんにも感謝致します.間違いが正され,画質が改善されました!

リンク
「Treva基板キット」の紹介
Strawberry Linuxのおちあい氏が 「Treva基板キット」の販売を始められました. コンパクトな専用基板に,普通はちょっと入手しにくい4極ジャックや,電源レギュレータなど必要な部品が揃っていてとてもお手軽な感じです. これから始められる方は検討の価値ありだと思います.

販売終了とのことです.(2003/1/27)


このページに関するコメントをお願いします
お名前:   ↓タグ使えます
コメント: →他の人のコメント

→最近のコメント


Copyright © 2001-2003 KOMORIYA Takeru リンクはご自由に (参考) →開発レポートにもどる