當今發達的交通在給人們帶來便捷的同時也帶來了許多的交通事故。人們遇到緊急事情處理超時是造成因素的主要原因之一。如果我們的汽車更加智能,事先能預測並顯示前面障礙物距離車的距離,當障礙物距離車很近的時候自動采取一些措施來避開障礙物,這樣就能在很大程度上避免事故的發生,下面我來帶大家做一個智能的避障小車。
下方可查看演示視頻!
一、實驗器材
1、TPYboard V102板 1塊
2、電機驅動模塊L298N 1個
3、電機 2塊
4、小車底盤 1個
5、超聲波模塊 1個
6、舵機 1個
7、SG90舵機支架 1個
8、超聲波雲台支架 1個
二、超聲波模塊
什么是超聲波模塊
超聲波傳感器是利用超聲波的特性研制而成的傳感器, 它是通過傳送一個超聲波(遠高於人的聽覺范圍)和提供一個對應於爆裂回聲返回到傳感器所需時間的輸出脈沖來工作的。超聲波傳感器在非接觸性測量方面的應用非常廣泛,如檢測液體水位(特別是具有腐蝕性的液體,如硫酸、硝酸液體),汽車倒車防撞系統,金屬/非金屬探傷等,都可以用到超聲波距離傳感器。
超聲波模塊測距的原理
采用IO口TRIG觸發測距,給最少10us的高電平信呈。
模塊自動發送 8 個 40khz 的方波,自動檢測是否有信號返回。
(3)有信號返回,通過 IO 口 ECHO 輸出一個高電平,高電平持續的時間就是超聲波從發射到返回的時間。測試距離=(高電平時間*聲速(340M/S))/2。
如下圖接線,VCC 供 5V電源, GND 為地線,TRIG 觸發控制信號輸入,接板子的X9,ECHO 回響信號輸出,接板子的X10,四個接口端。
三、電機驅動模塊
什么是電機驅動模塊
電機驅動模塊主要是可以控制電機的運行:調速、運行、停止、步進、勻速等操作。
L298N的使用方法
L298N模塊是2路的H橋驅動,所以可以同時驅動兩個電機,接法如圖所示使能ENA ENB之后,可以分別從IN1 IN2輸入PWM信號驅動電機1的轉速和方向,可以分別從IN3 IN4輸入PWM信號驅動電機2的轉速和方向。我們將電機1接口的OUT1與OUT2與小車的一個電機的正負極連接起來,將電機2接口的OUT3與OUT2與小車的另一個電機的正負極連接起來。然后將兩邊的接線端子,即供電正極(中間的接線端子為接地)連接TPYboard的VIN,中間的接線端子即接地,連接TPYBoard的GND,In1-In4連接TPYBoard的X1,X2,Y1,Y2,通過X1,X2與Y1,Y2的高低電平,來控制電機的轉動,從而讓小車前進,后退,向左,向右。
四、舵機
概述
舵機也叫伺服電機,最早用於船舶上實現其轉向功能,由於可以通過程序連續控制其轉角,因而被廣泛應用智能小車以實現轉向以及機器人各類關節運動中,如下圖所示。
2、舵機的組成
一般來講,舵機主要由以下幾個部分組成,舵盤、減速齒輪組、位置反饋電位計、直流電機、控制電路等,如下圖所示。
舵機的輸入線共有三條,紅色中間,是電源線,一邊灰色的是地線,這輛根線給舵機提供最基本的能源保證,主要是電機的轉動消耗。電源有兩種規格,一是4.8V,一是6.0V,分別對應不同的轉矩標准,即輸出力矩不同,6.0V對應的要大一些,具體看應用條件;另外一根線是控制信號線,Futaba的一般為白色,JR的一般為桔黃色。另外要注意一點,SANWA的某些型號的舵機引線電源線在邊上而不是中間,需要辨認。但記住紅色為電源,灰色為地線,剩下的一根為信號線,一般不會搞錯。本實驗中,舵機紅色接TPYBoard v102+的VIN引腳,灰色接TPYBoard v102+的GND引腳,剩下的橙色是信號線,接TPYBoard V102+的X3針腳。TPYBoard v102+ 的X1、X2、X3、X4為信號引腳。
3、舵機工作原理
控制電路板接受來自信號線的控制信號,控制電機轉動,電機帶動一系列齒輪組,減速后傳動至輸出舵盤。舵機的輸出軸和位置反饋電位計是相連的,舵盤轉動的同時,帶動位置反饋電位計,電位計將輸出一個電壓信號到控制電路板,進行反饋,然后控制電路板根據所在位置決定電機轉動的方向和速度,從而達到目標停止。其工作流程為:控制信號→控制電路板→電機轉動→齒輪組減速→舵盤轉動→位置反饋電位計→控制電路板反饋。
五、伺服電機的構造函數與方法
1.構造函數
pyb.Servo(id)
在這id為1-4,對應TPYBoard v102+的X1-X4。
2.方法
Servo.angle([angle,time = 0 ])
如果沒有給出參數,則該函數返回當前角度。
如果給出參數,則該函數設置伺服角度:
angle 是以度數移動的角度。
time是達到指定角度所需的毫秒數。如果省略,則伺服器盡可能快地移動到其新位置。
Servo.speed([speed, time=0])
如果沒有給出參數,則該函數返回當前速度。
如果給出參數,則該功能設置伺服的速度:
speed 是在-100到100之間變化的速度。
time是達到指定速度所需的毫秒數。如果省略,則伺服器盡可能快地加速。
Servo.pulse_width([value ]) <http://docs.micropython.org/en/latest/pyboard/library/pyb.Servo.html>
如果沒有給出參數,該函數返回當前的原始脈沖寬度值。
如果給出參數,則該函數設置原始脈沖寬度值。
Servo.calibration([pulse_min,pulse_max,pulse_centre [,pulse_angle_90,pulse_speed_100 ]])
如果沒有給出參數,則該函數返回當前的校准數據,作為5元組。
如果給出參數,該功能設置時序校准:
pulse_min 是允許的最小脈沖寬度。
pulse_max 是允許的最大脈沖寬度。
pulse_centre 是對應於中心/零位置的脈沖寬度。
pulse_angle_90 是對應於90度的脈沖寬度。
pulse_speed_100 是對應於速度100的脈沖寬度。
六、硬件接線圖
TPYBoard v102 |
超聲波模塊 |
舵機 |
L298N驅動模塊 |
VIN |
VCC |
|
|
GND |
GND |
|
|
X9 |
Trig |
|
|
X10 |
Echo |
|
|
VIN |
|
紅 |
|
GND |
|
灰 |
|
X3 |
|
橙 |
|
X1 |
|
|
In1 |
X2 |
|
|
In2 |
Y1 |
|
|
In3 |
Y2 |
|
|
In4 |
VIN |
|
|
+12V |
GND |
|
|
GND |
VIN |
|
|
+5V |
七、實驗效果
http://player.youku.com/player.php/sid/XMjY2MTQ1NDA2MA==/v.swf
八、源代碼
# main.py -- put your code here! import pyb from pyb import Pin from pyb import Timer from pyb import servo x1 = Pin('X1', Pin.OUT_PP) x2 = Pin('X2', Pin.OUT_PP) y1 = Pin('Y1', Pin.OUT_PP) y2 = Pin('Y2', Pin.OUT_PP) Trig = Pin('X9',Pin.OUT_PP) Echo = Pin('X10',Pin.IN) num=0 flag=0 run=1 zuo=0 qian=0 you=0 distance=0 def start(t): global flag global num if(flag==0): num=0 else: num=num+1 def stop(t): global run if(run==0): run=1 start1=Timer(1,freq=10000,callback=start) stop1=Timer(4,freq=2,callback=stop) #小車左轉 def left(): x1.high() x2.low() y1.high() y2.low() #小車前進 def go(): x1.high() x2.low() y1.low() y2.high() #小車后退 def back(): x1.low() x2.high() y1.high() y2.low() #小車右轉 def right(): x1.low() x2.high() y1.low() y2.high() #小車停止 def stop(): x1.low() x2.low() y1.low() y2.low() #控制舵機向右、向左、向前 def servo(): global distance global zuo global you global qian servo3=pyb.Servo(3) #向右75旋轉 servo3.angle(-75,500) pyb.delay(1000) ceju() you=distance print('you',you) #向左轉75度 servo3.angle(75,500) pyb.delay(1000) ceju() zuo=distance print('zuo',distance) #轉到0度 servo3.angle(0,500) pyb.delay(1000) ceju() qian=distance print('qian',distance) #返回正前方、左前方、右前方的距離 return qian,zuo,you #測距方法 def ceju(): global flag global num global run global distance if(run==1): Trig.value(1) pyb.udelay(100) Trig.value(0) while(Echo.value()==0): Trig.value(1) pyb.udelay(100) Trig.value(0) flag=0 if(Echo.value()==1): flag=1 while(Echo.value()==1): flag=1 if(num!=0): #測距 distance=num/10000*34299/2 #print('Distance:') #print(distance,'cm') pyb.delay(500) flag=0 run=0 return distance def main(): global distance global zuo global you global qian servo3=pyb.Servo(3) servo3.angle(0,500) pyb.delay(1000) ceju() while 1==1: ceju()、 #前方距離大於40cm前進 if distance > 40: go() ceju() print('juli',distance) #前方距離小於40cm if distance <= 40: stop() back() pyb.delay(500) stop() servo() #如果右前方距離大於左前方 if you>zuo: right() pyb.delay(400) ceju() #如果左前方距離大於右前方 if zuo>you: left() pyb.delay(400) ceju() #如果所有方向距離全部小於15cm if zuo<15 and you< 15 and qian<15 : stop() back() pyb.delay(800) stop() ceju() #有一個方向距離小於5CM if zuo<5 or you <5 or qian<5: stop() back() pyb.delay(800) stop() ceju() main()