Tech Note 16a: More on Serial IR Communications Jan 22, 2002
© NSB Corporation. All rights reserved. |
このテクニカルノートはNSBasicを使用する、低速度のシリアルIR(赤外線)インターフェースについて説明します。ここで説明するデータリンクは、Palm M100を使い、2400ボーレート(Palm IR受信にポートに送信)で一方通行のIRリンクを提供します。トランスミッターはPICマイクロコンピュータで作成したものです。インターフェースの概要と共に、サンプルコードが提供されています。
Palm IRポートは、IrDAの仕様(非常に複雑で包括的)に準じるようです。ほとんどの仕様はソフトウェア・プロトコルおよびレイヤー(私は使用していない)に関するものです。完全な仕様(pdfフォーマット、Zipファイル)は以下のサイトからダウンロード可能です。
http://www.irda.org/standards/specifications.asp
私の目的は、仕様にある物理的なレイヤーについて学ぶことです。
これにはまず、"IrDA SIR Data Specification"を選んでダウンロードして下さい。Zipファイルを解凍した後、"IrPHY_1p4.PDF"ファイルを開いて下さい。14-16ページの内用が、主に私が使用した情報です。
(注意:このドキュメントに記載されているページ番号は、PDFヴュウアーのページ番号と違います。ドキュメントのページ番号はいくつかが抜けていますので、ここではPDFヴュウアーのページ番号を使用しています。)
基本的に、(リンクの送信側は)RS232データを取ってIRダイオードにそれ送るというほど単純なものではありませんが、それほど大変でもありません。各ビットはIR"パルス"としてエンコードされます。各パルスの(最大)間隔は、データの1ビットの時間の3/16と等しくなります。2つの連続したパルスの間隔は、指定したボーレートの時間と等しくなります。(= 1 / baud rate) 私は2400のボーレートで走らせていますので、(最大)"on"(パルスがオン)時間=78マイクロセカンド(百万分の1秒)で、ビットの間隔=417マイクロセカンドになります。
この仕様によると、かなり短いパルス間隔も許容されます。私の場合では、2マイクロセカンド以下まで下がります。実際に5.5マイクロセカンドまで縮めてテストしましたが、問題なく走りました。もしパルス間隔を小さな値に落としていないと、かなり狭いパルスを使用するのは、高密度のパルス(=リンクの長距離レンジ)を許容しますが、短時間にバッテリーを消費するでしょう。
論理"1"ビットは"dark" (LED = off) として、論理"0"ビットは"bright" (LED = on) としてエンコードされます。データはスタートビット(1ビット、常に論理 "0" = LED "on")の後にデータ8ビット、そしてストップビット(1ビット、常に論理 "1" = LED "off")から構成されています。
私は実際、ストップビットを2つ使っています。これは非同期リンクですので、文字と文字の間隔には限度はないはずです。
各文字はASCIIデータで構成され、LSB first(lease significant bit:最下位ビット)のバイト順で送られる。私の場合、7ビットASCIIと8番目にパリティビットです。私はパリティを使用しませんので、このビットに論理"0" (LED = "on")をセットしています。
私のNSBasicコードは以下のラインが含まれています:
' Open the serial port ' This clears out the OpSys receive buffer ' And guarantees the received data is "fresh" receive_error = serialopen(0,2400) ' Switch to the infrared comm port receive_error = serialset("IR",1)
IRポートに切り替えた後は、他に何も変更する必要はありませんでした。この受信ソフトの残りは、元々Palm RS232ポートを使用する為に作ったもので、特に変更は必要ありませんでした。あなたのコードを書く時、先にRS232で正常に動作させ、それから上記のコードを使ってIRに切り替えると良いかもしれません。
これはIRパルスを生成するために使用したハードウエアの概要です:
チップはPIC 16C773 microで、3.58 MHz crystalで走ります。出力は汎用TTL対応I/Oピンです。このトランジスターは、普通のTTL出力から得られるものよりかなり多くの電流(パルス)をダイオードにぶつけることを許容してくれます。またシグナルの極性も逆にします・・・出力ピンの論理"0"をIR LED "on"へ換えてくれますので、ソフトの中でビットを逆にする必要はありません。ダイオードの電流は計測しませんでしたが、100 - 150 milliampsの辺りだと思います。(低デューティー・サイクルのため、平均電流はもっと低い)
IRリンクを友達に話したところ、彼はMaximのチップがRS232をIrDAへ変換するとの情報を提供してくれました。ハードウエアやアセンブリコードが苦手な人にとっては、このアプローチの方が妥当かもしれません: http://www.maxim-ic.com/
このサイトで"IrDA"を使って検索して下さい。いくつかのデバイスが出てきます。
リクエストしていただければ、ASCII文字の出力ルーチンようのPICソースコードの提供は可能です。このルーチンはPIC 16C773 micro用に書かれ、3.58 MHz crystalで走ります。パルスタイムとボーレートにソフトウエア・タイミング・ループを使用していますので、"crystal sensitive"です。リクエストは私のメールへお願い致します。pelican2© silcom.com
これはハイレベル言語でも可能かもしれませんが、ソフトウエア・タイミング・ループを使用してパルスタイムとボーレートを作っていますので、冒険でしょう。ハイスピードのデータリンクは、アセンブリルーチン無しではほぼ望みはありません。また高いデータ比の為にデザインされたハイレベル・ソフトウエアも同様です。
たぶんほとんどの方はPICアセンブリコードはご存知ないと思いますし、学びたいとも思わないでしょう。従って、一つのモデルとして以下の説明的な(アセンブリ)コードを用意しました。CPUがこのルーチンを呼び、送信されるASCII文字が"ASCII_char"変数に保管されます:
'ASCII character ouput routine sub_char_out: char_buffer = ASCII_char for bit = 0 to 7 LED = off char_buffer = char_buffer / 2 if char_buff - fix(char_buffer) < 0.4 then LED = on gosub bit_out char_buffer = fix(char_buffer) next bit return 'ASCII bit output routine sub_bit_out: LED_output_pin = LED (wait for interval = LED_pulse_time) LED_output_pin = off (wait for interval = (1/baud rate) - LED_pulse_time) return
リンクのレンジはLEDパルスパワーとLEDビーム幅に関係しています。わたしは35度のビーム幅で約300milliwatts (peak)で走るLEDを使用し、約5フィーとの(安定した)最大レンジを得ることが出来ました。私は送信データにパリティを使用していませんので、私が使用しているリンクはデータの「喪失」や「改ざん」に対してかなり弱点があると思います。
実際、リンクの極限に近いレンジで起こる極一部を除いては(意図的にこの"gray"ゾーンを見つけている状態)、データの喪失や改ざんは起こりませんでした。これはPalm IR recieverの内部ハードウエアがかなり"保守的"で、ソフトの(エラーチェッキング)負担を軽くするでしょう。
TechNote 16について、シリアルIRポートのサンプルNSBasicプログラムで別の(ユーティリティ)プログラムが必要なことを言い忘れました。そのプログラムはHackMasterと呼ばれ、私はYahooの検索で探しました。NSBasic サンプルプログラム(IRTest.prj)を使用するには、Ringwald氏のComLinkプログラムに加え、HackMasterが必要です。HackMasterはComLinkを有効にし、ComLinkがIRTestを有効にします。
これらの3つのプログラムを使って(および上記で述べた送信データフォーマット)、デバイス上のIRTestプログラムからの送信されたテキストデータを受信し表示することが可能になりました。一旦送信されたデータが正しいフォーマットであることが確認できたら、これらの3つのプログラムを取り除きました。リンクは問題なく動作しました...
LEDのビーム幅はリンクの最大レンジに大きな影響を与えます。(LEDのパワーレベルよりも影響力がある)基礎光学からすると、ビーム幅を半分にカットすることはLEDパワーを4乗に比例して増やすのと同じ効果です。
私の観察からすると、かなり狭いビーム幅のLEDを使用することにより、何十フィートの距離のリンクが可能でしょう。(しかし、方向を定めるのはとても難しいでしょう)
バラエティに富んだビーム幅のIR LEDが入手可能ですが、全ては約500 milliwatts (peak)パワーに制限されているようです。通常、異なるLEDは一定の光を生み出さないので、一つで不十分な時は、(同じデータで稼動)複数のIR LEDを使うことが出来るはずです。(1つは広いビーム、一つは狭いビームなどが可能)
トランスミッターとしてレーザーポインターを試してみるのも面白いかもしれません。レーザーダイオードはonとoffをどれくらいの早さで切り替えているのでしょうかね...
もしIRポートを"full duplex"(送受信を同時に)として使えたら、別の変わったアプリケーションが可能でしょう。IRポートの近くに反射板を置くことによって、IRポートは単純な"proximity detector"として使用できるでしょう。
光学タコメータとしても・・・
Yeah... go ahead... shove that $500 PDA down there, right next to that turbocharged fan blade, running at 3000 RPM...