赤外線コントロールの実験

赤外線コントロールの実験

[TopPage] -> [PIC] -> [ IrController ]  |   [blog1] [blog2] [blog3:PIC24FJへの実装]
1. はじめに
 ライトプレーンはやったことはないのですが、赤外線での制御については興味があります。

 最初はラジコンのプロポ準拠のPPM方式にしようかとも思ったのですが複数人で同時に使えないことや外来ノイズでの信号誤りの検出ができないことから、PCM方式を検討しました。

 方針としては、応答性の向上と複数同時使用が可能なようにデータ送信ビットレートをなるべく高速にすることです。

 因みに、家電等で使用される一般的なフォーマット(NECフォーマット)では

  リーダ部 : 16T(ON) + 8T(OFF) = 24T
  カスタムコード(8bit) : 3T/bit x 8bit x 2 = 48T (0:2T,1:4T -> average:3T/bit)
  データコード(8bit):3T/bit x 8bit x 2 = 48T
  ストップ信号:1T(ON) + 41T(OFF) = 42T

で合計 162T で1T=約0.57ms なので全体で平均 92ms の時間をかけて16bitのデータを送信していることになり、実質的なビットレートとしては約 174bps となります(実際にはデータの反転データ送信等もあり一般的にいうbpsとは違います)。

 また、今回と同様な用途と思われるエアロソアラの赤外線コントロールでは 6bit の制御信号を約18msで送信するので通信速度は約 333bps です。

 今回考案したフォーマットでは約 8.3ms で 4bit(ID) + 6bit/ch x 4ch = 28bit を送信しているので 実質的な通信速度は約 3400bps(チェックビット等も加えた一般的なbps表現では 5060 bps )で、家電方式の約20倍の速度ということになります。


2. 制御信号フォーマット
 赤外線受信ユニット(PL-IRM0208-A538:秋月さんで購入)の特性を調べてみたところ

a) 変調信号38KHz(PICが4MHz動作時26ステップ周期)出力(オン信号)では4サイクル以上出力しないと受信機からのディコード信号が安定してでない(潰されて無視される)
b) オフ信号に至っては10サイクル以上でないとつぶれる(前後のオン信号がくっ付く)
c) 受信ユニットでディコードされたオン信号出力は実際のLED出力の幅より 100us 程度長くなる。
d) 逆にディコードされるオフ信号幅は実際のLED出力よりも 100us 程度短くなる。

等の特性があり、単純にPCM通信しようとすると1ビット当りの信号幅を上記のブレが無視出来るくらい大きくする必要があり、かなり低速通信になってしまうことがわかりました。

 そこで次のようなフォーマットにしました。
1) PCM信号はLSB側から出力する。
2) ビット1は変調信号送信(オン)、ビット0は変調信号オフとする。
3) 1ビット分の送信で
ビット1:38KHzの変調波を6サイクル(156us)送信(特性aからマージン込みでの最小の値)
ビット0:6サイクルの時間38KHz信号をオフ。但し直前の送信ビットが1の場合、12サイクルの時間オフにする。(特性b対策)
4) 制御信号のフォーマット
   [1+ID(4)+01] + [0ff-ffff] + [1ss-ssss] + [0tt-tttt] + [1oo-oooo] + [0cc-cccc]
f,s,t,oはそれぞれ1〜4chの値で6ビット長なので64段階の制御
cは制御信号のチェックサム値で誤り検出用
構成としては 7bit x 6 でエッジ同期でディコードするのでエッジなし最長時間を保証するため、各データの先頭に同期用のビットを付加し、この同期用ビットは交互に反転しています。

1→0のパターンのみ12サイクル(確率1/4)なのでビット当りの平均送信時間は
  6x3/4+12x1/4=7.5サイクル
制御信号は42ビットなので送信に要する時間は
  42*7.5/38KHz = 8.3ms
