Config_ICUでのIRQの設定について

いつも大変お世話になっております。リューキィです。

現在、RX65N Envision Kitでロータリーエンコーダを使用した試作機の開発をしているのですが、

信号の入力も表示も出来ているのですが、なぜか1回転した時の数字がズレてしまう事が多々発生してしまっています。

ロータリーエンコーダの接続の方法や、接続端子の接触不良等も疑ったのですがどうやら問題なさそうで、次にマイコン側の端子の設定

を疑っている次第です。

13chのD7(IRQ1)とD6(IRQ2)ロータリーエンコーダの信号線は接続しており、

モジュールのConfig_ICUでIRQ1/2ともに立上りエッジのレベル15 フィルタ無しにしてあります。

また、メインソース上で

R_GPIO_PinDirectionSet( GPIO_PORT_D_PIN_1, GPIO_DIRECTION_INPUT );
gpio_err |=R_GPIO_PinControl (GPIO_PORT_D_PIN_1, GPIO_CMD_IN_PULL_UP_ENABLE);
R_GPIO_PinDirectionSet( GPIO_PORT_3_PIN_2, GPIO_DIRECTION_INPUT );
gpio_err |=R_GPIO_PinControl (GPIO_PORT_3_PIN_2, GPIO_CMD_IN_PULL_UP_ENABLE);

で入力端子設定とプルアップ設定も行っております。

(※もしかしたらこれが二重設定とかになっていて邪魔をしているのか??とも思い始めました)

また、ロータリーエンコーダのカウントは

IRQ1が立ち上がった際に、IRQ2の状態を見て0だったらカウントをインクリメント

IRQ2が立ち上がった際に、IRQ1の状態を見て0だったらカウントをデクリメント

としています。(それぞれの立ち上がりを見ずとも、一行目にelseでデクリメントすれば良いのもわかっているのですが、ズレが発生しているので何か問題があるのかもと思い、わざと

分けてあります)

ロータリーエンコーダの1周の分解能は40なので、非常に少ないのですが数回転回すとズレる状態です。

何かわかる方がいらっしゃいましたら、ご指導いただきたく思います。

よろしくお願い致します。

