マイコン入門 ON-OFF制御で走るライントレース

マイコン
この記事は約7分で読めます。

こんにちは、ナナです。

DCモーターの制御方法のベースとなる技術を身につけたところで、次は簡単なライントレース機能を作ってみましょう。

本記事では次の疑問点を解消する内容となっています。

本記事で学習できること
  • ON/OFF制御って何?
  • ライントレースってどうやってしてるの?
  • ON/制御を使ったモーター制御とは?

では、ライントレースの仕組みを学んでいきましょう。

スポンサー

ON-OFF制御によるライントレース方法とは

ライントレースを実現する方法を原理から解説します。

ライントレースの基本原理

一般的にロボットカーが黒いラインを走行することをライントレースと呼びます。

しかし、厳密にいうと黒いラインを走っているわけではありません。実は白と黒の境界線上を走っているのです。

ライントレースの走る場所

白か黒かを光センサを利用して見分けることができます。その白か黒かの情報を利用して走行する場所を決めるのです。

ON-OFF制御とは

最もシンプルなライントレース方法がON-OFF制御と呼ばれるモーター制御方法です。

モーターを回すか止めるかの2つでライントレースを行います。では何をもって回すか止めるかを決定するかというとセンサ値なわけです。具体的にイメージ図を示しましょう。

ONOFF制御のライントレース

矢印の丸い部分が現時点の光センサが存在する場所だと思ってください。

白と黒の境界線を走りたいのですから本例においては白だったら右側へ、黒だったら左側へハンドルを切りたいわけです。つまり、次のようにモーターを制御すればよいのです。

  • 右へ行きたい:左モーターを前進させ、右モーターを停止する
  • 左へ行きたい:右モーターを前進させ、左モーターを停止する

これがON-OFF制御の考え方です。結構簡単なロジックであることがわかりますね。

スポンサー

ON-OFF制御でDCモーター制御を行うMotorモジュールの変更

走ることの主役はやはりMotorモジュールとなります。今回はON-OFF制御で走行するためのインターフェースをMotorモジュールに追加してみましょう。

Motorモジュールの役割検討

  • ライントレース中は前進するのみとする
  • ON-OFF制御に必要となる光センサの値は呼び出し側から入力する形とする
  • 光センサが白なら右へ、黒なら左へ向かうように走行する

Motorモジュールのインターフェース仕様書(追加部分)

3.インターフェース定義

3.4 ON-OFF制御走行開始

Motor_runOnOff関数仕様

スポンサー

課題:MotorモジュールをON-OFF制御で走ってみよう

課題1

課題内容

モーターモジュールに新規インターフェースを追加せよ。motor.cとmotor.hは前章のプログラムをベースとし、下記プログラムを追加して修正を加えよ。

//------------------------------------------------
//  概 要:ON-OFF制御走行開始
//  引  数:brightness      光センサ値
//          duty            デューティ比(0 - 99)
//  戻り値:0   正常
//          -1  異常
//------------------------------------------------
int Motor_runOnOff(unsigned short brightness, unsigned char duty)
{

}

motor.cに追加すべきこと

  • 光センサ値が512以上なら右モーターを前進・左モーターを停止する
  • 光センサ値が512未満なら左モーターを前進・右モーターを停止する

※motor.hには忘れずにプロトタイプ宣言を追加すること。

motor.h(変更部分のみ抜粋)

int Motor_runOnOff(unsigned short brightness, unsigned char duty);
  • インターフェースのプロトタイプ宣言を追加する

motor.c(変更部部のみ抜粋)

//------------------------------------------------
//  概 要:ON-OFF制御走行開始
//  引  数:brightness      光センサ値
//          duty            デューティ比(0 - 99)
//  戻り値:0   正常
//          -1  異常
//------------------------------------------------
int Motor_runOnOff(unsigned short brightness, unsigned char duty)
{
    if (brightness >= 512)      //  黒なら左方向へ
    {
        //  右モーター前進
        IO.PDR3.BIT.B0 = 1;
        IO.PDR3.BIT.B1 = 0;

        //  左モーター停止
        IO.PDR3.BIT.B2 = 1;
        IO.PDR3.BIT.B3 = 1;
    }
    else                        //  白なら右方向へ
    {
        //  右モーター停止
        IO.PDR3.BIT.B0 = 1;
        IO.PDR3.BIT.B1 = 1;

        //  左モーター前進
        IO.PDR3.BIT.B2 = 1;
        IO.PDR3.BIT.B3 = 0;
    }

    //  GRAの周期レジスタをベースにデューティ比の割合を設定
    TZ0.GRB = TZ0.GRA * (duty / 100.0);
    TZ0.GRC = TZ0.GRA * (duty / 100.0);

    // タイマZのch0をカウント開始してPWM動作開始
    TZ.TSTR.BIT.STR0 = 1;

    return 0;
}
  • 引数の光センサ値を元に右左のモーターの片方を前進することでON-OFF制御を行っている。

課題2

課題内容

MAINモジュールからMotorモジュールに対しON-OFF制御で走行要求を行うようにし、次の処理を繰り返すようにせよ。

  • 光センサのセンサ1(左側)の値をMotor_runOnOff関数に設定せよ
  • デューティ比は20%を指定せよ

main.c

//------------------------------------------------
//  概  要:エントリーポイント
//------------------------------------------------
void main(void)
{
    //  システム初期化処理
    main_init();

    while(1)
    {

    }
}

課題が完成したらビルドを行いビュートローバー上で動作させ、期待動作通りに動くことを確認せよ。


期待動作

  • センサ1を黒い線の左側に合わせ走行させる。
  • 黒いラインに従ってON-OFF制御で走行すること。

ライントレースのコースは黒ビニールテープなどで自作してみましょう。ホームセンターなどで購入するとよいでしょう。コースはどのような形でもよいです。

走行画像

main.c

//------------------------------------------------
//  概  要:エントリーポイント
//------------------------------------------------
void main(void)
{
    //  システム初期化処理
    main_init();

    while(1)
    {
        unsigned short sen1;
        unsigned short sen2;

        Lsen_getSensor(&sen1, &sen2);

        Motor_runOnOff(sen1, 20);
    }
}
  • Lsenモジュールからセンサ値を取得しsen1をMotor_runOnOff関数へ渡しています。
  • while文の中で常に光センサ値をMotorモジュールに提供してライントレースを行います。
スポンサー

Q&A:ON-OFF制御でよくある質問

走行速度を上げた時にライン上を右左にカクカクする感じが大きくなりました。

はい、そうですね。カクカクしますね。

ON-OFF制御の欠点がこれです。ON-OFFというのはモーターにとって非常にバランスが悪く、左と右のモーターを行ったり来たりさせているため、どうしてもロボットがふらついてしまうのです。

次章ではこのカクカクを解消したいと思います。