になります。

 上記の a), b) の赤外線受信ユニットの特性からこの方式の速度は限界に近い速度と思います。
 低速な家電コントロール用の赤外線受信ユニット(PL-IRM0208-A538)を使って今回の速度を達成するには送信側はまぁいいとして受信側は調歩同期方式や家電のPPMもどきのようにサンプリングポイント時点の信号の状態をチェックするだけでは受信できず、エッジ割り込みとタイマー割込みを使って、エッジ毎に同期を取るようにしています(調歩同期のバイト毎同期ではなくエッジ同期)。
 更に受信側では100us周期の割込みで32段階のPWM制御を2ch(左右分)と正転/反転制御を行いました。

 下図が制御信号例で紫線が赤外線LEDの駆動波形で黄色線が赤外線受信ユニットの出力です。
 左図の駆動波形は電流制限抵抗部で測定したもので、LOWレベルが赤外線発光状態でグランドレベルまで落ちず1.8Vとなっていますが、電流制限抵抗値が15Ωなので赤外線LEDには約 120mA の電流が流れていることになります。制御可能距離の評価はしていませんが、室内(5m程度)では問題なくコントロールできました。
 LED駆動波形と赤外線受信ユニット出力を比較するとONとOFFとで対応する信号幅が違う(ONの幅が長くなる)ことがわかります(この違いがなければ受信側のディコード処理が楽なのですが・・・)
 右が信号全体のサンプル波形で、この例では最初のONの開始から最後のONの終了までの間隔が 7.8ms です。

制御信号 制御信号(全体)


3. 回路
a) 送信機
 送信機の回路図がこれです。  赤外線LEDは、秋月さんで購入した OSIR5113A を使用しました。
 駆動効率を高めるため、ニッカド8セルの 9.6V 電源を使用し、赤外線LEDを直列接続しています(R9の抵抗を小さくし、6セルの電源を使用することも可能)。
 LCDは秋月さんで購入した SD1602HUOB(-XA-G-R)で 5V 動作のため、PICとLCDの電源を3端子レギュレータでつくり、電源電圧測定の基準値にも使うことで 電源電圧を 0.01V の精度で測定しています(ソフトウェアによるキャリブレーション機能も付けています)。
 また、LCDのバックライトをPICのI/Oで駆動し、スイッチ操作でバックライトを ON/OFF できるようにしました。

送信機基板(部品面) 送信機基板(裏面)

b) 受信機
 受信機の回路図がこれで特徴としては
赤外線受信ユニットが 5V 動作のため、モーター駆動用の乾電池2本の電源を昇圧することでPICと赤外線受信ユニット用の 5V 電源を作っています。
昇圧用のクロックは回路簡略化のためにPICで作成しています(昇圧前の電圧での動作はPICの規格外ですが特に問題なく動いています^^;)。トランジスタのVbe電圧を基準にしてフィードバックすることで約5Vの電圧にしています。
 精度はそれほど高くなく、電源電圧の下降と共に昇圧電圧もなだらかに下降します。
BootloaderでPICに書込む時はアプリケーションの初期化処理前のためPICからの昇圧用クロックが出力されない状態であり、かつショットキーダイオードでの電圧降下もあり流石にPICの規格外なので電源として乾電池を3本か4本つないだ状態にして書き込みます。
モーターを正転/反転制御するために、FETでブリッジを組んでいますが、モーター用電源電圧よりもPIC側の電源電圧の方が高いため、FETは全てNチャンネルにできます。(Pchも使えるようにプラス側FETとマイナス側FETそれぞれ別々のI/Oで制御しています(PchのFETを使う場合は制御信号を反転する必要がある))。
 FETは秋月さんで購入したフラットパッケージのMOS FET(uPA2753GR)を使うため、基板はハーフピッチのスルホール汎用基板を使いました(慣れるまで半田付けがちょっと大変^^;)。
SW2は受信機のID変更操作用のもので、頻繁にID変更しないのであれば、実装しなくても問題ありません(ID変更する時はPICのRB1を手でGNDへ落とします)。

受信機基板(部品面) 受信機基板(裏面)

 斜めから見るとこんな感じです。

