■ホビーロボット部品の製造・販売 
  モータコントローラ、センサ、音声、画像、無線モジュールなど、
■ホビーロボット制作記事のページ (各種マイコン、PCとの接続事例)
■特殊メイク、特殊材料の販売 ※特殊メイクのコーナーはこちらに移りました。
Top(お知らせ) 製品紹介 使い方とサンプルプログラム 通信販売 リンク ロボット掲示板 会社案内
 Easy Robotics for all enthusiastic people!!!  ---HOBBY ROBOT PARTS SHOP ASAKUSAGIKEN---   Since 2003...
ATmega128(AVR)とCMOS-EYEのバス接続及びシリアル接続
はじめに

 ここでは AVRの中の、ATmega128を搭載したマイコンボード BTC068(ベストテクノロジー製) と浅草ギ研製CMOSイメージセンサーボードCMOS-EYEとの接続例を紹介します。

 ※このページで紹介する内容はあくまでも一例です。個別の作成のご相談ご質問はお答えできませんのでご了承下さい。このページと同じ内容についてのご質問についてはロボット掲示板にてお願いいたします。


用語について

 このページで説明する用語について解説します。

 CMOS-EYEはマイコンと接続することが前提となっております。以下の説明で「マイコン」と書いたところは、CMOS-EYEに接続するユーザー側のマイコンを示します。マイコン側の端子名は極力、そのマイコンのデータシートに書かれている名前を記載しています。
 マイコンチップが載ったCPUボードを「マイコンボード」とします。マイコンボードの端子名は極力、そのマイコンボードの取扱説明に書かれている名称を記載しています。

 CMOS-EYE上にも制御用のマイコンが搭載されていますが、これは「CMOS-EYE上のマイコン」とします。(バス接続時には特にこの「CMOS-EYE上のマイコン」を意識する必要はありません。)

 CMOS-EYEからはいろいろな端子が出ています。アドレスを指定する端子の集まりを「アドレスバス」とします。又、データを指定したり受けたりする端子の集まりを「データバス」とします。


CMOS-EYEとATmega128


<CMOS-EYEについて>

 CMOS-EYEは携帯電話用のCMOSカメラに、画像取り込み回路とSRAMを取り付けたもので、手持ちのマイコンなどと接続して小型の画像処理システムを構築できます。ロボットなどに搭載してスタンドアローンの自立型ロボットシステムを作るのに最適です。CMOS-EYEについては「CMOS-EYEの紹介・仕様・使い方」(以下「CMOS-EYEの紹介ページ」とする)のページに詳しく掲載しています。このCMOS-EYEの紹介ページはマニュアルも兼ねているので、使用前によく読んでください。特に、このページを読む前に、「ハードウェア仕様」「ピン配列」「バス接続での使い方」の節をよく読んでください。


<ATmega128について>

 CMOS-EYEはシリアル命令による内蔵プログラムを使った画像処理も行えますが、本領を発揮するのはバス接続で高速に画像処理を行うパターンです。アトメル社が出しているAVRというマイコンシリーズは種類が豊富で、内部構造も比較的標準的で、くせが少なく、一般的な機能がついており、プログラム書き換え回数も一万回と、学習用には向いており、入手製が良く、海外のサイトではサンプルプログラムが豊富にあります。がしかし、日本国内では書籍や情報が少ないこともあり、H8やPICにおされてあまり流行っていないようです。
 ちなみに、これは私個人の所感ですが、H8は機能が偏っており、PICはくせが多いと考えています。
 AVRの中のATmegaシリーズは、C言語での開発環境を想定して設計されており、C言語で作ったプログラムの動作効率が良いようです。ATmegaシリーズの中にもグレードがいろいろとありますが、今回は、IO数の多いATmega128を使用してみます。
 また、ATmegaシリーズはデータシートを見る限りでは3.3Vでも駆動できるようです。これについては下で実験してみます。


<BTC-068について>

 自分でチップの状態からマイコンシステムを作れる方も最近は(2006.9現在)増えてきましたが、多くの電子工作ホビーストやロボットビルダーは市販のマイコンボードを購入して使用していると思います。今回、ATmega128を選んだ理由としてはベストテクノロジー社(以下ベステクと略す)からマイコンボードが出ているということもありました。ベステクでは、マイコンの開発経験が少ない方でも比較的簡単にマイコンプログラミングを始められる「GDL」という開発ツールが無償で提供されています。メーカーのC言語のマイコン開発環境が数万円〜数十万円もするこのご時世で、¥4,500で、簡易とは言え、C言語開発環境が無償で使えるというのも魅力的です。


