赤外線リモコンの検討(構想編5)

f:id:torusanada98:20210807184838j:plain

構想編5

割り込みに対応したコードをさらに見直します。

コードの見直し

現状のコードのパルス長の読みとりにはpulseIn()関数を使用しています。この関数にはタイムアウトの設定ができますが、現状は設定していません。ネットで検索すると、デフォルトのタイムアウト時間は1秒との事でした。以下の状況では1秒間処理がMain loopに戻らない事になります。

1)赤外線が点灯したままの状態

2)赤外線が一旦消灯し、再点灯しない状態

という事でタイムアウトを設定する事にしました。下記が赤外線リモコンNECフォーマットですが、Leader長を考慮すると24T以上の時間以上を設定する必要があります。

f:id:torusanada98:20210807184901p:plain

562us x (16 + 8) = 13488us

一旦13500usを設定して確認してみまた。その時の動作波形は以下のとおです。

f:id:torusanada98:20210807184925j:plain

Leader検出前にpulseIn()関数がタイムアウトして正しく受信ができません。タイムアウト時間は13500usに設定しているにもかかわらず9400usでした。この結果から約1.5倍くらいの設定時間が必要となります。試しにタイムアウト時間を20500usに設定したところ正しく受信できるようになりました。どうして誤差が大きいのかpulseIn()関数について調べてみたところ、この関数の時間計測にはマイコンの処理ステップ数を使用しているとの事がわかりました。さらに調べたところ、タイマー割り込みを使用した同等の機能のpulseInLong()関数がある事がわかりました。関数を変更して改めてタイムアウト時間を13500usに設定してみたところ正しく動作する事が確認できました。タイムアウト時間は余裕を見て15000usとします。同様にデータビットの読み込み部分も約5Tに相当する2900usのタイムアウト時間を設定しました。

処理の見直し

Int0で実行される受信処理の最後に、2重受信防止の為に130msのwaitが入れられています。

f:id:torusanada98:20210807184958p:plain

この間、Main loopが走らないのは無駄なので、Main loop内で130msのwaitの実装を検討します。変更の概要は以下のとおりです。

・受信処理のdelay(130)を削除

・かわりにタイマー用のレジスタを初期化して、IR_WF=0(Int0有効化要求なし)

・10msのタイマー割り込み(MStimer2)を設定して以下の処理を行う

 タイマーのカウントアップ

 130ms経過でIR_WF=1(Int0有効化要求有り)&タイマーカウントアップ無効

タイマー割り込みMsTimer2は以前に一度使っているのでおさらいします。仕様概要は以下のとおりです。

・ライブラリMsTimer2.hをインクルードする

・設定はMsTimer2::set(ms, 関数)で行う

・割り込みの有効化はMsTimer2::start()

・割り込みの無効化はMsTimer2::stop()

それでは具体的な実装を紹介します。最初はタイマー割り込み処理IR_wait()です。

f:id:torusanada98:20210807185050p:plain

Int0処理と同様に処理の先頭で多重割り込みを許可します。Int0が有効時はそのままretrunします。無効時はタイマを10msカウントアップして、タイムアップ判定を行います。タイムアップ時はIR_WF=1としてMain処理へInt0有効化を要求します。次はInt0割り込み処理です。

f:id:torusanada98:20210807185118p:plain

delay(130)を単純に無効とするのではなく、必要なフラグ設定を行います。最後にMain処理です。

f:id:torusanada98:20210807185141p:plain

IR_WF=1(Int0要求化要求)を検出するとInt0を有効にします。念のためフラグ処理前後でタイマー割り込み処理を止めています。この対応による効果は以下のとおりです。

f:id:torusanada98:20210807185205j:plain

f:id:torusanada98:20210807185216j:plain

上が修正前で、下が修正後です。受信処理で割り込みが210msCPUを占有していましたが修正により占有期間が66msに短縮されました。リモコン処理後に約15ms割り込み処理が走りますが、Int0無効時の立ち下がりエッジが保存されていて、Int0有効とした時に一旦割り込みを走っているようです。試しにInt0のトリガ条件を立ち下がりからLOWに変えてみました。

f:id:torusanada98:20210807185248j:plain

Int0有効に変えた時の割り込み発生が押さえられました。次回は作成したコードのDACユニットへの組み込み検討を行います。

 

つづく(構想編6)