今天為大家分享一個Arduino自動避障小車的完整制作過程榆鼠,昨天有朋友咨詢想做一個自動施肥的創(chuàng)意遥昧,但說實(shí)話Arduino這個單片機(jī)是比較簡單的易桃,做一些簡單的應(yīng)用還可以褥琐,涉及到復(fù)雜的應(yīng)用不管是從算力還是接口方面都稍顯不足。不過整體而言還是很適合大家入門單片機(jī)的晤郑。
關(guān)于單片機(jī)方面敌呈,波波本身也沒有經(jīng)過專業(yè)的學(xué)習(xí)贸宏,而是因?yàn)楸旧韾酆镁幊毯碗娮訕I(yè)余學(xué)習(xí)。因此分享的筆記中難免有不足之處磕洪。還望大家指正吭练。
首先看下小車安裝好的效果圖:
想做一個Arduino 自動避障智能小車我們至少需要以下幾種材料,當(dāng)然類似螺絲刀這樣的工具就不說了褐鸥。
1线脚、Arduino主板一塊(不是必需的,如果大家有Esp8266這樣的芯片叫榕,也可以用來開發(fā)成網(wǎng)絡(luò)控制的小車)
2浑侥、L298N電機(jī)驅(qū)動模塊,作用驅(qū)動兩個輪子的直流電機(jī)晰绎。
3寓落、超聲波模塊,陀機(jī)及其支架荞下。
4伶选、小車底盤、萬向輪尖昏、電池盒仰税、接線。
材料準(zhǔn)備好了抽诉,我們要按照圖片所示安裝起來陨簇,最后一步是寫入程序。程序源碼如下:
#include <Servo.h>
#define Trig 2 //引腳控制超聲波發(fā)出聲波
#define Echo 3 //引腳反應(yīng)接收到返回聲波
#define LIN1 7 //左側(cè)輪子
#define LIN2 6
#define RIN1 5 //右側(cè)輪子
#define RIN2 4
//#define Steeringpin 9 //舵機(jī)控制端口
int S = 0; //初始化距離
Servo Steering; //轉(zhuǎn)向舵機(jī)
void setup() {
// put your setup code here, to run once:
Serial.begin(9600); //設(shè)置比特率
pinMode(Trig, OUTPUT);
pinMode(Echo, INPUT);
pinMode(LIN1, OUTPUT);
pinMode(LIN2, OUTPUT);
pinMode(RIN1, OUTPUT);
pinMode(RIN2, OUTPUT);
// pinMode(Steeringpin, OUTPUT);
Steering.attach(9); //定義舵機(jī)所用引腳
Steering.write(90); //初始化舵機(jī)角度
delay(2000); //開機(jī)延時
}
void loop() {
// put your main code here, to run repeatedly:
Steering.write(90);
Range(); //測距函數(shù)
if(S <= 5) //距離太近不足以轉(zhuǎn)彎
{
Back(); //執(zhí)行后退函數(shù)
delay(300); //后退持續(xù)時間
}
else if(S >= 5 && S <= 15) //距離中等可以轉(zhuǎn)彎
{
Turn(); //執(zhí)行轉(zhuǎn)彎判斷函數(shù)
}
else //距離充足
{
Line(); //執(zhí)行直行函數(shù)
}
}
void Range() //測距函數(shù)
{
digitalWrite(Trig,LOW); //測距
delay(2); //延時2微秒
digitalWrite(Trig,HIGH);
delay(10);
digitalWrite(Trig,LOW);
float distance = pulseIn(Echo,HIGH); //讀取高電平時間
S = float( distance * 17 )/1000; //把值賦給S
Serial.println(S); //向串口發(fā)送S的值迹淌,可以在顯示器上顯示距離
}
// float distance = pulseIn(Echo,HIGH);
// S = float( distance * 17 )/1000;
// 將回波時間換算成cm
// 讀取一個引腳的脈沖(HIGH或LOW)河绽。例如,如果value是HIGH唉窃,pulseIn()會等待引腳變?yōu)镠IGH耙饰,開始計時,再等待引腳變?yōu)長OW并停止計時纹份。
// 返回脈沖的長度苟跪,單位微秒。如果在指定的時間內(nèi)無脈沖函數(shù)返回蔓涧。
// 此函數(shù)的計時功能由經(jīng)驗(yàn)決定件已,長時間的脈沖計時可能會出錯。計時范圍從10微秒至3分鐘蠢笋。(1秒=1000毫秒=1000000微秒)
// 接收到的高電平的時間(us)* 340m/s / 2 = 接收到高電平的時間(us) * 17000 cm / 1000000 us = 接收到高電平的時間 * 17 / 1000 (cm)
void Turn() //轉(zhuǎn)向函數(shù)
{
Lull(); //停止
Steering.write(170); //使舵機(jī)轉(zhuǎn)到170度(左側(cè))
delay(1000); //留時間給舵機(jī)轉(zhuǎn)向
Range(); //測距
Steering.write(90); //使舵機(jī)回復(fù)原位
delay(1000);
if(S >= 15) //距離充足
{
turnLeft(); //左轉(zhuǎn)彎后退
}
else //距離不足
{
Steering.write(10); //使舵機(jī)轉(zhuǎn)到10度(右側(cè))
delay(1000);
Range();
Steering.write(90); //使舵機(jī)回復(fù)原位
delay(1000);
if(S >= 15) //距離充足
{
turnRight(); //右轉(zhuǎn)彎后退
}
else
{
Back(); //后退
int x = random(1); //產(chǎn)生一個隨機(jī)數(shù)使小車隨機(jī)轉(zhuǎn)向
if(x == 0)
turnLeft();
else
turnRight();
}
}
}
void Back() //后退函數(shù)(使電機(jī)反轉(zhuǎn))
{
digitalWrite(LIN1, LOW);
digitalWrite(LIN2, HIGH);
digitalWrite(RIN1, HIGH);
digitalWrite(RIN2, LOW);
}
void Line() //直線行駛函數(shù)(使電機(jī)正轉(zhuǎn))
{
digitalWrite(LIN1, HIGH);
digitalWrite(LIN2, LOW);
digitalWrite(RIN1, LOW);
digitalWrite(RIN2, HIGH);
}
void turnLeft() //小車左轉(zhuǎn)后退
{
digitalWrite(LIN1, LOW);
digitalWrite(LIN2, HIGH);
digitalWrite(RIN1, LOW);
digitalWrite(RIN2, LOW);
delay(1000);
}
void turnRight() //小車右轉(zhuǎn)后退
{
digitalWrite(LIN1, LOW);
digitalWrite(LIN2, LOW);
digitalWrite(RIN1, HIGH);
digitalWrite(RIN2, LOW);
delay(1000);
}
void Lull() //停止
{
digitalWrite(LIN1, LOW);
digitalWrite(LIN2, LOW);
digitalWrite(RIN1, LOW);
digitalWrite(RIN2, LOW);
}
程序燒錄完畢拨齐,我們就可以上電測試了。喜歡的朋友們別忘了點(diǎn)個贊喲~~
本文轉(zhuǎn)自“菠菜園”昨寞,原文:https://www.zkii.net/tech/arduino/2227.html