<GDL以外の開発環境を使う方>

 アセンブラで開発できる方やGCCなどをインターネット上から取ってきて自分で開発環境を構築できる方は、以降はプログラムロジックの参考程度に読んでいってください。個別のサンプルプログラムは作っておりませんのでご了承下さい。なお、画像処理の中心部分のプログラムの記述は開発環境に依存しないような書き方を心がけています。



3.3VでBTC068が動くか?のテスト

 まず、スペックだけで検討してみます。
 ATmega128は3.3Vでも動きますが、BTC068全体では3.3V動作をさせると2つの問題が起きる可能性があります。

 1つ目。BTC068にはATmega128以外にもいくつかのICが搭載されていますが、この中で、プログラムポートの電圧変換に使われているMAX3313というICのスペックが3.3V対応にはなっていませんでした。ということで問題が起きるとすると、「プログラムが書けなくなる」という可能性があります。

 2つ目。ATmega128のデータシートを見ると、電源電圧が低くなると動作クロックも低くなるというものがありますが、BTC068上のクロックICは16MHzなので、「オーバークロックで動作しない」かもしれないという可能性があります。
 下はデータシートの電気特性の抜粋です。これを見ると、3.3V動作時は8MHz程度までしか動かせないことになります。
  


 と、2つの懸念材料がありましたが、結論を言うと、BTC068に3.3Vを入れても問題なく動きました。

 浅草ギ研からはCMOS-EYEのオプションで5V変換ボードも出す予定ですが、ここでは、オーバースペックではありますが、3.3V動作でCMOS-EYEと直で動かすことにします。
 尚、あくまでも仕様外の使い方なので、実際のロボットなどへの搭載時に5V変換をするかどうかは各自で判断してください。



BTC068上のSRAMの切り離し

 BTC068には、32KBのSRAMが付いており、ATmega128のいくつかの端子に配線されています。BTC068の取説の回路図を見ると、ATmega128のPC7端子がこのSRAMへのCE(チップイネーブル)になっているようで、JP2で切り離しができるようです。
 CMOS-EYEではアドレスバスやデータバスなどでIOを沢山接続しますので、JP2を切り離してBTC068上のSRAMを使わないことにします。少しもったいないような気がしますが、CMOS-EYEは単純な512KBのSRAMとしても使えますので問題ありません。

 
JP2の様子

 JP2は裏面にあります。ハンダが四角く盛ってあるのが2つ見えるかと思いますが、この間に細いパターンが引いてありますので、このパターンをカットします。パターンの両端をカッターで切り込みを入れて、カッターの先で軽くえぐるとはがれます。

 

 カットした後は、ルーペなどを使って目視確認をし、テスターで導通を確認して下さい。ここがきちんとカットされていないと、CMOS-EYEの画像にアクセスできなくなります。


ATmega128に接続する端子の検討

 CMOS-EYE紹介ページを見ると、マイコンとの接続は下のようになります。これはバス接続時の図ですが、シリアル通信命令も使ってみますので、UARTのRXとTXも接続します。

 <バス接続時に必要なIO(ここではUARTのRXとTXもつなぎます)>
  


 ATmega128のデータシートと、BTC068マイコンボードの取説にある回路図を見ながら、CMOS-EYEと接続する端子を検討します。

 とりあえず、データシートを見ながら以下のように端子を割り振ってみました。

 <端子割り付け案(ATmega128データシートのFeaturesのPin Configurationsより)>
 

 TEST端子ですが、これはCMOS-EYEにはありません。後のページで、画像処理にかかった時間を計測するために利用することにした端子で、処理の前後にこの端子をHIGH/LOWさせてオシロスコープでその波形を観測して時間を測定しようと思います。(このページではそこまでいきません)。

 ピンクの部分は、もともとマイコンボード上で配線されているものです。BTC068では、あらかじめダウンロードプログラムが書き込まれた状態で販売されており、RXD0/TXD0の端子を使ってPCからシリアル通信でプログラムをダウンロードします。よってRXD0/TXD0は使用しません。PB7にはLEDがつながっており、LOWにすると点灯するようです。動作中にLEDを光らせた方がわかりやすいのでこれもこのまま使います(よってCMOS−EYEに接続する端子には使わない)。

 今回は、CMOS−EYEとはバス接続とシリアル接続両方で接続します。ATmega128のTXD1(送信)がCMOS−EYEのRX(受信)へ、RXD1(受信)がCMOS−EYEのTX(送信)へつなげます。

 ATmega128には入出力IO端子が53本あります。CMOS−EYEへ37本、時間測定(TEST)で1本、もともと接続されているものが3本なので、ATmega128の残りのIO端子(自由に使える端子)は12本となります。



