前回までで送信プログラムをある程度作成できたので、今回から受信プログラムを作っていきます。
受信プログラムの検討に入る前に、全体的な回路構成や受信データについての注意点など、周辺について説明します。
全体的な回路構成
下に、受信側の回路構成を示します。
戦車は左右にキャタピラがあり、それぞれをモーターで動かします。また、探照灯としてのLEDがあります。これらをPICで制御します。
ただし、PICでモーターを直接制御することはできないので、L9110というICを経由して制御しています。後述しますがこのICは2つの入力端子で制御できます。PICとしては左右のモーターを制御するために4つの出力端子を使う事になります。
また、LEDは1つの出力端子で制御(点灯)します。
赤外線受信モジュールからの信号は1つなので、1つの入力端子を使う事になります。
したがって、総計で、1つの入力端子と5つの出力端子を使うことになります。
モーターの制御について
赤外線受信の話からは少し脱線しますが、モーター制御についての話をします。というのもモーター制御の話が赤外線受信にも少し影響があるからです。
今回はL9110という8ピンICを使ってモーターを制御することにしました。このICは1つで1つのモーターを制御することができます。
OAとOBをモーターにつなぎ、IAとIBを制御するとモーターが正転/逆転します。Hブリッジ回路のようにブレーキをかけることはできないようです。データシートには、それっぽいことが明記されていません。
モーターの制御と言えば、PWMのDuty比を変えることで回転速度を制御することが一般的です。しかしこのICには、PWM制御についてデータシートには記載がありません。
いろいろと実験してみたのですが、高い周波数(100kHzとか)では、まともに動作しませんでした。例えばIBをLに固定しIAをDuty比50%のPWMで制御しても、OAの電圧が上がりませんでした。IAの変化が早すぎると、ICが信号を正しく認識できないようです。(High/Lowが平均化されてしまって、単調なHighやLowとして入力されてしまっているか、あるいはIC内部のOAやOBをドライブする部分が追い付かなくなるのかもしれません。)
L9110はとても安価なICなので、もっと単純な正転/逆転/停止にしか対応していないのでしょう。ある程度動いたのは100Hz未満の周波数でした。PWMと言ってよいのか?というレベルですが、Duty比を変えることでモーターの回転速度を制御するには、それぐらいの周波数に落とさないとダメだったのです。
そしてこれが1つの問題となりました。当初はPICのPWM機能を使うつもりでした。「赤外線を受信する→受信データに応じて、PWMの設定を変える。」という形だとプログラムの作成が楽です。
ところが100Hz未満の周波数だとPICのPWM機能を使う事ができません。PICのPWMの周波数はTMR2の設定とPICの動作クロック周波数で決定されます。100Hz未満の周波数でPWMを動かそうとすると、動作クロックを遅くしなくてはなりません。
そのために動作クロックを遅くすると、赤外線受信処理に影響があります。受信した赤外線を解析するときに、100usecオーダーの信号変化を検知する必要があるためです。またただ検知するだけで終わりなのではなく、検知した後はモーターを制御することになります。そういった処理が完了する前に次のパルス変化が来てしまうと、全体的な処理に支障が生じ、処理落ち状態になってしまいます。動作クロックを遅くすることはできません。
したがって、動作クロックは落とさず、モーター制御はソフトウェアPWMで行うことにしました。赤外線受信の処理とモーター制御のPWM処理を同時に両立できるように、注意して設計していく必要があります。
受信プログラムの周りの機能について
今回の赤外線通信は、赤外線リモコン戦車のために作成しています。このため、次の4つの機能をPICで処理することにしました。
- 赤外線受信機能:赤外線モジュールの出力値を、いずれかのポートから読み取り、信号を解析して8bitのデータにする。
- 戦車制御機能:戦車のモーターのスイッチをON/OFFする。単純なON/OFFではなく、正転/逆転を制御したり、ソフトウェアPWMでパワーを制御する必要がある。また、モーターは右キャタピラ用と左キャタピラ用の2つある。またモーターだけでなく、照明灯用LEDの制御も行う。
- 受信と制御の連絡機能:赤外線受信した8bitデータを解析して、戦車やLEDの制御に受け渡す。
- 停止機能:赤外線受信が無くなったときに、モーターを停止させる。この機能がないと、戦車が赤外線の届かない距離に移動したときに、(戦車の電池が切れるまで)永遠に移動し続けるので、ますます赤外線が届かなくなる。
送信と受信のタイミングの違い
赤外線受信モジュールは、赤外線のパルスの有無によって、OUT端子の信号値が変化します。
今、送信側からパルスのON/OFFを400usec毎に切り替えて送信するケースを考えてみましょう。
このとき、受信モジュールのOUT端子の信号値は、パルスがONのときはLowになり、OFFのときはHighになります。しかしその間隔は400usecにはなりません。データシートによれば最大で200usec程度のずれが生じます。そのため例えば「Lowが200usec、Highが600usec」になったり、逆に「Lowが600usec、Highが200usec」になったりする可能性があるのです。
今回の赤外線リモコン戦車を作成するために実験回路を作って測定したところ、送信側が400usecの間パルスONにしたとき、受信側は140usec~380usecの間Lowになりました。また400usecの間パルスOFFにしたとき、500usec~660usecの間Highになりました。常に一定のずれがあるのではなくバラツキがあるのです。
したがって送信時間通りに「Lowが400usecならばパルスONが400usec」と判定することはできません。上の実験結果をそのまま採用するなら、「Lowが140usec~380usecなら、パルスONが400usecだった」と判定しなければなりません。High(パルスOFF)に対する判定も同じようになります。
ただし、時間がズレるといっても送信側のONに対する受信側Lowの時間が減れば、OFFに対するHigh時間は増えるはずであり、送信側の「ONとOFFの合計時間」と受信側の「LowとHighの合計時間」はだいたい同じになるはずです。(ここもバラツキの影響があるため、完全に同じにはなりません。)
そこで受信時の判定としては以下のように判定することにしました。
- 受信側は「Lowの時間」と「Low+Highの時間」を用いて判定する。
- 受信側は「Lowの時間が(N-300)usec以上、かつLow+Highの時間が(M±200)usec」の信号を受け取った場合、「パルスONがN usec、パルスON+OFFがM usec」の信号を受信したと判定する。
例えば、送信側がリーダ部を送信するときは「パルスONが3200usec、パルスOFFが1600usec」を送信します。この場合Nは3200、Mは3200+1600=4800なので、受信側は「Lowが2900usec以上、かつ、Low+Highが4600~5000usec」を受信したら、「リーダー部を受信した」と判定するのです。ビットデータの受信も同様です。
受信データ
今作っている送受信のプログラムでは、1セットの通信で1byteのデータを送信できます。
今回のリモコン戦車では、その1byteのうち5bitにだけ情報を送信することにしました。その内訳は下の通りです。
ビット番号 | 説明 |
1と0 | 戦車のスピードや進行方向を2bitで表す。 00: 停止 01: 前に進む 10: 前に進む(01より高速) 11: 後ろに進む |
3と2 | 車体の方向変化を2bitで表す。 00: 車体の方向は変化しない 01: 車体を右に傾ける 10: 車体を左に傾ける 11: エラー値。2ビット目と3ビット目が同時に1なることはない。 |
4 | 探照灯用LEDを制御。 0: LEDをOFF 1: LEDをON |
7-5 | 未使用 |
4ビット目のLEDについては単純なON/OFFですが、3-0ビット目は少し複雑になります。
戦車のモーターがが完全に停止するのは、3-0のビットが0000のときだけです。
例えば、0100のときは、位置は変化せずに車体を右に傾けようとします。つまり、左モーターは前進、右モーターは後進にして、超信地旋回で右に回転しようとします。
また、1001のときは、車体を前に進ませつつ、車体を左に傾けようとします。このときは左のモーターを停止して、右モータだけ前進させます。
つまり1-0ビット目は車体の中心がどこにあるのかという観点で、停止や前後に進むことを表しています。
全パターンについてはプログラムの作成のところで説明する予定です。
使用するPICについて
今回、受信側で使用するPICはPIC16F1503にしました。
選定理由はいくつかあります。
- 当初PWM機能を4つ使うつもりだった。そのため8ピンPICは想定外になった。16F1503が条件にマッチした。(ただし、ソフトウェアPWMにすることにしたので、この条件はどうでもよくなりました。)
- ソフトウェアPWMにすることが決まった後でも、入力で1、主力で5つの端子を使うので、8ピンPICだと端子数がギリギリになってしまい、リセット端子も使わないとならない。
- 14ピンだと端子に余裕があるため、プログラマ用の端子を専用にできる。(赤外線リモコン戦車のための端子と兼用しなくてすむ。)その結果、DIP品ではなく、SOP品を使うことができ、基板が小さくできる。
- 価格がやすい。16F1503はどちらかと言えば安いです。選定当時、秋月電子でも8ピンの12F1822より14ピンの16F1503の方が安かったです。実際に使ったのはAliExpressで探して購入したものでしたが、DIP8よりSOP14の方が全般的に価格が安いです。
コメント