キーエンス社製 KV-NC32Tの外部入力割り込み機能を使って、位相差入力のリングカウンタをつくりました。リングカウンタは下限値とカウント幅を自由に設定できます。
KV-NC32Tには、位相差50kHz応答の高速カウンタが3チャネル分あり、「CPU高速カウンタ設定ウィザード」で手軽に設定できます。が。今回は自前でコードを書きます。
NC32TにはR000~R003の入力割り込みがあるので、自前コードを使うと2チャネル分の高速カウンタが増やせます。
また、PLCが信号を取りこぼさない速度の信号変化なら汎用デジタル入力ポートも使えます。
今回のサンプルではR000/R001で確認できるようにしています。また、ロータリエンコーダがない場合や、PLC実機がない場合でもシミュレーションで動作確認できます。
ラダー図のPDFファイル
(2024-07-15 初版投稿)
目次
- 初期化
- シミュレーション時のパラメータ
- 実際にロータリエンコーダをつないでみる
- パルスカウンタ仕様
- リングカウンタ仕様
- サンプルをダウンロードして動かしてみる
- (おまけ) スイッチの排他制御とOFF禁止
初期化
PLC起動時、1回だけ「サブルーチン0」を呼んで初期化します。(変数[Initial]がFの時callする)
各行の内容を見ていきましょう。
・L00088 :[DM11]にリングカウンタの下限値(ここでは4)を書きます。[DM10]にカウントできる範囲(ここでは15)を書きます。カウンタの値は4~18の範囲です。
リングカウンタなので正転時 18→4 に戻り、逆転時 4→18 に戻ります。
・L00090 :シミュレーション用にA相[MR1000] とB相[MR1100] の波形を定義します。B相はA相に対して π/2 位相をずらします。
A/B相の波形を変化させるためのクロックのタイマ値[@DM0] を500(ミリ秒)に設定。カウントモードを「4逓倍」(4逓倍動作のフラグ[MR102]を真) にしています。
・L00092~:[LR100]を真にして起動すると実際にロータリエンコーダをつないで確認できます。起動時の入力の状態をシミュレーション用の変数に代入します。(A相[R000]/B相[R001])
両相の割り込み極性を立ち上りと立下りの両微分に設定し、割り込み許可命令(EI)を実行します。
・L00095 :最後にサブルーチン1を呼んで、初期化終了フラグ(Initial)を真にします。
「サブルーチン1」は「サブルーチン0」からとリングカウンタの下限値が変更された時に呼ばれます。
・L00081~:リングカウンタをアップ ダウンする時にカウンタに加算する値を算出します。
インクリメント時はカウンタに[@DM10] を加算し、デクリメント時は[@DM11] を加算します。[@DM12] を加算してもカウンタ値に変化はありません。
最後に、リングカウンタを初期化します。(下限値を代入)
シミュレーション時のパラメータ
ロータリエンコーダの信号は[@DM0] で設定されたタイマで作られたクロックで自動的に変化させるモードと、手動で行うモードがあります。デフォルトは自動です。[MR200] を真にすると手動モードになります。手動モード中、[MR201] を真にすると1回変化します。
・L00010~:[MR200] が偽の場合(自動モード)、[T0]がアップした時に「サブルーチン2」を呼び、真の時は[MR201] を真にすると「サブルーチン2」を呼びます。
「サブルーチン2」ではロータリエンコーダをエミュレーションしています。
[MR1000]~[MR1015]と[MR1100]~[MR1115] を1ビット分、正転時には右ローテーション、逆転時には左ローテーションします。これにより最初に定義されたビットパタンで位相差信号を疑似的に作ることができます。
ロータリエンコーダの疑似信号[MR1000]と[MR1100] の立ち上り、または立下りでカウントアップダウン ルーチン「サブルーチン10/11」を呼び出します。
実際にロータリエンコーダをつないでみる
KV-NC32Tでは、差動信号出力のロータリエンコーダは接続できません。シングルエンド信号のみに対応しています。A相を[R000] に、B相を[R001] に接続してください。
ユーザーズマニュアル 入力端子詳細
PLC起動時、[LR100] が真ならばロータリエンコーダのエミュレータは実行されず、上記入力信号で外部割り込みが発生します。割り込み極性は、立ち上りと立ち下りの両極です。
割り込み優先度は、必要に応じて変更してください。ユーザーズマニュアル 割り込み優先度
割り込みプログラム内では外部入力の状態をエミュレータ用のデバイス([MR1000]/[MR1100])に渡してカウントアップダウン ルーチン「サブルーチン10/11」を呼び出します。
通常KV-NC32Tの入力時定数は10msあるのでロータリエンコーダの信号を取りこぼしてしまいます。入力を高速に読み込むため[R000]と[R001] の時定数を 「HSP命令」で 10μsにします。
パルスカウンタ仕様
このサンプルのカウント入力方式は位相差入力のみの対応です。カウントのモードは「1逓倍」「2逓倍」「4逓倍」が選択できます。A相変化時のカウントは「サブルーチン10」、B相変化時のカウントは「サブルーチン11」です。4逓倍モード時のみB相をカウントします。
それでは「1逓倍」時の動作からみていきます。
1逓倍モードはA相の変化時、B相が偽の時のみカウントさせます。
B相が真の時にはカウントさせたくないので、ルーチンの頭でカウントが変化しない加算値をレジスタにロード(レジスタを初期化)しておきます(L00061)。
A相の立ち上りでインクリメントさせる加算値をレジスタにロードします(L0063)。立ち下り時は、デクリメントさせる加算値をレジスタにロードします(L00064)。
レジスタに値がロードされたら、それをを引数にしてリングカウンタ値に加算します(「サブルーチン12」を呼び出す)。
2逓倍モードはA相の変化時、B相の状態に関わらずカウントします。
B相が偽の時は、A相の立ち上りでインクリメントさせる加算値をレジスタにロードします(L0063)。立ち下り時は、デクリメントさせる加算値をレジスタにロードします(L00064)。
B相が真の時は、A相の立ち下りでインクリメントさせる加算値をレジスタにロードします(L0066)。立ち上り時はデクリメントさせる加算値をレジスタにロードします(L00067)。
レジスタに値がロードされたら、それをを引数にしてリングカウンタ値に加算します(「サブルーチン12」を呼び出す)。
4逓倍モードはB相の変化時もカウントします。A相の変化時のカウントは2逓倍時と同じです。
A相が真の時は、B相の立ち上がりでインクリメントさせる加算値をレジスタにロードします(L0051)。立ち下り時は、デクリメントさせる加算値をレジスタにロードします(L00052)。
A相が偽の時は、B相の立ち下がりでインクリメントさせる加算値をレジスタにロードします(L0053)。立ち上り時は、デクリメントさせる加算値をレジスタにロードします(L00054)。
レジスタに値がロードされたら、それをを引数にしてリングカウンタ値に加算します(「サブルーチン12」を呼び出す)。
リングカウンタ仕様
リングカウンタ(「サブルーチン12」) はパルスカウンタから呼び出される形にしました。
リングカウンタは、レジスタを引数にしてカウント加算値をもらいます。コードに書かれている四則演算のみで任意の上下限値をもったリングカウンタを実現できます。(演算のオーバーフローには注意してください。)
カウンタ値と上下限値を比較し、オーバーフローした場合条件分岐でカウンタ値を書き直すことをする必要がありません。このコードの詳しいことについては別の機会に書こうと思っております。
※参考 CPC内蔵機能のリングカウンタでは、高速カウンタの現在値、または、リングカウンタの上限値・下限値を変更することで、カウンタの現在値が下限値~上限値の範囲外になった場合、カウンタの現在値をEND命令処理時に補正します。
サンプルをダウンロードして動かしてみる
サンプルコードはここからダウンロードできます。
実機(KV-CN32T)がなくてシミュレーターで動作確認する。または、実機があるがロータリエンコーダがない場合は[LR100] を偽にしてください。実機にロータリエンコーダを接続している場合は[LR100] は真にします。
実機がない場合は「メニューバー>モニタ/シュミレータ(N)>シュミレータ(L)Ctrl+F2」でシミュレーターを起動後RUN。実機がある場合は「メニューバー>モニタ/シュミレータ(N)>PLC転送→モニタモード(C)Ctrl+F8」でサンプルプログラムを転送後、RUNさせてください。
RUN後、登録モニタが表示されます。表示されない場合は「メニューバー>モニタ/シュミレータ(N)>登録モニタウィンドウ(G)」でウィンドウを表示させ、「ファイルを開く」から「R-Enc_R-Cnt_Nano」ディレクトリ(フォルダ)内にある「test.kmu」を開いてください。
また、プログラムコードの「ENDH」以降に主要な変数を記述しています。
プログラムをRUNさせたら、登録モニタウィンドウか「ENDH」以降に記述している変数で操作できます。※KV STUDIO では「ENDH」以降にもコードが記述できます。PLCへ転送時はこの部分は無効になるため影響はありません。この領域にはモニタ用の変数の記述や覚書のプログラムコード、ローカル変数宣言なども書けます。
初めに、カウントモードを選択します。MR100~MR102の何れかを選びます。
実機なし/ロータリエンコーダなしの場合。手動で実行したいなら、[MR200] を真にして[MR201]でトリガ。自動の場合はデフォルトのままで。
ロータリエンコーダを接続しているならば、軸を回転させるとカウントします。実機なし/ロータリエンコーダなしで自動の場合は、[MR000](正方向)か[MR001](負方向) を真にするとカウントが開始します。正負方向、逓倍選択、クロック周期(@DM0)、手動モード、リングカウンタのパラメータは随時変更可能です。
回転方向は排他ですがOFFできます。逓倍選択は排他制御で必ずどれかがONする仕様になっています。
下図は実際にロータリエンコーダを接続して波形観測した結果です。手でグリグリ回しています。
■KV STUDIOの操作とTRchartの動画
(おまけ) スイッチの排他制御とOFF禁止
本題からはそれますが、16bitsまたは32bitsのデバイスの内、どれか1bitしか選択できない様な制御を「正負回転方向」と「逓倍モード選択」で実装しています。逓倍モード選択を例にして解説します。
上図コードにおいて、00026行で[MR100]~[MR115] の内、真になったbitのみを[MR100]~[MR115] に書き戻しています。結果として最後に真になったbit以外は偽になり、必ず1つのbitのみ選択されることになります。
00027行では[MR100]~[MR115] の全bitがOFFになったら、1スキャン前の[MR100]~[MR115] の状態を記憶している[@DM4] の値を[MR100]~[MR115] に書き戻して、偽にされたbitを復活します。
このロジックは16bitsや32bitsまとめて記述できるのでこじんまりまとまりスッキリします。
同時に2つ以上のbitsが真になった時の対策など、より実用的な方法は、別の機会に書こうと思っています。
コメント