モータドライバのパルス入力を使い、サーボモータやステップモータを制御します。
計算で推定した角度をフィードバックに使うので、サーボモータでも角度エンコーダの信号は必要ありません。
3種類の異なるやり方でドライバへのパルス指令を生成しています。
ソースコードやプロジェクトファイルのダウンロードはこちら → drivePulse.zip
【注意】サーボモータの場合は、パルス駆動モードを備えたドライバが必要です。
(1)実運転用のプログラムです。シミュレーションもできます。 | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ブロック図 | ||||||||||||||||||||||||||||||||
プログラム | // ユーザ関数:パルス指令の発生 genPulse( vc, gain, step, pos, dead, rem ) { dir = 2 * ( vc > 0 ) - 1; // 回転方向指令(±1) freq = gain * abs( vc ); // 指令周波数 if freq > dead // 不感域を設ける { gen = w_sqr( 1/freq, 0, 1 ); // パルス生成 if gen != rem // 出力のup/dowmnで駆動 { pos = pos + dir * step; // 位置加算 } } rem = gen; // 次回のために記憶 Dout( 0, 0, gen ); // 速度パルス出力 Dout( 1, 0, dir ); // 方向パルス出力 return pos; } // メイン処理:パルス駆動によるモータの位置制御 var pos; var Vc; var last; proc { if currTime() > 0.1 { Pc = 1; } // 0.1秒後に移動指令発生 err = Pc - pos; // 誤差 acc = Kp * err - Vc; // 加速度 acc = limit( -sup, sup, acc ); // 加速度制限 Vc = integral( acc, Vc, T, 1, -1 ); // 速度指令 pos = genPulse( Vc, gain, step, pos, 10, last ); // パルス指令の発生 dir = auxfunc( dir ); // 方向指令のモニタ rate = auxfunc( gen ); // 速度パルス指令のモニタ } | |||||||||||||||||||||||||||||||
説明 |
モータ角度制御のページと同じやりかたで速度指令 Vc を生成し、
ユーザ関数 genPulse により駆動信号 gen と方位信号 dir を生成します。
フィードバックは、角度信号の代わりに計算値 pos を使います。
この例では以下の関数、信号、パラメータを使います。
| |||||||||||||||||||||||||||||||
設定例 | ||||||||||||||||||||||||||||||||
記録例 |
(2) 積分器を使ってパルスを発生させます。結果はほとんど同じになります。 | |
---|---|
プログラム | // ユーザ関数:パルス指令の発生 genPulse2( vc, stp, pos ) { pc = integral( vc, pc, 1, 1, -1 ); // 速度指令を積分して位置指令とする dir = 0; if pc > stp { dir= 1; } // ステップ幅を超えたら正方向回転指令 elsif pc < -stp { dir=-1; } // ステップ幅を逆に超えたら負方向回転指令 if dir != 0 // 正または負方向に回転の場合は { gen = ! gen; // High/Low切替 (0→1、1→0) pos = pos + dir * stp; // 指令回転角度を位置に加算して pc = pc - dir * stp; // 回転させる分 次回の指令を減らす Dout( 0, 0.5, gen ); // 速度パルス出力 Dout( 1, 0, dir ); // 方向パルス出力 } return pos; } // メイン処理:パルス駆動によるモータの位置制御 var pos; var Vc; proc { if currTime() > 0.1 { Pc = 1; } // 0.1秒後に移動指令発生 err = Pc - pos; // 誤差 acc = Kp * err - Vc; // 加速度 acc = limit( -sup, sup, acc ); // 加速度制限 Vc = integral( acc, Vc, T, 1, -1 ); // 速度指令 pos = genPulse2( Vc, step, pos ); // パルス指令の発生 dir = auxfunc( dir ); // 方向指令のモニタ rate = auxfunc( gen ); // 速度パルス指令のモニタ } |
(3) 2相パルス信号でドライバを駆動する場合のプログラムです。 | |
---|---|
ブロック図 | |
プログラム | // ユーザ関数:パルス指令の発生 genPulse3( vc, stp, pos, A, B ) { pc = integral( vc, pc, 1, 1, -1 ); // 速度指令を積分して位置指令とする dir = 0; if pc > stp { dir= 1; if A^B { A=!A; } else { B=!B; } } // 正方向回転 elsif pc <-stp { dir=-1; if A^B { B=!B; } else { A=!A; } } // 負方向回転 if dir != 0 // 上記いずれかの場合は { pos = pos + dir * stp; // 位置を加算 pc = pc - dir * stp; // 加算分を指令から減算 Dout( 0, 0.5, A ); // A相信号出力 Dout( 1, 0.5, B ); // B相信号出力 } return pos; } // メイン処理:2相パルス駆動によるモータの位置制御 var pos; // 位置フィードバック信号 var Vc; // 速度指令信号 var A; // 駆動指令信号 A相 var B; // 駆動指令信号 B相 proc { if currTime() > 0.6 { Pc = 0; } // 0.6秒以降の指令 elsif currTime() > 0.1 { Pc = 1; } // 0.1〜0.6秒の指令 err = Pc - pos; // 誤差 acc = Kp * err - Vc; // 加速度 acc = limit( -sup, sup, acc ); // 加速度制限 Vc = integral( acc, Vc, T, 1, -1 ); // 速度指令 pos = genPulse3( Vc, step, pos, A, B ); // 2相パルス指令の発生 } |
記録例 |
短時間で位置指令 Pc を0に戻し、速度を逆転させてみました。 |
拡大すると、速度指令 Vc の符号変化とともに、AとBの位相関係も逆転しています。 |