うしこlog
公開: 2014/03/19

ライントレーサのプログラム作成

今回の内容

 ライントレーサのAVR用プログラムを作成していきます。プログラム言語はC言語を使用します。搭載する機能としては、センサの状態表示、車体の進行方向の決定、進行方向へのモータ制御とします。なおpid制御はしません。

前回と次回の内容は?

 前回までに、ライントレーサ車体部の作成と、フォトリフレクタ、モータドライバの使い方を説明し、回路を作成しました。
AVRでライントレーサを作成する記事については、今回で最後になりますので次回はありません。

もし、車体部や回路部についての記事を見ていない方や、モータドライバ、フォトリフレクタの使い方が分からない方、AVRにプログラムを書き込む方法がわからない方は、以下の記事もご覧ください。

ライントレーサに関する記事

  1. AVRの環境構築と使い方
  2. ライントレーサ車体部
  3. モータドライバーの使い方
  4. フォトリフレクタの使い方
  5. ライントレーサ回路部
  6. この記事

ライントレーサのプログラム

 ライントレーサのプログラムを作成します。
プログラムの動作手順は、以下の通りです。

  1. センサの状態をLEDで表示する
  2. センサの状態を取得し、車体の進行方向を決定する
  3. 進行方向に車体が進むようにモータを制御する

早速プログラムを書きます。

#include <avr/io.h>
#include <util/delay.h>

//進行方向を示す値を定義する
#define FORWARD 0x10  //前へ
#define BACK  0x20    //後へ
#define LEFT  0x30    //左へ
#define RIGHT 0x40    //右へ
#define BRAKE 0x50    //ブレーキ
#define STOP  0x60    //停止

/*
 * センサ(フォトリフレクタ)の情報をLED表示する
 *
 */
void controllLED(){
  //左のセンサがONなら
  if(bit_is_clear(PINC,PC5)){
    PORTD |= (1<<PD0);  //PD0をHIGHに(LED点灯)
  }
  else{
    PORTD &= ~(1<<PD0);  //PD0をLOWに(LED消灯)
  }

  //中央のセンサがONなら
  if(bit_is_clear(PINC,PC4)){ 
    PORTD |= (1<<PD1);  //PD1をHIGHに(LED点灯)
  }
  else{
    PORTD &= ~(1<<PD1);  //PD1をLOWに(LED消灯)
  }

  //右のセンサがONなら
  if(bit_is_clear(PINC,PC3)){
    PORTD |= (1<<PD2);  //PD2をHIGHに(LED点灯)
  }
  else{
    PORTD &= ~(1<<PD2);  //PD2をLOWに(LED消灯)
  }
}

/*
 * 車を前進させる
 */
void moveForward(){
  //左モータはCCW
  PORTB |= (1<<PB6);
  PORTB &= ~(1<<PB7); 
  
  //右モータはCW
  PORTD &= ~(1<<PD6);
  PORTD |= (1<<PD7);
}
/*
 * 車を後退させる
 */
void moveBack(){
  //左モータはCW
  PORTB &= ~(1<<PB6);
  PORTB |= (1<<PB7);  
  
  //右モータはCCW
  PORTD |= (1<<PD6);
  PORTD &= ~(1<<PD7);
}
/*
 * 車を左に動かす
 */
void moveLeft(){
  //左モータはストップ
  PORTB &= ~(1<<PB6);
  PORTB &= ~(1<<PB7);

  //右モータはCW
  PORTD &= ~(1<<PD6);
  PORTD |= (1<<PD7);  
}
/*
 * 車を右に動かす
 */
void moveRight(){
  //左モータはCCW
  PORTB |= (1<<PB6);
  PORTB &= ~(1<<PB7); 

  //右モータはストップ
  PORTD &= ~(1<<PD6);
  PORTD &= ~(1<<PD7);
}
/*
 * 車をブレーキで止める
 */
void brake(){
  //左モータはブレーキ
  PORTB |= (1<<PB6);
  PORTB |= (1<<PB7);

  //右モータはブレーキ
  PORTD |= (1<<PD6);
  PORTD |= (1<<PD7);
}
/*
 * 車を停止させる
 */
void stop(){
  //左モータはストップ
  PORTB &= ~(1<<PB6);
  PORTB &= ~(1<<PB7);

  //右モータはストップ
  PORTD &= ~(1<<PD6);
  PORTD &= ~(1<<PD7);
}
/*
 * センサ情報により車を動かす方向を決める
 */
char getCarMode(){
  char mode = STOP;
    
  //中央のセンサがONなら(ライン内)
  if(bit_is_clear(PINC, PC4)){
    mode = FORWARD;   //前進
  }
  //中央がOFF(ライン外)
  else{
    //左のセンサがONなら
    if(bit_is_clear(PINC, PC5)){
      mode = LEFT;  //左へ
    }
    //右のセンサがONなら
    if(bit_is_clear(PINC, PC3)){
      mode = RIGHT; //右へ
    }
  }
  return mode;
}

/*
 * モードによりモータを制御し車を動かす
 * param mode : 車を動かすモード
 */
void runMotor(char mode){
  switch(mode){
    case FORWARD:
      moveForward();
      break;

    case BACK:
      moveBack();
      break;

    case LEFT:
      moveLeft();
      break;

    case RIGHT:
      moveRight();
      break;

    case BRAKE:
      brake();
      break;

    case STOP:
      stop();
      break;

    default:
      stop();
  }     
}

/*
 * メイン
 * センサ情報の表示および車体の制御を行う
 */
int main(void){
  DDRB = 0b11111111;  //portBは全て出力モード
  DDRC = 0b00000000;  //portCは全て入力モード
  DDRD = 0b11101111;  //portDはPD4のみ入力モード

  PORTB = 0b00000000;
  PORTC = 0b00000000;
  PORTD = 0b00000000;  
  
  char carMode; 
  
  //無限ループ
  while(1){
    //センサ情報をLEDで表示  
    controllLED();

    //センサ情報により車を動かす方向を決定
    carMode = getCarMode();
    
    //モータを回転させ車を動かす
    runMotor(carMode);
    _delay_ms(10);
  }
  return 0;
}

端子の接続について説明します。

PC5~PC3は、それぞれ左、中、右センサに繋がっています。

PB6,7は、左モータ用ドライバのIN1, IN2にそれぞれ繋がっています。

PD6,7は、右モータ用ドライバIN1, IN2にそれぞれ繋がっています。

PD0~PD2は、それぞれ左、中、右センサの状態を表示するLEDに繋がっています。


プログラムの関数の説明については以下の通りです。

関数名役割
void main()センサ情報の表示および車体の制御を行う
void controllLED()センサ情報をLEDに表示する
char getCarModeセンサにより進行方向を決定し、進行方向を示す値をcharで返す
void runMotor(char)getCarModeで求めた進行方向に進むようにモータを制御する

書込みと動作確認

 プログラムを記述したら、avrに書き込んで実際にライン上を走らせてみましょう!書き込む方法が分からなければこちらをご覧ください。

 どうですか、無事に走りましたか?
センサの感度が良すぎる、または悪いという場合は、センサ部の半固定抵抗をマイナスドライバを使って調節したり、センサと床との距離を変えてみてください。

 今回作成したライントレーサは、モータが弱く、タイヤが柔らかいため速度はあまりでませんでした。そのため、もっと速く走らせたい方はモータやタイヤを変えることをおすすめします。

 最後までご覧いただきまして、ありがとうございました。

<< ライントレーサ回路部 工作へ >>