リモコンコードの読み込み

こんにちはRooL78と申します。

リモコン受信信号のリーダ部のHigh・Low幅(Low→High及びHigh→Low)を測定するため
入力ポートの割込み(INTP5)とTAU0のインターバルタイマ(1usec)を用いて実現したいのですが、
リーダの最初のHigh→Lowのパルス幅の測定がうまくいきません。
オシロ波形の実測値よりも半分以下の値になり、何度か繰り返すと5回程度に1回は正しい値になります。

※因みにですが、High→Lowパルス幅のあとのLow→Highの幅の方は毎回正しい値で問題ございません。

ソフトとしましてはPIF5が1になっているかポーリング方式でモニターし、なっていたら
(確認後はすぐにPIF5を0にセットする)、すぐにTAU0をスタートします。
そして、再びPIF5が1になっているポーリング方式でモニターし、なっていたらTAU0をストップします。
そのあと、TAU0のタイマーのカウント値を取り込んでおります
※INTP5は両エッジ検出モードです

使用マイコン:RL78 G14

お手数をおかけ致しますが、宜しくお願い致します。

  • チョコです。

    リモコンの信号としては、検波した(キャリアを削除した)リモコンのベース・バンドの信号を入力しているものと考えます。

    まず気になるのは、リモコン信号は受信モジュールーからオープン・コレクタ信号で出力されていると思いますが、信号線にノイズが載っていることはないでしょうか。プルアップ抵抗の値が大きすぎて、ハイレベルが弱くなり、ノイズ(キャリア信号の漏れ等)が載っている(ロウレベルは出力トランジスタで引っ張っているので、ハイには上がらない)可能性はないでしょうか。

    次に、1usecのインターバルタイマの周期はリモコン信号用としてはかなり短いようですが、タイマのカウントクロックの周期が1usecということでしょうか。

    ソフトでの処理として、最初の測定開始のタイミングはどのようになっているのでしょうか?

    INTP5を使っているということは、その端子にはTM01の入力も兼用になっているので、TM01で入力パルス間隔測定機能を使ったらどうなるでしょうか。

  • チョコさん

    早急にご回答有難うございます。

    >リモコン信号は受信モジュールーからオープン・コレクタ信号で
    >出力されていると思いますが、信号線にノイズが載っていることは
    >ないでしょうか。

    はい。オシロで再度確認しましたが、受信時にノイズが重畳されいる様子はありませんでした
    尚、今回用いた受信モジュールは回路内部で電源とプルアップされておりまして
    かつ、データーシートの推奨通り出力端子直近で外部抵抗22kΩでプルアップしております。

    >次に、1usecのインターバルタイマの周期はリモコン信号用としてはかなり短いようですが、
    >タイマのカウントクロックの周期が1usecということでしょうか。
    はい。コード生成のインターバル時間(16bit)を1usecに設定しております。
    INTTM00の割込みが入る度に変数をカウントアップしております。
    リーダパルスの後のデータパルスが350usec±3%なので、
    厳しめにサンプリングとしてインターバル時間を1usecに設定しました。
    ※10usecにしても変わりませんでした。最初のHigh→Lowの幅の値が不安定です

    >TM01で入力パルス間隔測定機能を使ったらどうなるでしょうか。

    パルス間隔機能ハイ・ロウ測定(両エッジ)も考えてみたのですが
    アプリケーションノートには"1回目に TDR00 レジスタにキャプチャされた値は
    意味を持たないため使用しません"とあり、
    二回目のエッジから有効になるそうなのでリーダパルスの最初のHigh→Lowの
    測定がうまくいかないと思い、試みませんでした。

  • チョコです。

    >はい。オシロで再度確認しましたが、受信時にノイズが重畳されいる様子はありませんでした
    >尚、今回用いた受信モジュールは回路内部で電源とプルアップされておりまして
    >かつ、データーシートの推奨通り出力端子直近で外部抵抗22kΩでプルアップしております。

    オシロの時間軸がどの程度かわかりませんが、信号線に高速(1usec以下)のノイズが重畳していればわかりますか?

    モジュール内部に抵抗が内蔵されているのは知っていますが、外部の22kΩで十分にインピーダンスが下がっているかは気になります。(ロウの幅はきちんと測定できていることからの疑問です。)

     

    >最初のHigh→Lowの幅の値が不安定です

    ここらが、入力パルス間隔測定機能で触れている1回目のキャプチャ結果の不定と同じ理由だと考えています。

    これは、測定方法に依存しません。PINT5は本当に立ち上がりエッジを検出していますか?(信号がロウの段階で計測を開始しているかが気になります。)

    >※10usecにしても変わりませんでした。

    1usec場合に気になるったのは、頻繁に割り込みが入るので、PIF5のポーリングが実行できなくてタイミングがずれてしまう可能性も考えていたのですが、10usecでも変わらないのであれば、関係なさそうですね。(入力パルス間隔測定機能のことを紹介したのは、ポーリングがきちんとできない可能性を考えたからです。)

    残りは、測定開始前にPIF5がクリアされているかです。

    ところで、両エッジであれば、立上がり/立下りの確認はどうされていますか。

  • チョコさん

    お世話になっております。
    有難うございます。

    >オシロの時間軸がどの程度かわかりませんが
    >信号線に高速(1usec以下)のノイズが重畳していればわかりますか?
    すみません、再度確認しました
    100nsecくらいまで時間軸をひろげて確認致しましたが、
    ノイズはなく(プローブ+グラウンドスプリング)問題なさそうです

    >外部の22kΩで十分にインピーダンスが下がっているかは気になります。

    外部抵抗を2.2kΩ/4.7kΩに変更し再度テストしましたが、
    現象は変わりませんでした。

    >残りは、測定開始前にPIF5がクリアされているかです。
    while (1U)
    {
    if(PIF5==SET){
     PIF5=CLR;
    はい。クリアにております

    >ところで、両エッジであれば、立上がり/立下りの確認はどうされていますか。
    一番最初のリーダーパルスのHigh -> Low だけは確認しておりません
    If(PIF5==SET)のあと、自作関数内でP16端子の状態を変数に格納し次のIf(PIF5==SET)で
    前回のP16の状態を格納したレベルと比較しております。

  • チョコです。

    >100nsecくらいまで時間軸をひろげて確認致しましたが、
    >ノイズはなく(プローブ+グラウンドスプリング)問題なさそうです

    そうするとハードの可能性は低いですね。

    そうなると、残ったのは、測定開始とリーダーパルスのタイミングの問題ですね。

    >一番最初のリーダーパルスのHigh -> Low だけは確認しておりません

    信号がL→Hのタイミングから計測開始しないといけないのに、そこがきちんとできてないですね。

    最初にP16がLになっていることを確認する必要があり、そこから最初のエッジ検出で計測を開始してください。

    そうでなければ、最初は立ち上がりエッジ検出に設定しておき、エッジ検出したら、立下りエッジも許可すべきです。

  • プログラムを修正して確認しましたが、リモコン受光信号の時間をうまく補足できず

    改善できませんでした。

    そこで他のタイマーなど割込みが重なっていて、取り込みタイミング(きっかけ)となる

    INTP5の割込みがリモコン受光信号の両エッジを捉えていないのではと思い、

    新しいプロジェクトを作成しなおして、INTP5の割込み以外の何もない簡単なプログラムを

    作成して確認してみました。(使用ボード:c-First) 下記のようなプログラムでINTP5の割込みが

    入ると、D7 (P02ポート)をHighにするだけのプログラムです。
    D7のクリアは
    メインループ側でD7 = CLR;にしております。(メインループも左記以外は何もありません)

    static void __near r_intc5_interrupt(void)
    {
    /* Start user code. Do not edit comment generated here */

    D7 = SET;
    PIF5 = CLR;

    /* End user code. Do not edit comment generated here */
    }

    そして、リモコン受光信号を入れてオシロで観測しましたところ、信号の2割~6程度くらいしか

    立ち上がり・立ち下りに反応しておりませんでした。

    ※高速オンチップオシレータの設定など変更して改善しませんでした

    ちょっとお手上げになってきました

  • チョコです。

    この新しいプロジェクトをzipにして添付することはできませんか。

  • >この新しいプロジェクトをzipにして添付することはできませんか。

    お手数をおかけ致しますが、宜しくお願い致します

  • > 下記のようなプログラムでINTP5の割込みが入ると、D7 (P02ポート)をHighにするだけのプログラムです。
    D7のクリアはメインループ側でD7 = CLR;にしております。(メインループも左記以外は何もありません)

     割り込み処理から抜けると、すぐに D7 = CLR; が実行されるんですか?
     D7は髭のような波形に成りますね。オシロの時間的な分解能が無いと見落としますが大丈夫ですか?

     髭を見るのでは無く、割り込み処理の中でD7を反転させれば良いのに。
     そうすれば入力信号と同じ波形になる。場合によっては反転するけれど。

  • チョコです。

    プロジェクトをざっと眺めてみましたが、エッジ検出ごとに、P02に0.5usec程度の幅のパルスが出るだけのプログラムですね。

    main処理をNOP()だけにして、何もしないようにしました。INTP5の割り込み処理は以下のようにD7を反転するようにしてみました。(PIF5は割り込みを受け付けると、ハードで自動的にクリアされるので、ここでクリアする必要はありません。)

    static void __near r_intc5_interrupt(void)
    {
    /* Start user code. Do not edit comment generated here */

    D7 ^= 1;

    /* End user code. Do not edit comment generated here */
    }

    シミュレータの信号で9msecのハイと4msecのロウの信号を作っています。

    下の入出力パネルで入力信号とD7出力の波形を記録するようにしています。

    このプログラムは実行すると、入力した信号と同じような信号が得られます。

    (時間軸が長すぎて、分かりやすい波形にはならなかったので画面イメージは付けません。)

    この変更を行って、実際の信号を入れて波形を確認してください。同じ波形(または、反転した波形)が得られるはずです。

    そうなると、INTP5は正常に動作していることになります。

    以上

  • チョコさん
    お世話になっております
    有難うございます。教えて頂きました通りに実行いたしましたら
    無事に動作致しました。

    早急に(しかも夜遅く)ご対応下さり誠に有難うございました。




  • リカルドさん
    ご指摘誠に有難うございます

  • チョコです。

    G14_test_TIMER.zip

    RL78でのパルス間隔測定の動作例をまとめてみます。

    赤外線リモコンの信号のリーダー信号は、NECフォーマットではハイが9msec、ローが4.5msecなのですが、赤外線リモコンのレシーバの出力は負論理です。そこで、13.5msec周期でデューティ33%PWM信号を入力します。

    この信号を測定する入力パルス間隔測定で使用するTM01は、カウントクロックとして1usecで動作させます。最初は立下りエッジ検出(検出リモコン信号は負論理なので、リモコン信号の立ち上がり相当)で起動します。キャプチャの割り込みが発生したら、両エッジ検出に変更します。

    TM01割り込み処理プログラムは以下のようになっています。

    最初の赤で囲んだ部分は、コード生成されたそのままで、その後に処理を追加しています。

    次の青で囲んだ部分は端子の状態を読み出して、立下り(つまり測定したのはハイの区間)なら見やすいように頭に8が付くようにデータを細工して配列(TM01_data)に格納しています。

    緑で囲んだ部分は、立下りエッジ検出で起動したのを両エッジに変更する処理です。タイマ・モード・レジスタ(TMR01)の有効エッジを変更している部分です。有効エッジ検出だけは、タイマの動作中に変更することができます。

    次のオレンジ色で囲んだ部分が、割り込みの回数をカウントし、16回完了したら、whileでループするようにしています。ループの中のNOP()でブレークポイントを設定して、16回キャプチャしたら、実行を停止するようにしています。

    16回のキャプチャ結果を以下に示します。

    最初のキャプチャ値[0]”80007818”となっていますが、頭の8TI01のハイ期間を示します。最初が立下りエッジ検出割り込みなので、その直前は当然ハイになります。その幅が、7818usec)となっています。ここで、入力信号のハイ幅より大きいのは、下に示すように、測定を開始したのはハイ期間の前のロー期間だったからこのような値になったと考えられます。

    これが、パルス間隔測定で、最初のキャプチャ値が使えない理由です。要するに、パルスの変化点から計測を開始していないことが理由なので、どのような測定方法を行ってもパルス間隔測定の最初の測定値は使えません。ちなみに似たような機能であるパルス幅測定は、最初に、指定された極性になるのを待ってから測定を開始するので、きちんとした期間が測定できます。

    [1]は9037usec)となり、この部分がリーダーの先頭部分になります。[2]4451usec)はリーダーの後半部となります。

    以下、9msecのロー期間と4.5msecのハイ期間が連続していて、パルス間隔測定が正しく動作していることが分かります。値が細かく変動しているのは、PWMの発生元(RL78/G13)と測定側(C-First)のクロックが非同期になっているのと、HOCOの精度は1%だからでしょう。

    以上

  • パルス幅を検出するなら、フリーラン・カウンタを用意します。

    フリーラン・カウンタとは止まらないカウンタで、最大値になったら次はゼロになる。

    エッジの割り込みでカウンタ値を読み記録しておきます。

    次の割り込みでカウンタ値を読み、前回の値との差を求めればパルス幅が分かります。

  • チョコです。

    パルス幅を検出するなら、フリーラン・カウンタを用意します。

    それは、RooL78がやろうとしていた方法と類似の方法ですね。RL78では、インターバル・タイマで0xFFFFをセットして、インターバル割り込みを無視すればフリーランと同じに動作になります。

    どちらにしても、1回目の割り込みまでは無視することになる点は同じですね。