受信機基板(部品面) 受信機基板(裏面)

 
4.処理概要
a) 送信機
 内部クロック4MHz動作で、赤外線LED駆動信号は実行ステップ数調整でタイマ割込みを使用しないで生成しました。50msのタイマインターバルの割込みでスティック状態をチェックし、変化があった場合のみ制御信号を送信します。但し、複数同時使用を考慮して制御信号の送信間隔は最短で 100ms にしています(処理に余裕があるのでこの辺の間隔はソース変更で自由に変更可能)

 この場合、制御信号送信時間を 8ms と仮定し、2人で同時に使用した場合、常にスティック操作している時に制御信号がぶつかる確率を単純計算すると、
  8ms x 2 / 100ms = 0.16
なので、84%の確率で信号が衝突しないことになります(この数値を見るとチャンネル数が16というのは多すぎたか・・・)。

 また、スティック位置に変化がない場合にも 1.5s 間隔で制御信号を送信するようにしています。

 スティック位置はX−Yの2軸の状態で読み取れるので、今回のような左右のモーター制御のためにミキシングモードを設けました。
 ミキシング方式としてはX−Y座標系を45°回転させる方式やX−Yの各代表ポイントでの制御値をテーブルで持ち、内分計算する方法等も考えたのですが、旋回半径を最小にするため最大旋回時には左右の回転方向を逆にしたかったことと処理の簡略化のため次のようにしました。

Y座標値を左右モータの基本スロットル量とする。
旋回情報としてX座標値の1/2の値を左右のスロットルにそれぞれ符号を逆にして加算する。
制御信号のMSB(回転方向情報)を除いた5bitに上記処理を行い、上下限の桁溢れが発生した場合はクリップ処理で範囲内の値にする。

これらの処理によって最大旋回時には左右のモーターが逆方向に回転し、くるりと自転するような操作が可能になります。
 チャンネル(ID)番号、MIXモード/ノーマルモード及び電源電圧アジャスト値をスイッチ操作で設定できるようにし、設定値はPIC内EEPROMに記憶します。
 これらの設定処理等を入れたこともあり、プログラムサイズがフリー版CC5Xコンパイラの上限1Kを超えたため、分割コンパイル方式でリンクしています。


b) 受信機
 内部クロック8MHz動作で、制御信号ディコード用にエッジ割り込みとタイマ割込みを使用しています。
 2項で書いた赤外線受信ユニット出力のON/OFF信号の非対称性のため、エッジ毎にタイミング調整するようにすることでなんとかディコードできるようにしました(今回一番苦労したところ)^^;

 また、左右のモーター制御のために 100us 間隔のタイマ割込みで32段階のPWM制御と正転/反転制御を2ch分行いました(制御信号が6bitなので)。
 ノーコン対策として3.2秒以上制御信号を受信できなかった場合はモーターを強制的にoffにするようにしています。(赤LEDは制御信号受信時に一瞬点灯、ノーコン状態で点灯しっぱなしになります)
 起動時に設定チャンネル数分、LEDが点滅しますが、この間に設定スイッチをONすることでチャンネル数をインクリメントできるようにしました(設定したチャンネル番号はPIC内EEPROMに保存されます)。

赤外線制御マウス?
 コントロール対象はタミヤ製の「壁づたいねずみ工作基本セット」を使用しました(基板ができるとすぐ試したかったので基板取付はとりあえずテープで仮付です)^^;
 少し試すつもりが、結構面白い(特に水平/垂直のA/D変換値をソフトウェアでミキシングし左右のモータ制御としている部分)のでついつい夢中になってしまう。(^^)

★2017/11/19 追記
 受信処理について「PIC24FJで4足ロボットの製作(その8)」のブログの記事に詳細説明を書いています。


5.使用方法
a) 送信機
 同種のLCD表示を付けた電源電流モニタではスイッチ操作がメインなので操作スイッチを3個つけましたが、今回はスティック操作がメインとなることから操作スイッチは2個にしました。スイッチの同時押し操作も可能にすることでそれなりの操作性にできました。^^

1) 電源を入れるとバージョン情報等を表示する初期画面を1秒間表示後、制御信号送信状態(2)になります。

IR control V0.11
Init:Push L&R SW

