目次

モータ制御

 モータは、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変数だけを設定します。

 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倍します。乗算よりも多少高速になります。

目次

inserted by FC2 system