Arduino-尋跡小車
作者:Atopos
這是完整的代碼,下面有各部分的詳解
#define AIN1 7 //定義兩個電機 左
#define AIN2 8
#define BIN1 3 //右
#define BIN2 4
#define l A1 //從車尾方向從左到右排序
#define z A2
#define r A3
#define STBY 10
int PWMA=5; //左PWM調速
int PWMB=6; //右
int LED0; //定義三個用來存儲傳感器返回值
int LED1;
int LED2;
void setup() {
// 電機驅動模塊引腳初始化
pinMode(AIN1,OUTPUT);
pinMode(AIN2,OUTPUT);
pinMode(BIN1,OUTPUT);
pinMode(BIN2,OUTPUT);
//循跡模塊引腳初始化
pinMode(A1,INPUT);
pinMode(A2,INPUT);
pinMode(A3,INPUT);
pinMode(PWMA,OUTPUT);
pinMode(PWMB,OUTPUT);
pinMode(STBY,OUTPUT);
}
void loop() {
xunji();
}
void xunji(){
LED0=digitalRead(A1);//這里用之前定義的三個變量來讀取傳感器的返回值,用與接下來的判斷
LED1=digitalRead(A2);
LED2=digitalRead(A3);
digitalWrite(STBY,HIGH);
if(LED0==HIGH&&LED1==LOW&&LED2==HIGH) //正常情況小車正常直行
{
digitalWrite(AIN1,HIGH);
digitalWrite(AIN2,LOW);
analogWrite(PWMA,80);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMB,110);
delay(30) ;
}
else if(LED0==HIGH&&LED1==HIGH&&LED2==HIGH) //三個傳感器都接受到信號小車正常行走
{
digitalWrite(AIN1,HIGH);
digitalWrite(AIN2,LOW);
analogWrite(PWMA,80);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMB,110);
delay(30);
}
else if(LED0==LOW&&LED1==HIGH&&LED2==HIGH) //小車左轉
{
digitalWrite(AIN1,LOW);
digitalWrite(AIN2,HIGH);
analogWrite(PWMA,100);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMB,100);
delay(50);
}
else if(LED0==HIGH&&LED1==HIGH&&LED2==LOW) //小車右轉
{
digitalWrite(AIN1,HIGH);
digitalWrite(AIN2,LOW);
analogWrite(PWMA,115);
digitalWrite(BIN1,LOW);
digitalWrite(BIN2,HIGH);
analogWrite(PWMB,90);
delay(30);
}
else if(LED0==LOW&&LED1==LOW&&LED2==HIGH) //小車進內圈左轉
{
digitalWrite(AIN1,LOW);
digitalWrite(AIN2,HIGH);
analogWrite(PWMA,80);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMB,120);
delay(600);
}
else if(LED0==LOW&&LED1==LOW&&LED2==LOW) //遇到十字路口,小車3個感應器都感應到黑線,小車停止
{
digitalWrite(STBY,LOW);
delay(1000);
}
}
詳解
第一部分:線路
放上小車的線路連接圖
第二部分:代碼
UNO板子,電機以及傳感器接口的預處理
對每個接口都進行定義
#define AIN1 7 //定義兩個電機 左
#define AIN2 8
#define BIN1 3 //右
#define BIN2 4
#define l A1 //從車尾方向從左到右排序
#define z A2
#define r A3
#define STBY 10
int PWMA=5; //左PWM調速
int PWMB=6; //右
int LED0; //定義三個用來存儲傳感器返回值
int LED1;
int LED2;
宣告接口狀態,也就是初始化各個引腳的狀態
void setup() {
// 電機驅動模塊引腳初始化
pinMode(AIN1,OUTPUT);
pinMode(AIN2,OUTPUT);
pinMode(BIN1,OUTPUT);
pinMode(BIN2,OUTPUT);
//循跡模塊引腳初始化
pinMode(A1,INPUT);
pinMode(A2,INPUT);
pinMode(A3,INPUT);
pinMode(PWMA,OUTPUT);
pinMode(PWMB,OUTPUT);
pinMode(STBY,OUTPUT);
}
下面是主程序——loop程序
這里用一個函數代替,方便后續修改,至於后續要修改什么,文章最后會提到
void loop() {
xunji();
}
最后就是我們的重點——尋跡模塊
這也是整個程序的核心
首先,先定義LED0,LED1,LED2,三個變量來接收三個傳感器返回過來的高低電頻
LED0=digitalRead(A1);//這里用之前定義的三個變量來讀取傳感器的返回值,用與接下來的判斷
LED1=digitalRead(A2);
LED2=digitalRead(A3);
digitalWrite(STBY,HIGH);
這里用if -else語句,根據傳感器返回的值來判斷小車的狀態,從而做出相應的操作
void xunji(){
if(LED0==HIGH&&LED1==LOW&&LED2==HIGH) //正常情況小車正常直行
{
digitalWrite(AIN1,HIGH);
digitalWrite(AIN2,LOW);
analogWrite(PWMA,80);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMB,110);
delay(30) ;
}
else if(LED0==HIGH&&LED1==HIGH&&LED2==HIGH) //三個傳感器都接受到信號小車正常行走
{
digitalWrite(AIN1,HIGH);
digitalWrite(AIN2,LOW);
analogWrite(PWMA,80);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMB,110);
delay(30);
}
else if(LED0==LOW&&LED1==HIGH&&LED2==HIGH) //小車左轉
{
digitalWrite(AIN1,LOW);
digitalWrite(AIN2,HIGH);
analogWrite(PWMA,100);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMB,100);
delay(50);
}
else if(LED0==HIGH&&LED1==HIGH&&LED2==LOW) //小車右轉
{
digitalWrite(AIN1,HIGH);
digitalWrite(AIN2,LOW);
analogWrite(PWMA,115);
digitalWrite(BIN1,LOW);
digitalWrite(BIN2,HIGH);
analogWrite(PWMB,90);
delay(30);
}
else if(LED0==LOW&&LED1==LOW&&LED2==HIGH) //小車進內圈左轉
{
digitalWrite(AIN1,LOW);
digitalWrite(AIN2,HIGH);
analogWrite(PWMA,80);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMB,120);
delay(600);
}
else if(LED0==LOW&&LED1==LOW&&LED2==LOW) //遇到十字路口,小車3個感應器都感應到黑線,小車停止
{
digitalWrite(STBY,LOW);
delay(1000);
}
}
存在問題
- 上述程序用的是數字傳感器,如果是灰度傳感器,不可以用上述程序
- 還有,程序采用了正反轉,這個根據實際情況而定,如果不要求時間,可以讓他慢一點
- 因為測試用的小車電機比較廉價,所以左右電機會有一定的物理誤差,也就是給它一樣的PWM值
兩個電機的轉速是不一樣的,這個對小車的尋跡也有一定的影響,所以要經過反復實驗,調整合適的PWM值 - 還有傳感器的位置,這個也根據賽道的情況自己調整
更新:四個傳感器代碼
哥哥接口跟引腳和上述三個傳感器的一樣,第四個傳感器接在A4引腳。從左往右依次為1,2,3,4傳感器,pwm速度需要自己調試
#define AIN1 7 //定義兩個電機 左
#define AIN2 8
#define BIN1 3 //右
#define BIN2 4
#define l A1 //從車尾方向從左到右排序
#define z A2
#define r A3
#define f A4
#define STBY 10
int PWMA=5; //左PWM調速
int PWMB=6; //右
int LED0; //定義三個用來存儲傳感器返回值
int LED1;
int LED2;
int LED3;
void setup() {
// 電機驅動模塊引腳初始化
pinMode(AIN1,OUTPUT);
pinMode(AIN2,OUTPUT);
pinMode(BIN1,OUTPUT);
pinMode(BIN2,OUTPUT);
//循跡模塊引腳初始化
pinMode(A1,INPUT);
pinMode(A2,INPUT);
pinMode(A3,INPUT);
pinMode(A4,INPUT);
pinMode(PWMA,OUTPUT);
pinMode(PWMB,OUTPUT);
pinMode(STBY,OUTPUT);
}
void loop() {
xunji();
}
void xunji(){
LED0=digitalRead(A1);//這里用之前定義的四個個變量來讀取傳感器的返回值,用與接下來的判斷
LED1=digitalRead(A2);
LED2=digitalRead(A3);
LED3=digitalRead(A4);
digitalWrite(STBY,HIGH);
if(LED0==HIGH&&LED1==0&&LED2==0&&LED3==HIGH) //正常情況小車正常直行
{
digitalWrite(AIN1,HIGH);
digitalWrite(AIN2,LOW);
analogWrite(PWMA,90);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMB,95);
delay(30) ;
}
else if(LED0==HIGH&&LED1==HIGH&&LED2==HIGH&&LED3==HIGH) //四個個傳感器都接受到信號小車正常行走
{
digitalWrite(AIN1,HIGH);
digitalWrite(AIN2,LOW);
analogWrite(PWMA,90);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMB,95);
delay(30);
}
else if(LED0==HIGH&&LED1==LOW&&LED2==HIGH&&LED3==HIGH) //小車左小調整
{
digitalWrite(AIN1,LOW);
digitalWrite(AIN2,HIGH);
analogWrite(PWMA,100);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMB,100);
delay(80);
}
else if(LED0==LOW&&LED1==HIGH&&LED2==HIGH&&LED3==HIGH) //小車左大調整
{
digitalWrite(AIN1,LOW);
digitalWrite(AIN2,HIGH);
analogWrite(PWMA,100);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMB,100);
delay(30);
}
else if(LED0==HIGH&&LED1==HIGH&&LED2==LOW&&LED3==HIGH) //小車右小調整
{
digitalWrite(AIN1,HIGH);
digitalWrite(AIN2,LOW);
analogWrite(PWMA,130);
digitalWrite(BIN1,LOW);
digitalWrite(BIN2,HIGH);
analogWrite(PWMB,100);
delay(80);
}
else if(LED0==HIGH&&LED1==HIGH&&LED2==HIGH&&LED3==LOW) //小車右大調整
{
digitalWrite(AIN1,HIGH);
digitalWrite(AIN2,LOW);
analogWrite(PWMA,130);
digitalWrite(BIN1,LOW);
digitalWrite(BIN2,HIGH);
analogWrite(PWMB,100);
delay(50);
}
else if(LED0==HIGH&&LED1==LOW&&LED2==LOW&&LED3==LOW) //小車右直角
{
digitalWrite(AIN1,HIGH);
digitalWrite(AIN2,LOW);
analogWrite(PWMA,125);
digitalWrite(BIN1,LOW);
digitalWrite(BIN2,HIGH);
analogWrite(PWMB,90);
delay(30);
}
else if(LED0==LOW&&LED1==LOW&&LED2==LOW&&LED3==HIGH) //小車進內圈左轉
{
digitalWrite(AIN1,LOW);
digitalWrite(AIN2,HIGH);
analogWrite(PWMA,90);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMB,120);
delay(30);
}
else if(LED0==LOW&&LED1==HIGH&&LED2==HIGH&&LED3==LOW) //小車進內圈左轉
{
digitalWrite(AIN1,LOW);
digitalWrite(AIN2,HIGH);
analogWrite(PWMA,90);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMB,120);
delay(30);
}
else if(LED0==LOW&&LED1==HIGH&&LED2==LOW&&LED3==LOW) //小車進內圈左轉
{
digitalWrite(AIN1,LOW);
digitalWrite(AIN2,HIGH);
analogWrite(PWMA,90);
digitalWrite(BIN1,HIGH);
digitalWrite(BIN2,LOW);
analogWrite(PWMB,120);
delay(30);
}
else if(LED0==LOW&&LED1==LOW&&LED2==LOW&&LED3==LOW) //遇到十字路口,小車3個感應器都感應到黑線,小車停止
{
digitalWrite(STBY,LOW);
delay(1000);
}
}