Arduino智能避障小車避障程序
《Arduino智能避障小車避障程序》由會(huì)員分享,可在線閱讀,更多相關(guān)《Arduino智能避障小車避障程序(27頁珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。
1、Arduino智能避障小車避障程序
首先建立一個(gè)名為modulecar. ino的主程序。// modulecar. ino,玩轉(zhuǎn)智能 小車主程序
^include
2、/右電機(jī)正 const int IN4 = 8 ; //右電機(jī)負(fù) const int trigger = 9 ; //定義超聲波傳感器發(fā)射腳為D9 const int echo =10 ; //定義傳感器接收腳為DIO const int max_read = 300; //設(shè)定傳感器最 大探測(cè)距離。int no_good二35; //*設(shè)定35cm警戒距離。 int read_ahead; //實(shí)際距離讀數(shù)。 Servo sensorStation; //設(shè)定傳感器平臺(tái)。 NewPing sensor (trigger, echo, max_read) ; //設(shè)定傳感器引腳和最大
3、讀數(shù) 〃系統(tǒng)初始化 void setup () { Serial, begin(9600) ; //啟用串行監(jiān)視器可以給調(diào)試帶來極大便利 sensorStation. attach(ll); 〃把 Dll 分配給舵機(jī) pinMode(ENA, OUTPUT) ; //依次設(shè)定各I/O屬性 pinMode(INI, OUTPUT); pinMode (IN2, OUTPUT); pinMode(ENB, OUTPUT); pinMode (IN3, OUTPUT); pinMode (IN4, OUTPUT); pinMode(trigger, OUTPUT)
4、; pinMode(echo, INPUT); sensorStation. write (90) ; //舵機(jī)復(fù)位至 90? delay (6000); 〃上電等待6s后進(jìn)入主循環(huán) //主程序 void loop() read_ahead = readDistance() ; //調(diào)用 readDistanceO 函數(shù)讀出前方距離 Serial, printin(,?AHEAD:z,); Serial. println(read_ahead) ; //串行監(jiān)視器顯示機(jī)器人前方距離 if (read_ahead < no_good) //如果前方距離小于警戒值 { f
5、astStop() ; //就令機(jī)器人緊急剎車 waTchO ; 〃然后左右查看,分析得岀最佳路線 goForwardO ; //*此處調(diào)用看似多余,但可以確保機(jī)器人高速運(yùn)轉(zhuǎn)下動(dòng)作的連 貫性 } else goForward() : //否則就一直向前行駛 } 主程序用到了兩個(gè)庫,Servo庫是IDE自帶的,NwePing庫是笫三方庫,需要 下載安裝。 接下來建立一個(gè)名為move, ino的標(biāo)簽。 //move, ino,機(jī)動(dòng)模塊。 〃剎車 void fastStop () { Serial. println(〃STOP〃); 〃串行監(jiān)視器顯示機(jī)器人狀態(tài)為STOP(停止
6、) 〃左電機(jī)急停(注:L298N和L293D均帶有剎車功能,在使能成立的條件下,同 時(shí)向兩相寫入高電平可令電機(jī)急停,詳見芯片手冊(cè)) digitalWrite(ENA, HIGH); digitalWrite(INI, HIGH); digitalWrite(IN2, HIGH); 〃右電機(jī)急停 digitalWrite(ENB, HIGH): digitalWrite(IN3, HIGH); digitalWrite(IN4, HIGH): } 〃前進(jìn) void goForward() Serial, print In ("FORWARD"); 〃串行監(jiān)視器顯示機(jī)器人
7、狀態(tài)為FORWARD (前進(jìn)) 〃左電機(jī)逆時(shí)針旋轉(zhuǎn) analogWrite(ENA, 106) ; //左電機(jī)PWM,可微調(diào)這個(gè)數(shù)值使小車左右兩側(cè)車輪 轉(zhuǎn)速相等,右電機(jī)同理 digitalWr辻e(INl, LOW): digitalWrite(IN2, HIGH); //右電機(jī)順時(shí)針旋轉(zhuǎn) analogWrite (E>JB, 118); digitalWrite(IN3, HIGH): digitalWrite(IN4, LOW); } 〃原地左轉(zhuǎn) void turnLeft () { Serial, printin ("LEFT") ; //串行監(jiān)視器顯示機(jī)器人狀
8、態(tài)為LEFT (向左轉(zhuǎn)) 〃左電機(jī)正轉(zhuǎn) analogWrite(ENA, 106); digitalWrite(INI, HIGH); digitalWrite(IN2, LOW); 〃右電機(jī)正轉(zhuǎn) analogWrite(ENB, 59); //*微調(diào)這個(gè)數(shù)值,使轉(zhuǎn)彎時(shí)內(nèi)側(cè)車輪起主導(dǎo)作用。相 當(dāng)于讓小車向后 打一把輪再拐彎。右轉(zhuǎn)同理 digitalWrite(IN3, HIGH); digitalWr辻e(IN4, LOW): delay (205) : //*延遲,數(shù)值以毫秒為單位,調(diào)節(jié)此值可使機(jī)器人動(dòng)作連貫 } 〃原地右轉(zhuǎn) void turnRight() Se
9、rial, print In ("RIGHT"); 〃串行監(jiān)視器顯示機(jī)器人狀態(tài)為RIGHT (向右轉(zhuǎn)) 〃左電機(jī)反轉(zhuǎn) analogWrite(ENA, 53); digitalWrite(INI, LOW); digitalWrite(IN2, HIGH); 〃右電機(jī)反轉(zhuǎn) analogWrite (E>JB, 118); digitalWr辻e(IN3, LOW): digitalWrite(IN4, HIGH); delay (205) : //*調(diào)節(jié)此值可使機(jī)器人動(dòng)作連貫 } 〃原地掉頭(暫時(shí)用不到) void turnAround() { Serial. pr
10、intlnCTURN 180"); 〃串行監(jiān)視器顯示機(jī)器人狀態(tài)為TURN 180(原 地順時(shí)針旋轉(zhuǎn) 180?) 〃左電機(jī)反轉(zhuǎn) analogWrite(ENA, 106); digitalWr辻e(INl, LOW): digitalWrite(IN2, HIGH); 〃右電機(jī)反轉(zhuǎn) analogWrite(ENB, 118); digitalWrite(IN3, LOW): digitalWrite(IN4, HIGH); delay (500); //* } // ping, ino,測(cè)距模塊 int readDistance() { delay(30); //聲
11、波發(fā)送間隔30ms,大約每秒探測(cè)33次。受系統(tǒng)所限,此值不 可小于29ms int cm = sensor, ping () / US_ROUNDTRIP_CM; //把 Ping:值(口 s)轉(zhuǎn)換為 cm return (cm) ; //readDistance ()返回的數(shù)值是 cm } 最后是驅(qū)動(dòng)云臺(tái)掃描并分析左右兩側(cè)距離的watch, ino模塊。// watch, ino,查看模塊 void waTch() { 〃測(cè)量右前方距離。 //*注意舵機(jī)旋轉(zhuǎn)方向,SG5010為逆時(shí)針旋轉(zhuǎn) sensorStation. write (20) ; //*舵機(jī)右轉(zhuǎn)至20?。調(diào)節(jié)
12、此值會(huì)影響傳感器掃描 區(qū)域,夾角越小, 機(jī)器人轉(zhuǎn)彎越謹(jǐn)慎 delay (1200) ; //延遲1. 2s待舵機(jī)穩(wěn)定 int read_right = readDistance () : //調(diào)用 readDistance ()函數(shù)讀出右前方 距離 Serial, print("RIGHT:”); Serial, printIn(read_right); //sensorStation. write (90) ; //*舵機(jī)復(fù)位至90度。廉價(jià)舵機(jī)大角度旋轉(zhuǎn)會(huì) 產(chǎn)生抖動(dòng),要加上這 兩行以求讀數(shù)準(zhǔn)確。 //delay (500); //延遲 0.5s //測(cè)量左前方距離 sen
13、sorStation. write (160) ; //舵機(jī)左轉(zhuǎn)至 160? delay (1200); //延遲1.2s待舵機(jī)穩(wěn)定。 int read_left = readDistance() ; //調(diào)用函數(shù)讀出距離左前方距離。 Serial, print("LEFT:”); Serial, printin(read_left); sensorStation. write (90) ; //這一行確保只要小車處于行駛狀態(tài),傳感器就 面向正前方 delay (500) ; //延遲 0.5s。 //分析得出最佳行進(jìn)路線。 辻(read_right > read_left)
14、//如果右前方距離比較大
{
turnRight () : //就向右轉(zhuǎn),
}
else turnLeft () : //否則就向左轉(zhuǎn)
〃此處也可以加入另一層邏輯:如果左右兩側(cè)讀數(shù)相等就調(diào)用turnAround()原 地掉頭。但
實(shí)際上觸發(fā)的兒率不大。
}
2C 液晶測(cè)試程序,Ar du i no 版本 1. 5. 6~r2, LiquidCrystal_I2C 庫版本 2. 0 // I
^include
15、 16, 2); 〃設(shè)定 IC 地址及液晶屏參數(shù) void setup () { led. init () ; //始化液晶屏 led. backlight (); led. print ("Hello, world!"); //開始打印信息 led. setCursor (3, 1) ; //設(shè)定顯示位置,第3列,第1行 led. print ("ZANG. HAIBO") ; } void loop () { } 〃前進(jìn) void goForward() { Serial, print In ("FORWARD") ; //吊行監(jiān)視器顯示機(jī)器人狀態(tài)為FORWARD
16、 (前進(jìn)) //左電機(jī)逆時(shí)針旋轉(zhuǎn) int vail = analogRead(AO) : //手動(dòng)調(diào)整左電機(jī)轉(zhuǎn)速。電位器兩端分別接至 +5V 和 GND, 中心抽頭接至A0 int leftSpeed = map (vall,0, 1023, 0, 255); //把讀數(shù)映射為 PWM analogWrite(ENA, leftSpeed): 〃寫入速度。下面的右電機(jī)同理 digitalWrite(INI, LOW); digitalWrite(IN2, HIGH): //右電機(jī)順時(shí)針旋轉(zhuǎn) int val2 = analogRead(Al); int rightSpeed =
17、 map (val2, 0, 1023, 0, 255); analogWrite(ENB, rightSpeed); digitalWr辻e(IN3, HIGH): digitalWrite(IN4, LOW); } // ping, ino,紅外測(cè)距模塊 // trigger腳沿用D9, echo腳換成A3 int readDistance() { digitalWrite (trigger, HIGH) ; //點(diǎn)殼紅外發(fā)射管 delayMicroseconds (200) ; //給接收管留出200 P s響應(yīng)時(shí)間 IRvalue=analogRead(echo) ;
18、 //讀取自然光和紅外線下反射值的總和 digitalWrite (trigger, LOW) ; //關(guān)閉紅外發(fā)射管以讀取自然光下的反射值 delayMicroseconds (200) ; //留出 200 P s 響應(yīng)時(shí)間 IRvalue=IRvalue-analogRead(echo): 〃刨除自然光得出實(shí)際值(紅外發(fā)射管 產(chǎn)生的部 分) return map(IRvalue, 120, 930, 30, 0) ; //用 map()函數(shù)把讀數(shù)轉(zhuǎn)換為距離} IRGR^gitaloD. £CtiOJ8Dij£a4Z. 加皿叩呵珂〃定:?鈕*次fTE削它割I(lǐng) FCin?4i |
19、
ircoutputPn-5; ”宜災(zāi)逹產(chǎn)友ft!■弓友口 TN3按S匚
vnld 3fttu 卩()
<
SQna.t?gtnt3Suo)
priMuje(iFpjPi! i.lhPUT)
pnMn^eioirpurFin, OUTFUT),
I
?vDd V30PI)
< V1 r
d口姑* w:.ugt??LW乙b施罰!牡題》找百麗□說平磺
決I眇QMEU他⑵: L
dgit3Wfte?::
20、rr 6Mam& r-削|綸腳g-?3|g high) if 劉鸚沖制何I g:arc- hwc去訊;":耳膨呦iFRWWbS;(卩氐 也和 ^r alpnrriniacurccj;的T出距奧 3 代碼l:HC-SR04超聲波傳感器典型代碼 digitalWr辻e(TrigPin, LOW): delayMicroseconds(2); digitalWrite (TrigPin, HIGH); 〃發(fā)送 10 P s 的高電平觸發(fā)信號(hào) delayMicroseconds(10); digitalWrite(TrigPin, LOW); distance = pulseln(E
21、choPin, HIGH) *340/60/2; // 檢測(cè)脈沖寬度即為超聲 波往返時(shí)間 代碼2:簡易超聲波測(cè)距代碼 const int TrigPin = 2; const int EchoPin = 3; //設(shè)定 SR04 連接的 Arduino 引腳 float distance; void setup () { //初始化串口通信及連接SR04的引腳 Serial, begin (9600); pinMode(TrigPin, OUTPUT); //要檢測(cè)引腳上輸入的脈沖寬度,需要先設(shè)置為輸入狀態(tài) pinMode(EchoPin, INPUT); Seria
22、1. println('"Ultrasonic sensor:"); } void loop() { //產(chǎn)生一個(gè)10 P s的高脈沖去觸發(fā)TrigPin digitalWrite(TrigPin, LOW); delayMicroseconds(2); digitalWrite(TrigPin, HIGH); delayMicroseconds(10); digitalWrite(TrigPin, LOW): //檢測(cè)脈沖寬度,并計(jì)算出距離 distance = pulseln(EchoPin, HIGH) /58.00; Seria1. print(distance)
23、;
Serial, print ("cm");
Seria 1. println ();
delay(1000);
}
代碼3:具有溫度補(bǔ)償?shù)某暡y(cè)距代碼
nclude <0neWire?h>
itinclude
24、RE_BUS); DallasTemperature sensors(&oneWire); void setup() { 〃初始化串口通信及連接SRO4的引腳 Serial, begin (9600); pinMode(TrigPin, OUTPUT): 〃要檢測(cè)引腳上輸入的脈沖寬度,需要先設(shè)置為輸入狀態(tài) pinMode(EchoPin, INPUT): sensors? begin (); } void loop() { //產(chǎn)生一個(gè)10 p s的高脈沖去觸發(fā)TrigPin sensors? requestTemperatures(); temperature_valu
25、e = sensors?getTempCBylndex(O); Seria 1. print (''temperature = ”); Seria1. print(temperature^value); Serial, print (,ZC ”); digitalWrite(TrigPin, LOW); delayMicroseconds(2); digitalWrite(TrigPin, HIGH); delayMicroseconds(10); digitalWrite(TrigPin, LOW): 〃檢測(cè)脈沖寬度,并計(jì)算出距離 distance = pulseln(E
26、choPin, HIGH) *(331?4+0. 6*temperature_value)/2; Seria1. print(^distance = ”); Seria1. print(distance); Serial, print ("cm"); Seria 1. printlnO ; delay(1000); } 代碼4:基于GP2D12的紅外測(cè)距系統(tǒng)代碼 int i; float val; void setup () { Serial, begin (9600); } void loop() { i=analogRead(A0); val二2547. 8/
27、((float) i*0. 49-10.41)-0. 42; Seria 1. println(val, 2); } □ui ”無. 2E8?S? 口[ i //藍(lán)牙遙控小車 //Arduino源程序 //定稿日期:2016-3-16 〃程序功能簡介: //程序采用軟件PWM方式,控制兩支直流電機(jī)的運(yùn)行行為,實(shí)現(xiàn)直行、后退、 左轉(zhuǎn)和右轉(zhuǎn) 動(dòng)作。 //操作者使用Android手機(jī)的藍(lán)牙功能發(fā)出指令,操控小車動(dòng)作。 //操作者還通過藍(lán)牙對(duì)小車的動(dòng)作參數(shù)進(jìn)行調(diào)試。//使用自定義串口收發(fā)數(shù) //使用軟件PW,輸出引腳可任意制定//使用Atmega48芯片 //Ar
28、duio 版本 1. 0. 5
#include
29、電機(jī)運(yùn)轉(zhuǎn)方向unsigned int LP = 0; unsigned int RP = 0; unsigned int LD 二 0; unsigned int RD = 0; unsigned int PWM[6]; 〃存放肖前PWM參數(shù)的整數(shù)型數(shù)組,全局變量 unsigned char inputString[8]; //存輸入數(shù)據(jù)字符串變量 boolean stringComplete = false; //數(shù)據(jù)串結(jié)束標(biāo)志//定時(shí)器2初始化函 void timer2_init() cli(); TCCR2B 二 0x00; // TCN
30、T2 二 0xF6; // TCCR2A 二 0x00; TCCR2B = 0x02; // TIMSK2 = 0x01; //定時(shí)器2中斷允許sei (); } 〃定時(shí)器2中斷服務(wù)函數(shù) //PWM波形產(chǎn)生器 ISR(TIMER2_0VF_vect) { TCNT2 二 0xF6; // counter++; if(counter = 0x3ff) if (rDirect = 1) bitSet(PORTD,5); else bitSet(PORTD,4); if (IDirect = 1) bitSet(PORTD,7); else bitSet(POR
31、TD,6); counter = 0; } if(counter = pwm_RH) { bitClear(PORTD, 4); bitClear(PORTD, 5); } if(counter = pwm_LH) { bitClear(PORTD, 6); bitClear(PORTD, 7); } } //電機(jī)運(yùn)行函數(shù) void Move(unsigned int LS, unsigned charLD, unsigned int RS, unsigned char RD) asm(,zBCLR 7") ; //關(guān)中斷 pwm_LH 二 LS; pwm_
32、RH = RS; IDirect = LD; rDirect = RD; asm("BSET 7"); //開中斷 } 〃獲取EEPROM數(shù)據(jù)函數(shù)//功能:從EEPROM里順序讀出六個(gè)PWM參數(shù),存入 PWM數(shù)組 void GetDataO unsigned char bytes[2]; //暫時(shí)存放PWM參數(shù)的字節(jié)數(shù)組,全局變量 unsigned char 1; unsigned char j; unsigned char k; for(i = 0;i < 6; i++) //for循環(huán),讀六個(gè)參數(shù) for (j二0;j < 2;j++) 〃內(nèi)
33、循環(huán),每次讀兩個(gè)字節(jié) k二i * 2 + 1 - j; //地址計(jì)算 bytes [j] = EEPROM. read (k) : //EEPROM 讀操作 } = word (bytes[0], bytesEl]) ; //將讀出的兩個(gè)字節(jié)合成一個(gè)PWM整數(shù)數(shù) 據(jù) } } //數(shù)據(jù)發(fā)送函數(shù) 〃功能:將一個(gè)整數(shù)拆分成四個(gè)ASCII代碼,通過藍(lán)牙串口發(fā)出的函數(shù)。 〃例如:整數(shù)784,將拆分成','7','8','4'四個(gè)字符 void Number(int val) { inttmp; //中間變量 unsigned char i ; //循環(huán)計(jì)數(shù)變量 unsigne
34、d char buf [4] ; //存字符數(shù)組 tmp= val / 1000; buf [0] = tmp + 0x30; //獲得千位 val= val % 1000; tmp二 val / 100; buf[1] = tmp + 0x30; //獲得百位 val= val % 100; tmp二 val / 10; buf [2] = tmp + 0x30; //獲得十位 val= val % 10; buf[3] = val + 0x30; //獲得個(gè)位 for(i = 0;i < 4;i++) 辻(buf = 0x30) //從高位整理,如果是0,則轉(zhuǎn)換成空
35、格。 buf = 0x20; else break; } Usart_Transmit (buf 10]) ; //通過藍(lán)牙串口連續(xù)發(fā)出四個(gè)字符。 Usart_Transmi t(buf[1]); Usart_Transmit(buf[2]); Usart_Transmit(buf[3]); } void setup () { timer2_init (); Usart_Init(9600); sei(); PORTD = 0x00; DDRD = OxFO; GetData () ; //初始化PWM參數(shù) } void loop () { unsigne
36、d char buf [6]; //存連續(xù)字符的數(shù)組 unsigned char index = 0: // 存索引值變量unsigned char i; unsigned char k; unsigned int para; 〃存 PWM 數(shù)據(jù)變量 delay (500); if (stringComplete = true) //分解手機(jī)傳過來的參數(shù){ //格式是:#n%dddd k= 0; //其中:n為索引(地址);dddd為數(shù)據(jù) index = 0; for (i = 0;i <= wCnt ;i++) { if (inputString = ' %') { in
37、dex = inputString[i~l] - 0x30; //獲得索引 k = 0; } else { buf[k] = inputString - 0x30: 〃獲得數(shù)據(jù) k++; } } para = 0; for (i = 0;i < k-1;i++) para = para * 10 + buf; PWM[index] = para; //將得到的整數(shù)參數(shù)立即存入對(duì)應(yīng)的PWM數(shù)組單元,修 改當(dāng)前運(yùn) 行參數(shù) buf [1] = lowByte(para) : //將整數(shù)轉(zhuǎn)換成兩個(gè)字節(jié)。 bufEOZ = highByte(para); index =
38、index * 2; 〃計(jì)算 EEPROM 地址 EEPR0M. write (index, buf[l]); 〃寫入 EEPROM 低位在前 index++; EEPROM, write (index, buf [0]) ; //高位在后 stringComplete = false; wCnt = 0; } } ISR(USART_RX_vect) { unsigned char command^O; inti; command = UDRO; //接收數(shù)據(jù) inputString[wCnt] = command; wCnt++; if(command == 13
39、) { stringComplete = true; wCnt——; else if (command == 10) stringComplete = false; wCnt = 0; } switch (command) { case ' @’ : GetDataO ; //從EEPROM中讀出數(shù)據(jù) for (i = 0;i < 6;i++) Number (PWM) ; //Android通過藍(lán)牙回傳,手機(jī)上會(huì)有顯示 } wCnt = 0; break; case '#': 〃得到手機(jī)發(fā)回的修改參數(shù)數(shù)據(jù) break; case ' wf : //接收到'wf
40、 ,前進(jìn) LP = PWM[0]; RP = PWM[1]; LD = 1; RD = 1; wCnt 二 0; break; case ' x' : //接收到'x',后退 LP = PWM[0]; RP = PWM[1]; LD = 0; RD = 0; wCnt = 0; break; case ' a' : //接收到'a',左轉(zhuǎn) LP = PWM[2]; RP 二 PWM[3]; LD = 0; RD = 1; wCnt = 0; break; case ' d' : //接收到'd,,右轉(zhuǎn) LP = PWM[4]; RP = PWM[5]; LD = 1; RD = 0; wCnt = 0; break; case 's' : //接收到's',停止電機(jī) LP = 0; RP = 0; LD = 1; RD = 1; wCnt = 0; break; default: LP = 0; RP = 0; LD = 1; RD = 1; } Move (LP, LD, RP, RD) ; }
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。