ライントレーサのプログラム作成
今回の内容
ライントレーサの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に書き込んで実際にライン上を走らせてみましょう!書き込む方法が分からなければこちらをご覧ください。
どうですか、無事に走りましたか?
センサの感度が良すぎる、または悪いという場合は、センサ部の半固定抵抗をマイナスドライバを使って調節したり、センサと床との距離を変えてみてください。
今回作成したライントレーサは、モータが弱く、タイヤが柔らかいため速度はあまりでませんでした。そのため、もっと速く走らせたい方はモータやタイヤを変えることをおすすめします。
最後までご覧いただきまして、ありがとうございました。
| << ライントレーサ回路部へ | 工作へ >> |