Parents
  • リューキィさん、こんにちは。NoMaYです。

    その後、どうでしょうか?既に解決済みでしょうか?前回の後、hirakuni45さんからアドバイスがあったものの、他には、発生しているトラブルの原因の特定に繋がりそうな、また、その原因の回避策に繋がりそうな、そういうリプライは無かったですね。

    実は、あれから何か調査方法はないかと以下のスレッドで私は考えていたのですが、ちょっと難易度が高いかな、という案しか思い浮かばなかったのですが、今しがた、難易度は低めだろう、と思われる案が思い浮かびました。

    難易度は低めだろう、と思われる調査方法案

    (1) 今のプログラムとは別にもうひとつプログラムを作る
    (2) LCDの表示とかそういったものをバッサバッサと捨てて、ロータリエンコーダの信号を調べることのみに専念するプログラムを作る ← 重要
    (3) 1μsec程度でカウントアップするフリーランカウンタをRXスマートコンフィグレータのCGコンポーネントで作る
    (4) まずはロータリエンコーダのA相の信号をP32(IRQ2-DS)とPD1(IRQ1-DS)に入れる
    (5) P32(IRQ2-DS)では立ち上がりエッジのみ検出し、PD1(IRQ1-DS)では立下りエッジのみ検出する
    (6) 検出したら上記の(3)のフリーランカウンタの値をメモリにどんどん残していく
    (7) 文房具屋さんへ行って方眼紙を買ってくる
    (8) 買ってきた方眼紙上で上記の(6)で集めたデータをプロットしてロータリエンコーダの信号の波形を手作業で描いてみる
    (8') 最近、日本で、未だにFAXが使われているとか、未だにフロッピーディスクが使われているとか、話題になったけれども気にしない ← 重要
    (8'') たぶん、ロボットを多用した最先端の自動車工場でも、人手で何かをやっている作業は存在する(と思うのだけれども)
    (9) A相の確認が出来たらB相についても確認する

    (10) もし波形にバタつきが見られたら、それを証拠にロータリエンコーダのメーカさんに原因として考えられることを聞く
    (11) そして波形にバタつきが見られたら、それで症状の説明が付くか考察する
    (12) また波形にバタつきが見られたら、機械式ロータリエンコーダのチャタリング除去と同じやり方を実装してみる

    (X) バタつきが見られなかったら、その時は、また、何か考える

    [メモ]

    あれこれ考えていた別スレッド

    FIT R_SCI_RXモジュールでprintfをfrom inside interrupt routine内から行えるかどうか考えてみるスレッド
    community-ja.renesas.com/cafe_rene/forums-groups/tools/f/forum21/9610/fit-r_sci_rx-printf-from-inside-interrupt-routine/46949#46949
     

  • NoMaYさん、こんにちは。リューキィです。

    いつもいつもありがとうございます。別件の締切が差し迫った仕事が山積みになり、そちらに明け暮れていました。

    ロータリーエンコーダですが、どうもギアの嚙み合わせでのバタつきやノイズ等もかなり影響しているのでは?というところで作業が止まっています。それらを確認するために配線の整理をしたりしていたのですが、また別でコンパイル中にエラーログが出るようになり、それを解析してみようと試行錯誤してたところ、ぐちゃぐちゃになっている状態です。エラーログ自体が意味不明な表示が多いので、難易度が高いです。。。話がそれてすみません。

  • >バタつきやノイズ等もかなり影響しているのでは?

    メカスイッチで2相信号を作り、片側のスイッチをガチャガチャ動かせば良いのです。

    カウント値が1だけ前後して元に戻れば問題無し。

    カウント値が2以上変化したら問題有り。

  • 改行ミスりました。。。

    ご教授ありがとうございます。今エラーでまともに動かない状態になってしまっているので、動くようになったら試してみたいと思います。これからもよろしくお願い致します。

  • NoMaYさん、こんにちは。リューキィです。

    オシロが手に入ったので、エンコーダの信号を見てみました。

    結果としては、あくまでマイコンに接続してエンコーダを回してみた状態での計測ですが、エンコーダからの信号は問題なく出ている様子でした。しかし、つながったマイコンのカウント表示は低速回転時にはズレは感じませんでしたが、高速回転させると明らかにおかしくなってしまいました。(増減が互い違いに入っているのか、なかなか数字が進まない状態)

    オシロ側の信号のバタつきやノイズは見受けられずだったので、hirakuni45さんからご指摘頂いた割込み処理の方を確認しようと思っています。しかし、ハードルの高さも感じているので、何か良いアドバイスをお持ちではないでしょうか?

    よろしくお願い致します。

  • リューキィさん、こんにちは。NoMaYです。

    入手されたオシロは何chのものでしょうか?

  • NoMaYさん、こんにちは。リューキィです。

    2CHでした。

  • リューキィさん、こんにちは。NoMaYです。

    では、以下のようにした場合の波形が見たいです。

    (1) ポート出力を1本確保する
    (2) ロータリーエンコーダの回転角をカウントアップする時に(1)のポート出力をトグルする
    (3) ロータリエンコーダのA相の信号波形と(1)の波形を同時にオシロに表示させて異常個所を探す

    (4) オシロにどれくらいのデータバッファがあるか分からないが適切にトリガを掛ける方法が咄嗟に分からないので暫くの間は闇雲に探してみる

  • NoMaYさん、こんにちは。リューキィです。

    すみません。。。

    ⑴と⑵の意味がわかっていません。。。⑴は今のA相とB相はP32とP33なので大丈夫なのでしょうか??

Reply Children
  • リューキィさん、こんにちは。NoMaYです。

    うっ、、、文章を考えます。

  • NoMaYさん、こんにちは。リューキィです。

    申し訳ないです。。。

  • リューキィさん、こんにちは。NoMaYです。

    よくよく考えてみれば、今まで会社にオシロが無かったぐらいなのですから、伝わらないですよね。すみません。あと、以下の文章ですが、私自身はA相やB相の立ち上がりや立下りと回転軸の右回転や左回転の関係を暗記出来ているのでは無いので、もしかしたら、以下の文章のA相をB相としないと話がおかしい、とかあるかも知れません。あるいは、右回転というのは左回転と書き換えないと話がおかしい、とか。

    (1) ポート出力を1本確保する

    RX65N Envision KitのArduinoコネクタに未使用の端子があるかどうか?
    あればそれを使います。無ければ、何とかしてRX65N Envision Kitのボード上から出力として使えるマイコンの端子を1つ引き出します。

    RXスマートコンフィグレータで、その端子を出力に設定します。

    (2) ロータリーエンコーダの回転角をカウントアップする時に(1)のポート出力をトグルする

    この文章ではそもそもピンと来ないのも無理ないかも知れませんでした。すみません。

    回転角をカウントアップ、というところを、回転角を保持している変数をカウントアップ、とすると伝わるでしょうか。

    たぶん、現在の回転角を保持している変数がある、だろうと思ったのです。
    1回転40パルスですので、1パルスで360度÷40=9度、ですね。
    回転軸を回した時に、何度回転軸が傾いているか(0度~351度)のような状態を保持している変数はありませんか。
    その変数を、インクリメント(もしくはデクリメント)、あるいは+9(もしくは-9)、している箇所がありませんか。
    そこで以下のようにして欲しいということです。たぶん、IRQ割り込みルーチン内だと思っているのですけれども。

        if(回転軸が1パルス(角度9度)右へ回された)
        {
            上記の変数 += 1 もしくは 上記の変数 += 9
            あるいは
            上記の変数 -= 1 もしくは 上記の変数 -= 9
            とか
            そういうことをしている箇所があると思うのだけれども

            以下を追加

            上記の(1)のポート出力 = ~上記の(1)のポート出力(現在の出力がHiならLowへ変更、現在の出力がLowならHiへ変更)
        }

     
    (3) ロータリエンコーダのA相の信号波形と(1)の波形を同時にオシロに表示させて異常個所を探す

    オシロの画面上の本来の期待値波形は、A相の信号の変化と関連して(1)のポート出力が綺麗にトグルする、というものです。
    ですが、現状では、A相の信号の変化とは無関係のような変な位置で、(1)のポート出力が奇妙にトグルすることがある筈なのです。

    それが一体どこなのか、ひとまず把握したいのです。

    たとえば、A相の信号はバタついていないように見えても、通常は(1)のポート出力が綺麗にトグルする箇所でポート出力がバタバタするか、とか。

    (4) オシロにどれくらいのデータバッファがあるか分からないが適切にトリガを掛ける方法が咄嗟に分からないので暫くの間は闇雲に探してみる

    今は闇雲に探してみて下さい。

  • NoMaYさん、こんにちは。リューキィです。

    いつもいつもすみません。本当にありがとうございます。

    大体わかりました!!ちょっとやってみます!

  • 取り急ぎ、オシロで計測してみた画像です。

    黄色がA相の波形

    ピンクがカウントをインクリメントした際のフラグの波形(見づらくてすみません)

    波形そのものにズレがあるのと、立ち上がる毎でオン/オフをしているのですが、明らかに数回飛ばしていたりします。(回転が速いほど飛ばす数が増えている模様)

    またズレの部分ですが、半期ズレているようなので、デクリメントでも同様のオン/オフを入れているので、そちらが作用したのかと。

    回転は同じ方向にしかしていません。今回は手動で回していますが、モーターで回す際は1秒間に2回転回らないくらいの回転速度なので、大体それくらいの間隔で回してみました。(幅が狭い波形は試しでもっと早くまわしています)

    ちなみに、Config_ICUのIRQ2の設定は 

    検出タイプ「立上りエッジ」

    デジタルフィルタ「PCLK/***」(特に根拠なしで試してみただけ)

    優先順位 レベル15

    です。今回の検証にあたって、LCDの割り込みも懸念したので、画面表示上の数字の変更は止めてやってみました。

    ついでにA相・B相の波形も計測してみましたが、きれいに半期でかぶって出ている様に見えました。

  • リューキィさん、こんにちは。NoMaYです。

    > ついでにA相・B相の波形も計測してみましたが、きれいに半期でかぶって出ている様に見えました。

    この写真は添付されていない、ということでよいのですよね。それで、添付されていた写真を見ると、20~30msのレベルの長期間に渡って割り込み禁止になっているような印象がしました。

    それで、LCDパネルに何かを表示させるという動作をさせていない、ということだけでは確証が弱いと思います。main()の中でemWinを起動している箇所をコメントアウトして、ロータリエンコーダのIRQだけが動くだけのようなプログラムを実験用に作って、それでまたオシロで波形を見るとどうなりますでしょうか?

    あと、確認したいのは、もっと素朴にIRQの立ち上がりエッジの割り込み処理の先頭で素朴にポート出力をトグルするようにしてみるとどうなるかです。(IRQの立下りエッジでは敢えて何もしないことにします。わけが分からなくなりそうですので。すみません、この文章の、立ち上がりエッジ、立下りエッジ、というのも、疎覚えです。要はIRQ割り込みがすっぽ抜けているかどうかを、もうすこし確実に明確に把握したい、ということです。)

  • リューキィさん、こんにちは。NoMaYです。

    割り込み禁止になっているかどうかを確認するには、CMT割り込みで1ms程度の割り込みを発生させ、その割り込み処理内でポート出力をトグルさせて、オシロで波形を見るというのがあります。問題無ければ、1msごとにトグルし続ける筈ですが、20~30msのレベルの長期間に渡ってトグルが止まってしまうようであれば、そこが問題ということになります。

    あるいは、100μs程度でトグルさせてみてもよいです。

  • リューキィさん、こんにちは。NoMaYです。

    あと、以前にリューキィさんにお渡しした土台のプログラムのさらに土台の手元の`Hello こんにちは`プログラムでは、以下の赤文字箇所にブレークポイントを設定してGo/Breakを繰り返してみると、デバッガの実行時間表示が5ms弱となりましたので、少なくともその時点では20~30msのレベルの長期間に渡って割り込み禁止になっていることは無かった、ということになります。(まだ、そういう割り込み禁止時間がある、ということがはっきりしたわけではありませんけれども。)

    void MainTask(void) {
      //
      // Setup configuration dependent pointers
      //
      APPW_X_Setup();
      //
      // Initialize AppWizard
      //
      APPW_Init(APPW_PROJECT_PATH);
      //
      // Create all persistent screens except initial screen
      //
      APPW_CreatePersistentScreens();
      //
      // Create initial screen...
      //
      APPW_CreateRoot(APPW_INITIAL_SCREEN, WM_HBKWIN);
      //
      // ...and keep it alive
      //
      while (1) {
        while (GUI_Exec1()) {
          APPW_Exec();
        }
        APPW_Exec();
        GUI_X_Delay(5);
      }
    }

     

  • NoMaYさん、こんにちは。リューキィです。

    A相・B相の波形は撮影していません。

    main()のemWinの部分をコメントアウトしようとしたのですが、どれか分からず、とりあえず「APPW_」の部分と

    最後にある

    -------------------------------------

    while (GUI_Exec1()) {
    APPW_Exec();
    }
    APPW_Exec();
    GUI_Delay(5);

    -------------------------------------

    をコメントアウトしたのですが、そうすると割込み自体が発生しません。エンコーダには電源が入っているので信号は出ています。コメントアウトしている場所を間違えているのだとは思うのですが。。。すみません。

  • リューキィさん、こんにちは。NoMaYです。

    では、こうして下さい。

    void main(void)
    {
        //MainTask();

        IRQを使えるようにする初期化コードをここに(既に作られているものをコピペすれば良い筈)

        for(;;)
        {
        }
    }