実際の接続

 下は、マイコンボードとCMOS-EYEの接続を図にしたものです。
 CMOS-EYEからは3.3V電源出力が出ています。これは700mAぐらいまで供給できます。
BTC068のSRAMは使いませんので、ATmega128と232CコンバータIC(取説の回路図ではMAX3313というもの)ぐらいしか動かしませんので、十分駆動できます。BTC068は本来5V動作のマイコンボードですので確実に動作するかという保証はありせんが、今回の実験では問題なく動いているようです。

  

  今回はテストなので、CMOS-EYEとBTC068にヘッダピンを取り付けて、その間を一本づつコネクタで接続しました。その様子は下のようになります。写真の黄色い線のコネクタは2550コネクタというのを使ってます(浅草ギ研で販売してます)。このケーブルの作り方はこのページでやってますので参照してください。一本づつのコネクタだと配線を変えられるので実験に最適です。(使いまわしもできます。ブレッドボードの逆ですね。)

 線は、電源ラインにAWG24、配線にAWG28相当の太さのものを使ってますが、実際にロボットに組み込むときにはもっと細い線&小さいコネクタを使用しても良いかもしれません。電源は太いままでも良いかも。

  


 一応、板金パーツの図面も載せておきます。ご参考まで。サーボホーン用の穴をあけてありますので、ヨー軸方向にカメラを回転させることもできる、というものです(が実際に使うかどうかは?)。CMOS-EYEは2φ5mm長のスペーサとM2L8ネジ(電気を通さないものが良い)あたりで止めています。これらはWILCOで買えます。 センサ部の取り付け金具はCMOS-EYEに付属しているものを使いました。





サンプルプログラム

 操作の基本であるSRAMへのアクセスと、シリアル命令を送ってみるプログラムを作りました。全ソースプログラムはこちら

 CMOS-EYE_ATmega128.c (右クリックで対象を保存)

 これは、

 1) ST端子を使って撮影してみる

 2)シリアル通信で命令を送って撮影してみる

 3)CMOS-EYE上のSRAMに値を読み書きしてみる

 という流れになります。この、撮影、SRAM読み書き、シリアル命令が実装できれば、CMOS-EYEを使いこなすことができます。

 以下、詳細を説明します。


サンプルプログラム−ヘッダーファイルと名称定義

 ヘッダファイルはGDLに添付されているヘッダーファイル avr/io.h を使っています。GDLでH8系を使っていた方にとってはこのヘッダファイルは少々使いにくいかもしれませんので自分で使いやすいものを用意してもよいでしょう。以後、書き方などは一応AVR系のデータシートに掲載されているCの書き方例に沿った書き方で進めます。

 名称定義は、上で検討・接続したピンをわかりやすい(?)ように名称定義しておきました。

 
 
 アドレスは19本必要なので、ポートAと、ポートCと、ポートGの一部を使っています。これらを使ったアドレッシングについては次で説明します。

  IO方向ですが、データバスだけは双方向の通信を行うので、入力と出力を切り替える必要があります。よって、入出力の方向を設定する、ポートDのIOレジスタにDATA_DIRという名称をつけてます。

 各ポートの、IOレジスタは 0で入力 1で出力 となっています。初期値は0入力になっています。データシートを見なくてもわかるように、ここでは INPUT OUTPUT の名称をつけてます。よって、たとえば、データバスの方向を変えたい場合は

 DATA_DIR = ALL_OUTPUT;

のように記述できます。



