TCM8240MD breakout (i2cで画像取得モジュール) 動作確認完了
English abstract is below.
以前お知らせした、猫カメラのカメラの部分だけ取り出して電子工作の部品にしようという計画(TCM8240MD breakout)、完了しました。下の写真にあるように動作確認がとれています。
上の動作確認では、モジュールにArduino Miniを繋げて、モジュールから画像をi2c経由でArduinoに取り込み、それをUSBシリアルでPCに流し、さらにPCでOpenCVを使ったデモプログラムで表示させています。
モジュールのスペックを以下にまとめておきます。
- 接続は4本です。電源2本(VCCとGND)、i2c(SDAとSCL)です。VCCは+5Vにも+3V3にも対応しています。i2cについてもHレベルが+5Vであっても+3V3でも問題ありません。
- 最大でSXGA(1280 x 1024 pixel)まで撮影できます。その他にもSVGA(800 x 600)、VGA(640 x 480)、QVGA(320 x 240)、QQVGA(160 x 120)、CIF(352 x 288)、QCIF(176 x 144)、subCIF(128 x 96)が出せます。
- フレームレートはサイズやインターフェイスに依存しますが、明らかに動画は不可能で、インターバル撮影を主な用途として想定しています。これはインターフェイス(i2c)が遅いことによる影響で、Arduinoとの接続だと例えばQQVGAでも1fps以下です。撮像自体は常に15fpsで行っており、画像取得を行ったタイミングから最も近くで切られたシャッターの画像を出力します。
- フォーマットはRGB565(詳細は後述)というRawフォーマットです。モジュール内部のカメラの能力的にはJpegは出せるはずなのですが、現時点では設定方法がわからずスペックから除外します
- 画像取得のためのi2cは最大10Mbps程度まで速度をだせるはずです。Arduinoのi2cの最大速度(1Mbps)は余裕をもって対応しています。
しばらくお時間をいただくことになるかもしれませんが、スイッチサイエンスさんやFPGA-Cafeさんで購入できるようにしたいと考えています。
※試作段階にも関わらず、製品を評価してくださった方を紹介します。
- 『なんでも作っちゃう、かも』の@arms22さんに使っていただきました。
- 『モッパーのロボット研究所』のモッパーさんに使っていただきました。ロボットサッカーのセンサとして使う計画のようです。
- いしかわきょーすけさん (OLEDに写した!)、酔漢さん(mbedでチャレンジ中)、hajimesさん (PCに転送できました!、Netduino経由でOLEDに表示!) に押し付けてきました。
※※(2010/8/23)ここに書いてあったサンプルコード上のi2cアドレスが間違っていました(0x3Dと0x3Eが逆)。訂正しました。
※※※(2010/11/21)実はMTM06でスイッチサイエンスさんからこっそり販売していました。購入していただいた方からの動作報告です。
以下、使い方やフォーマットなどの紹介です。
使い方ですが、カメラの設定、カメラからの取り込み、の2段階にわかれています。
まず配線を以下の図のようにします。4本です。
そして、カメラモジュールに対して設定のおまじないをi2c経由で行います。例えば160x120の画像を取り出すにはArduino語で以下のおまじないをします。ここでArduinoではi2cのライブラリWireが必要になりますので、スケッチ先頭に#include <Wire.h>や、先にWire.begin()するのを忘れないようにしてください。サイズの変更や色合いの調整などその他の設定については、モジュール内のカメラTCM8240MDを参考にがんばってみてください。
{0x02, 0x00}, // Set Camera Active
{0x02, 0x40}, // Set Camera Reset
{0x03, 0x00}, // PLL
{0x02, 0x00}, // Set Camera Active
{0x0B, 0x00}, // White Line OFF
{0x58, 0x20}, // Exposure Time
{0x05, 0x80}, // Frame Rate Quarter(00)/Half(40)/Full(80)
{0x1A, 0xFF}, // HCOUNT = 0x3FF = 1023
{0x1B, 0xB3}, // VCOUNT = 0x21B = 539
{0x1C, 0xA1}, //
{0x11, 0x4A}, // Changed b/c of PICSIZE
{0x14, 0x23}, // Changed b/c of PICSIZE
{0x04, 0x0B}, // RGB 160x120 OUT ON
{0x1F, 0x0C}, // SPCOUNT = 0xBC3 = 3011 // Doesn't match formula?
{0x1E, 0x23}, // SPCOUNT[7:0]
{0x0E, 0x00}, // According to the AppNote it should be 0xAC for this PICSIZE?
};
int i;
for(i = 0; i < sizeof(cam_config) / sizeof(cam_config[0]); i++){
Wire.beginTransmission(0x3D);
Wire.send(cam_config[i][0]); Wire.send(cam_config[i][1]);
Wire.endTransmission();
}
そしてお次はカメラから画像データをi2cで引っ張ってきます。0x3Eのアドレスから読み取りを行うと、4bytesのデータサイズ(リトルエンディアン形式)がまずはじめに出力され、続いてデータ本体が流れてきます。またArduino語で書くと、以下のようなコードになります。
unsigned long count;
{
byte header_count = 0;
while(header_count < 4){
buf = WireExt.get_byte();
*((byte *)(&count) + header_count) = buf; // Little Endian
header_count++;
}
}
while(count-- > 0){
byte b = WireExt.get_byte();
// do something with b
}
WireExt.endReception();
}
ここでArduinoでは、標準i2cのWireライブラリを拡張したWireExt.hを使っていることに注意してください(使い方詳細はリンク参照)。画像データは大量(例えばQQVGAだと160 x 120 x 2(RGB565) = 38400 bytes)でArduinoの内蔵RAMを遥かに超えており、データを全て読み込んだ後に他の作業を行う、といったことはできません。そこでi2cで読み出しながら逐次処理を行うことが必須となりますが、その動作に対応したのがWireExt.hです。
取り込みまでの使い方は以上ですが、取り込んだ後の話として画像のフォーマットRGB565について触れておこうと思います。RGB565は1ピクセルあたり2bytes(=16bit)で表現されたRawフォーマットです。色とビットの対応関係を表すと、bbbbbggg gggrrrrrという並びになっています。各色を0から255までの値で表したければ以下のコードを使うと良いでしょう。
byte r, g, b;
r = (b_first & 0x1F) << 3;
g = ((b_first & 0xE0) >> 3) | ((b_second & 0x07) << 5);
b = (b_second & 0xF8);
エンディアンが相変わらずリトルエンディアンであることに注意してください。
あとは液晶につなぐなり、SDカードに記録をとるなり、Twitterに投稿するなりなんでもできると思います。残念ながら未だにJpegをうまく取り込めていませんが、むしろ圧縮がないほうがArduino単体で画像表示させるなどPCとの切り離しができて、より面白いプロジェクトに使っていただける、とも考えています。
技術的な話に興味があれば、回路図やモジュール内のCPLDのコードの詰め合わせ(camera_breakout_r5146.zip)を公開していますので、遊んでみてください。例えば大量にあるバッファを利用して、連射画像をとったりといったことがコードの変更で可能になります。
Abstract in English
This article describes a DIY image capture module by using a Toshiba TCM8240MD. You can make a same module by yourself with my open-sourced board schematics, artwork, CPLD HDL, and your electronics knowledge. The module has following features:
- Capability to capture and calibrate images via I2C. This means you can get images by using only foure wires: VCC(+5V or +3V3), GND, SDA, and SCL.
- The image resolutions can be selectable among SXGA(1280 x 1024 pixel), SVGA(800 x 600), VGA(640 x 480)、QVGA(320 x 240), QQVGA(160 x 120), CIF(352 x 288), QCIF(176 x 144), and subCIF(128 x 96).
- The frame rate is very low. For example, you can get about 1fps in QQVGA format.
- The image format is RGB565 raw format.
- The maximum speed of I2C is about 10MHz.
- Example codes of initialization and capturing, which run on an Arduino with WireExt, i.e., my extension of Wire I2C library, can also be referred. WireExt files will be installed into "libraries" directory of Arduino.
More information about why I developed the module will be provided. I was motivated to seek a nice camera for CatCAM project. The final goal of CatCAM project is gathering and analyzing cat's life-log, which mainly consists of images they saw. However, there were no existing suitable cameras for cats because their size and weight were too big and heavy. Therefore, I developed a dedicated device for cats, which is composed of not only a camera but also GPS, accelerometer, and bluetooth. The module described here is a part of the dedicated device.
コメント
>モッパーさん
fenrirです。とりあえずメールしてみました。内容をご確認ください。
こんにちは、私はあなたのカメラのプロジェクトが好きです。私はあなたのためのいくつかの質問を持っているあなたは、電子メールを持っている。ありがとうございました!
(translated from: hello, i like your camera project. do you have email as i have some questions for you. thank you!)
> Dear F.Liford
Hello, I'm this blog author. I'd like to discuss you in public space. If you have any questions, please make comments on this page. Note that for reducing spams this blog is not allowed to make comments in English only, thus, please add "こんにちはこんにちはこんにちは" to the head of your comments, thanks.
初めまして、猫カメラのことは知っていたのですがこのモジュールのことは気がついていませんでした。
もし基板の予備がありましたら譲っていただけないでしょうか昔ストロベリーリナックスさんから購入した東芝のカメラを動かいたいと思います。半田付に自信がありませんが挑戦したいと思います。
よろしくお願いいたします。
>tomi9さん
コメント気づくのが遅くなってしまいました、fenrirです。猫カメラの基板ですが、随分時間がたったこともあり、すいません行方不明です。最近は当時と違ってカメラも一般的になってきているので、私にとってはモチベーションの対象からカメラはもう外れつつあります…。一番お手軽なのはなんでしょうか、Raspberry Piのカメラモジュールでしょうかね…。
コメントする
- 匿名でのコメントは受け付けておりません。
- お名前(ハンドル名可)とメールアドレスは必ず入力してください。
- メールアドレスを表示されたくないときはURLも必ず記入してください。
- コメント欄でHTMLタグは使用できません。
- コメント本文に日本語(全角文字)がある程度多く含まれている必要があります。
- コメント欄内のURLと思われる文字列は自動的にリンクに変換されます。
- 投稿ボタンを押してエラーがでなければ、投稿は成功しています。反映されるまでには少し時間がかかります。
モッパーと申します。こんばんわ。
ロボカップジュニアのサッカー競技で使えそうなので、是非トライアルしてみたいです。QQVGA 以下の解像度でも良いのでカラーセンサーを代用出来るレベルのスピードを CCD+I2C+Arduino で実現したいです。一度メール頂けないでしょうか ?
Posted by: モッパー : August 4, 2010 01:01 AMよろしくお願いします。