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

f:id:torusanada98:20210803072530j:plain

構想編4

サンプルコードを実装用に改変します。

サンプルコード

前回の記事で確認したサンプルコードですが、処理を理解する観点では良かったとおもいますが、DACユニットへ実装する観点で見直してみます。最初に簡単な実験を行ってみます。サンプルコードを関数化(IR_process())し、ダミーのMain loopへ組み込んでみました。Main loopでは100msのダミー処理(delay(100))も組み込んでいます。

f:id:torusanada98:20210803072558p:plain

このプログラムを実行してみました。

f:id:torusanada98:20210803072633j:plain

上の波形が受信モジュール出力で、下がMain loopを走っていいる時に'H'になる信号です。受信完了後のわずかなタイミングのみMain loopを走るのみで、受信処理がCPUをほぼ100%占有しています。原因はsamplecodeのleader受信確認処理です。

f:id:torusanada98:20210803072703p:plain

上記のとおり、Leader確認処理に入ると局所ループ(do{} while文)でLeaderを受信するまで処理を抜けません。まずは試しに、受信処理の最初に受信モジュール出力のチェックを追加して'H'(消灯)時には処理を抜けるように修正してみました。

f:id:torusanada98:20210803072725p:plain

このときの受信波形は以下のとおりです。

f:id:torusanada98:20210803072749j:plain

非同期な受信チェックの為、正しくコマンド受信ができませんでした。これを解決するには受信処理を割り込み処理にするしかありません。

arduino UNO外部割り込み

arduinoでは以前タイマー割り込みを使ってLEDのブリンクをさせた事はありますが、外部割り込みは初めての経験です。arduino UNOの外部割り込み仕様を調べてみました。

・Int0(2pin)とInt1(3pin)が使用可能

・エッジ割り込みとレベル割り込みの計4種類のトリガ条件の設定が可能

・attachInterrupt()で割り込みを有効

・dettachInterrupt()で割り込み無効

・割り込み処理内はデフォルトで割り込み処理は無効

受信処理の割り込み化

上記を踏まえて受信処理の割り込み化を検討します。検討結果は以下のとおりです。

・受信モジュールとの接続はこのままとしてInt0を使用する

・受信モジュール出力の立ち下がりで割り込み処理実行

・割り込み処理の先頭で外部割り込みを無効化(Int0の多重割り込み禁止)

・他割り込み処理有効化(多重割り込み許可)

・先頭の'H'パルス期間がLeaderと不一致の場合return

・一致の場合は、samplecodeの受信処理を実行

・割り込み処理を抜けてから外部割り込み有効化

まずは上記を反映したsetup()とloop()処理です。

f:id:torusanada98:20210803072821p:plain

setup()内でInt0を有効化しています。Main loopの2カ所でIR_WF(外部割り込み無効フラグ)が1の時にInt0を有効化しています。続いて受信用割り込み処理です。

f:id:torusanada98:20210803073135p:plain

上段がLeader検出処理で、下段が受信処理です。処理を抜ける際に、外部割り込み禁止状態(IR_WR=1)としています。下図が実行時の統合環境画面です。

f:id:torusanada98:20210803072958p:plain

早速コンパイルして実行してみます。シリアルモニタに受信コードが正しく表示されています。さらに下図は実行時の波形モニタ結果です。

f:id:torusanada98:20210803073040j:plain

青の波形は、割り込み処理実行中'H'を示しています。これで受信処理がCPUを占有する事がなくなりました。次回はこの割り込み処理をさらに改善検討して、DACユニットのファームウェアへの移植の検討もします。

 

つづく(構想編5)