この時、LスイッチとRスイッチが同時に押されていると初期化処理(EEPROM内のチャンネル番号、モード等を初期化する)が行われます。初めて電源をオンした場合(EEPROM内のデータが0xffの場合)も初期化処理が行われます。チャンネルの初期値は3です。
2) この状態が制御信号送信できる通常の状態です。
この状態ではLCD画面に

mmm:ss ch:nn ddd
vv.vvV L:zz R:rr

と表示されます。
  mmm:ss 経過時間(mmm:分、ss:秒)
  nn:チャンネル番号(1〜16)
  ddd:モード(mix:Mixモード、nor:ノーマルモード)
  vv.vv:電源電圧
  zz:送信する制御値1ch目の値(2桁hex表現)
  rr:送信する制御値2ch目の値(2桁hex表現)

Lスイッチを押すことで経過時間がリセットされます。Lスイッチを押した状態でRスイッチを押すとLCDのバックライトがON/OFF(トグル動作)します。
Rスイッチを押すことで「Change ch」と表示され状態(3)に移行します。
3) Lスイッチを押すことでチャンネル設定状態(4)になります。Lスイッチではなく、Rスイッチを押すと「Change mode」と表示され状態(7)に移行します。
4) Lスイッチを押すことで表示されているチャンネル番号がインクリメントされます。Lスイッチを押しながらRスイッチを押すとチャンネル番号がディクリメントされます。
5) 表示されているチャンネル番号を設定値にしてからRスイッチを押すと「sure? L:yes R:no]と表示され状態(6)に移行します。
6) Lスイッチを押すとLCD2行目に表示されている設定値がEEPROMに保存され、状態(2)に戻ります。Rスイッチを押すと設定がキャンセルされ状態(2)に戻ります。
7) Lスイッチを押すことでモード設定状態(8)になります。Rスイッチを押すと「adjust Power」と表示され状態(9)に移行します。
Lスイッチを押すごとにLCDの2行目に表示されているモードがmix(ミキシングモード)とnor(ノーマルモード)に変わります。設定したいモードが表示された状態でRスイッチを押すことで確認状態(5)に移行します。
9) Lスイッチを押すことで電源電圧アジャストモード(10)に移行します。Rスイッチを押すと「adjust Timer」と表示され状態(11)に移行します。
10) LCDに表示される電源電圧を見ながらLスイッチ(補正値+)、Lスイッチを押しながらRスイッチ(補正値−)の操作で電源電圧をテスタ等で確認した値になるように調整します。調整後Rスイッチを押すことで確認画面(5)に移行します。
11) Lスイッチを押すことでタイマーアジャストモード(12)に移行します。Rスイッチを押すと状態(2)に戻ります。
12) LCDにタイマー補正値が表示されます。Lスイッチ(補正値+)、Lスイッチを押しながらRスイッチ(補正値−)の操作でタイマー補正値を調整します(単位はμSで大きくなると遅くなる)。調整後Rスイッチを押すことで確認画面(5)に移行します。

b) 受信機
 電源投入時に設定されているチャンネル数(1〜16)の回数分、表示用LEDが点滅します。
 この点滅中に操作スイッチを押すとチャンネル番号が一つインクリメントされます(誤操作防止のため、電源投入直後はスイッチoffでLEDがチャンネル表示中にonになった場合のみこの動作をします)
 チャンネル表示終了から1秒後に制御信号を受信するモードになります(電源を切るまでずっとこのモード)。
 制御信号を受信すると一瞬LEDが点灯します。また、一定時間制御信号を受信できなかった場合には、LEDが常時点灯となり、モーターの電源が強制的にオフ状態になります。


6.ダウンロード
送信機のhexファイル(Ver0.11)
送信機のhexファイル(Ver0.10)
受信機のhexファイル
送信機の回路図
受信機の回路図

※:商用利用の場合は本ページに記載の内容を許可なく使用することを禁じます。


[history]
2009/03/29 Ver0.11   added timer display and adjust timer parameter for controller
2009/03/15 Ver0.10   first published by T.Satoh

[TopPage] -> [PIC] -> [ IrController ]  |   [blog1] [blog2] [blog3:PIC24FJへの実装]