ライントレーサのプログラム作成
今回の内容
ライントレーサのAVR用プログラムを作成していきます。プログラム言語はC言語を使用します。搭載する機能としては、センサの状態表示、車体の進行方向の決定、進行方向へのモータ制御とします。なおpid制御はしません。
前回と次回の内容は?
前回までに、ライントレーサ車体部の作成と、フォトリフレクタ、モータドライバの使い方を説明し、回路を作成しました。
AVRでライントレーサを作成する記事については、今回で最後になりますので次回はありません。
もし、車体部や回路部についての記事を見ていない方や、モータドライバ、フォトリフレクタの使い方が分からない方、AVRにプログラムを書き込む方法がわからない方は、以下の記事もご覧ください。
ライントレーサに関する記事
ライントレーサのプログラム
ライントレーサのプログラムを作成します。
プログラムの動作手順は、以下の通りです。
- センサの状態をLEDで表示する
- センサの状態を取得し、車体の進行方向を決定する
- 進行方向に車体が進むようにモータを制御する
早速プログラムを書きます。
#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に書き込んで実際にライン上を走らせてみましょう!書き込む方法が分からなければこちらをご覧ください。
どうですか、無事に走りましたか?
センサの感度が良すぎる、または悪いという場合は、センサ部の半固定抵抗をマイナスドライバを使って調節したり、センサと床との距離を変えてみてください。
今回作成したライントレーサは、モータが弱く、タイヤが柔らかいため速度はあまりでませんでした。そのため、もっと速く走らせたい方はモータやタイヤを変えることをおすすめします。
最後までご覧いただきまして、ありがとうございました。
<< ライントレーサ回路部へ | 工作へ >> |