サンプルプログラム−アドレスセット

 CMOS−EYEのアドレスはA0〜A18の19本あります。ATmega128のIOポートは8本のものが最大ですので3つのポートを使って19本のアドレスバスを形成します。

 

 AVRはPICやH8と違って、中抜けしている端子などが無いのでアドレッシングは簡単にできます。わかりやすい。



サンプルプログラム−端子のHIGH/LOW

 AVRのデータシートの作法によると、標準的なヘッダファイルは特殊レジスタのアドレスしか設定していないので、論理演算を行って各ビットをHIGH/LOWにするように記載されています。たとえば、PORTBの2ビット目をHIGHにしたい場合は

 PORTB |= (1<<PB2);

 のようになります。この作法だと、ビット単位の動きがよくわかるのでプログラムの勉強には良いのですが、書くのが少々めんどうです。
 CMOS-EYEと接続した端子をビット単位で設定することが多いので、このあたりを関数化しました。

 

 使い方は見ればわかるかと思います。各ビット操作を関数化して名前を変えただけです。


サンプルプログラム−IO初期化

 IO初期化部分です。各端子のHIGH/LOWの初期値と、入出力の方向を指定します。

 

 −−−アドレスバス設定−−−
 アドレスバスは、ATmega128->CMOS-EYEへアドレス指定しか行わないので、全て出力に設定します。

 −−−データバス設定−−−
 データバスは入出力切替で使いますが、ICの端子同士が出力同士になると破損する可能性があるので、とりあえず入力に設定しておきます。動作中は、CMOS-EYEのSRAMの中身を読み出すときに、CMOS−EYE側のデータバスが出力になりますので、その時にこちら側が出力にならないように注意して下さい。

 −−−シリアルポート設定−−−
 シリアルポートの設定をしています。AVRのシリアル通信機能は同期/非同期両方使えるのでUSARTという名称になってます(ユニバーサル・シンクロナス(同期)・アシンクロナス(非同期)...)。2つあるのですが、BTC068の場合、USART0がプログラム用で使われるので、USART1を使ってCMOS-EYEにシリアル命令を出すことにしました。
 ATmegaのシリアルポートは他のマイコンと比べて設定するところが少なく、使いやすいと思います。基本的にはUCSR?Aがフラグ系で、UCSR?Bが許可/不許可系で、UCSR?Cが通信設定です。その他は特に設定する必要はありません。ボーレートはとりあえず9600bpsにしました。(CMOS-EYEのUARTは9600bpsか115200bps)設定値その他詳細はデータシート(USART Register Descriptionだけ読めばわかる。他にハマるとこは無いです。)を参照してください。

 −−−コントロール線−−−
 CMOS-EYEのBSY端子を監視する以外は、ATmega128側からHIGH/LOWを出力する端子です。使っていない端子は全て入力に設定しています。(初期値も入力になっている)

 −−−タイマ設定−−−
 ATmegaの場合は特に設定しなくてもタイマを使えます。

 −−−初期値−−−
 初期値では、
 1)アドレスを0番地指定
 2)モードを80x60白黒
 3)SRAMコントロールを全て無効
 4)シャッターを待機状態
 にしています。
 シャッター端子のSTですが、これは撮影時以外はHIGHにしておかないとCMOS−EYEが撮影しっぱなし(常にBUSY状態でLEDが点きっぱなし)になるので、初期値は必ずHIGHにして下さい。
 モード指定やSRAMコントロールについては「CMOS-EYEの紹介のページで説明しています。



サンプルプログラム−ウェイト関数

 ウェイト関数を作りました。かなーり適当に作ったので、正確な時間はウェイトしません(少し長い)。
 本来はこのような方法ではなく、コンペアマッチか割り込みでタイマを動かすともっと正確なのができますが、時間の正確さはあまり必要でないのでこれでよしとします。他のプログラムなどに流用しないように注意して下さい。
 タイマはタイマ0を使っています。設定するレジスタはTCCR0だけなので使うのが楽。プリスケーラの設定をすると動き出します。16MHzで1/64分周なので250カウントで約1mSになります。が、forやwhileが動いているのでその分長く時間がかかります。

 



