目次
前
次
モータ制御
モータは、DCモータとサーボモータを利用します。
DCモータは、PWM(Pulse Width Modulation)で回転数を制御します。
サーボモータは、20msごとに1.0ms〜2.0msの幅のパルスを出力して
制御します。
2つのモータを別に制御するのは面倒なので、DCモータとサーボモータ
の制御をひとつの変数で管理します。
DCモータも、20msごとに0.0ms〜19.9msの幅のパルスを出力する処理に
置き換えます。
タイマー割込みを0.1ms周期で発生させて、変数pcntを0〜199まで
カウントアップします。
サーボモータ用のパルスは、変数servoに10〜20の整数を入れておき
変数pcntと比較して、1か0を決定します。
DCモータ用のパルスは、変数motorに0〜199の整数を入れておき
変数pcntと比較して、1か0を決定します
説明をそのままコードにすると、次のようになります。
outb = 0 ;
if ( pcnt <= motor ) { outb |= 1 ; }
if ( pcnt <= servo ) { outb |= 2 ; }
今4つのモータがあり、チャネル0、1、3がDCモータ、チャネル2が
サーボモータであった場合、制御は次のように記述できます。
outb = 0 ;
if ( pcnt <= rmotor ) { outb |= 1 ; }
if ( pcnt <= lmotor ) { outb |= 2 ; }
if ( pcnt <= servo ) { outb |= 4 ; }
if ( pcnt <= nmotor ) { outb |= 8 ; }
/* 出力 */
上の処理に、変数pcntを変更する処理を加えます。
pcnt++ ;
if ( pcnt == 200 ) { pcnt = 0 ; }
変数pcntが最大値から0に戻るときに、各モータの制御値を
更新します。
if ( pcnt == 200 ) {
pcnt = 0 ;
rmotor = rmotorx ;
lmotor = lmotorx ;
servo = servox ;
nmotor = nmotorx ;
}
まとめると、タイマー割込みの処理コードは以下です。
void timer_handler(void)
{
/* generate pulse code */
outb = 0 ;
if ( pcnt <= rmotor ) { outb |= 1 ; }
if ( pcnt <= lmotor ) { outb |= 2 ; }
if ( pcnt <= servo ) { outb |= 4 ; }
if ( pcnt <= nmotor ) { outb |= 8 ; }
/* impress */
PORTB = outb ;
/* update */
pcnt++ ;
if ( pcnt == 200 ) {
pcnt = 0 ;
rmotor = rmotorx ;
lmotor = lmotorx ;
servo = servox ;
nmotor = nmotorx ;
}
}
パルス生成を依頼側は、次の4変数だけを設定します。
- rmotorx
- lmotorx
- servox
- nmotorx
4変数の設定だけやっておくと、タイマー割込み処理が
必要なタイミングで、その値を採用します。
DCモータは、DUTY比を設定するので、カウント値に変換
しなければなりません。
50%でカウント値を100にすればよいので、DUTY比の2倍を
rmotorx、lmotorx、nmotorxに設定します。
左右のモータのDUTY比を一度に設定するには、次の関数を
定義すればよいでしょう。
void update_motor(UBYTE ld,UBYTE rd)
{
rmotorx = (rd << 1);
lmotorx = (ld << 1);
}
シフトを利用し2倍します。乗算よりも多少高速になります。
目次
前
次