サンプルプログラム−シリアル送信関数

 ATmega128のシリアル送信機能は、バッファが2個しかないので、送信レジスタの状態を監視しながら値をセットします。データレジスタはUDR?になりますが、ここに値をセットすると、あとは自動で送信されます。ここも詳しくはデータシートを見てください。

 



サンプルプログラム−SRAMへのデータ読み込み

 読み込みの流れは

 1)SRAMを有効にする
 2)読み込むアドレスを指定(出力)する
 3)OEをLOWにする
 4)データバスに表れるデータを読み込む
 5)OEをHIGHに戻す

 という手順になります。

 SRAMを有効にするのは、冗長的な作業(読んだり書いたりする時はずっとCEをLOWにするので)になるので下の関数では入れてません。

 



サンプルプログラム−SRAMへのデータ書き込み

 書き込みの流れは、

 1)SRAMを有効にする
 2)書き込むアドレスを指定(出力)する
 3)データバスに値を出力する
 4)WEをLOWにする
 5)WEをHIGHに戻す

 という手順になります。

 CMOS-EYEのSRAMのアクセス速度は30nSです。下の関数ではWEをLOWした後すぐにWEをHIGHにしてますが、30nS以外に切り替えると問題が生じます。
  ATmega128はほとんどの命令が1クロックで動きますので、最速でも16MHz時では62.5nSかかりますので問題ありません。おそらく行247,248の切替には1クロック以上の時間がかかります。

 



サンプルプログラム−撮影関数

 ST端子を使って撮影をする関数も作りました。

 ST端子を数百μS以上LOWにするとCMOS−EYEは外部バスをハイインピーダンス状態にして、撮影を開始します。ここで注意点ですが、ST端子をLOWにするとその瞬間に撮影されるのではなく、撮影には約100mSかかりますので、STをLOWにした後に次の指示をだそうとしても受け付けません。よって、ここではBSY端子を監視することで撮影が終了するのを検知してから、関数を終了させています。
 この間の時間も他の処理のためにSH2を動かしたいという場合は、CMOS−EYEのBSY端子を外部割込みが出来る端子につないで割り込み処理をすると良いでしょう。

 



サンプルプログラム−main(全体の流れ)

 上で紹介した関数を使って、

 1)ST端子を操作して画像を撮影してみる

 2)シリアル命令を使って画像を撮影してみる

 3)SRAMになにか書き込んで呼んでみる

 という動作をさせてテストしてみます。これらは単純に上の関数を使えばよいのですが、実はATmega128起動時にポイントがあります。CMOS-EYEは起動時や設定のときに時間がかかりますので、それらが終わるまで待つ必要があります。これを忘れると、意図したとおりに動かないので注意が必要です。

 下はmainの中心部分です。行290はCMOS−EYEが起動するまで待っています(3秒ぐらいでもOK)。また、行297はモードの設定(M0-M2)が終わるまで待っています。作った自分が言うのも何ですが、私もこの2つを入れてなくて意図した通りに動かなくて悩むことが多いです。注意して下さい。(自分で作った仕様を忘れてしまう...)
 行293から295は、M0-M2の設定をしようとしていましたが、ATmega128の場合はこのようにビット操作を連続して行うと上手く行かないことがあるようです。よって行296のようにポート単位で値を設定しています。以後もATmega系の場合のM0-M2の設定はこのようにポート単位ですることにします。(原因がわかりません???)

 

 細かいところはソースのコメントを参照願います。あとデータシートも。



実際に動かしてみる

 ソースプログラムを動かして、CMOSEYE Viewerで確認した画像が下になります。

 CMOS−EYE ViewerはCMOS−EYEの紹介ページからダウンロードできます。このソフトウェアはPCで画像確認するためのサンプルプログラムとして作ったものですのでご注意下さい。ソースも公開していますので改良などを行う場合はそちらを参照してください。


 夕方、照明の無い室内で逆光で撮ったので、少々見づらいです。

 撮影1の画像(0番地から160x120カラーで格納されている)
 


 撮影2の画像(57600番地から格納されている)
 


 10万番地から20バイトの値を表示したところ
 


おわりに

 このようにして、ATmega128で画像処理をすることができそうです。次は色判定について解説します。


2006年9月12日

 
(C)Copylight 2003. 有限会社浅草ギ研 | 通信販売の法規(訪問販売法第8条)に基づく通信販売業者の表示