树莓派综合项目2:智能小车(三)无线电遥控
一、介紹
??閱讀本篇文章前建議先參考前期文章:
??樹莓派基礎(chǔ)實(shí)驗(yàn)34:L298N模塊驅(qū)動(dòng)直流電機(jī)實(shí)驗(yàn)
??樹莓派綜合項(xiàng)目2:智能小車(一)四輪驅(qū)動(dòng)
??樹莓派綜合項(xiàng)目2:智能小車(二)tkinter圖形界面控制
??《智能小車(一)四輪驅(qū)動(dòng)》中,實(shí)現(xiàn)了代碼輸入對(duì)四個(gè)電機(jī)的簡(jiǎn)單控制。《智能小車(二)tkinter圖形界面控制》中,實(shí)現(xiàn)了本地圖形界面控制小車的前進(jìn)后退、轉(zhuǎn)向和原地轉(zhuǎn)圈。
??本實(shí)驗(yàn)中將使用無(wú)線電遙控設(shè)備控制小車的前進(jìn)后退、轉(zhuǎn)向和原地轉(zhuǎn)圈。使用傳統(tǒng)無(wú)線電通信設(shè)備通信仍然是非常重要的通信方式,比如無(wú)線電臺(tái)、對(duì)講機(jī),航模、車模、船模遙控等等。與手機(jī)移動(dòng)網(wǎng)絡(luò)、WIFI連接相比,無(wú)線電連接有它獨(dú)特的優(yōu)勢(shì),遙控距離遠(yuǎn),實(shí)時(shí)性好,操作靈活,不受網(wǎng)絡(luò)信號(hào)限制。
??其它基礎(chǔ)內(nèi)容可以參考文集:樹莓派基礎(chǔ)實(shí)驗(yàn)。
二、組件
★Raspberry Pi 3 B+全套*1
★睿思凱Frsky XM+ 迷你接收機(jī)*1
★電平反向器模塊*1
★睿思凱Frsky Taranis X9D PLUS SE2019遙控器*1
★L(fēng)298N擴(kuò)展板模塊*1
★智能小車底板模塊*1
★減速電機(jī)和車輪*4
★跳線若干
三、實(shí)驗(yàn)原理
本實(shí)驗(yàn)中使用的遙控系統(tǒng)可以自行選擇其它品牌的產(chǎn)品,如國(guó)產(chǎn)的天地飛還不錯(cuò)。
這里的遙控器就是像電視機(jī)遙控器、空調(diào)遙控器一樣可以不用接觸到被控設(shè)備,而通過(guò)一個(gè)手持器件,使用無(wú)線電與被控設(shè)備進(jìn)行通信,從而達(dá)到對(duì)設(shè)備的控制。
遙控器想到達(dá)到與小車通信的功能需要有兩部分配合完成。即:發(fā)射器(遙控器)與接收機(jī)。遙控器上的控制桿轉(zhuǎn)為無(wú)線電波發(fā)送給接收機(jī),而接收機(jī)通過(guò)接收無(wú)線電波,讀取遙控器上控制桿的讀數(shù),并轉(zhuǎn)為數(shù)字信號(hào)發(fā)送到樹莓派中。
接收機(jī)輸出兩種信號(hào),一種是模擬信號(hào)PWM,一種是SBUS數(shù)字信號(hào)。
由于每一路遙控器通道都需要一個(gè)PWM采集器進(jìn)行采集,但是對(duì)于樹莓派來(lái)說(shuō)不可能使用多個(gè)定時(shí)器來(lái)采集多個(gè)通道的PWM,這對(duì)于樹莓派的GPIO端口資源來(lái)說(shuō)十分浪費(fèi),因此我采用的就是SBUS信號(hào),可以在一個(gè)管腳中傳輸多路控制信號(hào)。
S-BUS其實(shí)是一種串口通信協(xié)議,采用100000的波特率,數(shù)據(jù)位點(diǎn)8bits,停止位點(diǎn)2bits,偶效驗(yàn),即8E2的串口通信。使用樹莓派的串口GPIO(TXD/RXD)中的RXD端口接收接收機(jī)的SBUS輸出信號(hào),解析出每路通道的控制信號(hào),進(jìn)而控制小車行進(jìn)。
但是S-BUS采用的是反向電平傳輸,也就是說(shuō),在S-BUS的發(fā)送端高低電平是反向的,協(xié)議中的所有高電平都被轉(zhuǎn)換成低電平,協(xié)議中的所有低電平都被轉(zhuǎn)換成高電平。所以在S-BUS的接收端需要增加一個(gè)高低電平反向器來(lái)進(jìn)行電平反轉(zhuǎn)。
關(guān)于解析無(wú)線電接收機(jī)PWM、SBUS信號(hào)的更詳細(xì)內(nèi)容,請(qǐng)參考樹莓派基礎(chǔ)實(shí)驗(yàn)39:解析無(wú)線電接收機(jī)PWM、SBUS信號(hào)。
四、實(shí)驗(yàn)步驟
??第1步: 連接電路。在樹莓派綜合項(xiàng)目2:智能小車(一)四輪驅(qū)動(dòng)中的接線基礎(chǔ)上,接入電平反向器、無(wú)線電接收機(jī)。
| GPIO.0 | 11 | ENA |
| GPIO.2 | 13 | IN1 |
| GPIO.3 | 15 | IN2 |
| GPIO.1 | 12 | ENB |
| GPIO.4 | 16 | IN3 |
| GPIO.5 | 18 | IN4 |
| GND | GND | 電池組供電負(fù)極 |
關(guān)于這里樹莓派GND、L298N小車擴(kuò)展板的電池組供電負(fù)極相連,是特殊情況下的情況,經(jīng)測(cè)試發(fā)現(xiàn):
如果樹莓派用的是充電頭供電,而L298N擴(kuò)展板用的是電池組供電,這兩個(gè)負(fù)極必須相連,否則馬達(dá)不動(dòng)。
如果樹莓派用的是L298N擴(kuò)展板接出來(lái)的5V供電,即兩者同一個(gè)電源,則這里不用連接。
| 電池+(-) | 電池+(-) | |||
| 5V供電 | 電源接口 | |||
| +(-) | +(-) | |||
| T1(L后) | +(-) | |||
| T2(L前) | +(-) | |||
| T3(R前) | +(-) | |||
| T4(R后) | +(-) |
| A6 | SBUS_OUT | ||
| RXD | 10 | B6 | |
| 3.3V | 1 | VCC | |
| 0V | 9 | GND | |
| 5V | 2 | VCC | |
| 0V | 14 | GND |
這里也要注意,由于樹莓派的GPIO只能接收3.3V的最高輸入,所以電平反相器的電源也只能使用3.3V,若反向后接收的信號(hào)需要是5V,則電平反相器的電源就使用5V。
這里我將18650電池組換成了航模使用的格氏ACE鋰電池(3S/11.1V/2200MAH/40C),電壓更高,能給樹莓派提供更穩(wěn)定的電源,動(dòng)力性也更好,效果非常不錯(cuò)。
??第2步: 編寫電機(jī)的驅(qū)動(dòng)程序,文件名為motor_4w.py。與樹莓派綜合項(xiàng)目2:智能小車(一)四輪驅(qū)動(dòng)中的程序完全相同。
??該車的行進(jìn)控制與履帶車的行進(jìn)控制類似:
前進(jìn)和后退很簡(jiǎn)單,左右兩邊的方向都朝前或朝后,速度一致;
原地順時(shí)針旋轉(zhuǎn)時(shí),左邊輪子前進(jìn),右邊輪子后退,速度一致;
原地逆時(shí)針旋轉(zhuǎn)時(shí),左邊輪子后退,右邊輪子前進(jìn),速度一致;
偏左前進(jìn)時(shí),左右兩邊的方向都朝前,左輪速度比右輪速度慢一點(diǎn);
偏右前進(jìn)時(shí),左右兩邊的方向都朝前,左輪速度比右輪速度快一點(diǎn);
偏左后退時(shí),左右兩邊的方向都朝后,左輪速度比右輪速度慢一點(diǎn);
偏右后退時(shí),左右兩邊的方向都朝后,左輪速度比右輪速度快一點(diǎn);
motor_4w.py:
#!/usr/bin/env python #-*- coding: utf-8 -*- #本模塊只含SMPcar()一個(gè)類,用于樹莓派對(duì)電機(jī)信號(hào)的控制 #通過(guò)GPIO輸出信號(hào),直接對(duì)某個(gè)電機(jī)的轉(zhuǎn)動(dòng)方向、速度進(jìn)行控制import RPi.GPIO as GPIOclass SMPcar():'''控制小車四輪動(dòng)作的類'''ENA = 11 #使能信號(hào)A,左邊兩輪IN1 = 13 #信號(hào)輸入1IN2 = 15 #信號(hào)輸入2ENB = 12 #使能信號(hào)B,右邊兩輪IN3 = 16 #信號(hào)輸入3IN4 = 18 #信號(hào)輸入4GPIO.setwarnings(False) #關(guān)閉警告def setGPIO(self):'''初始化引腳'''GPIO.setmode(GPIO.BOARD)GPIO.setup(SMPcar.ENA, GPIO.OUT)GPIO.setup(SMPcar.IN1, GPIO.OUT)GPIO.setup(SMPcar.IN2, GPIO.OUT)GPIO.setup(SMPcar.ENB, GPIO.OUT)GPIO.setup(SMPcar.IN3, GPIO.OUT)GPIO.setup(SMPcar.IN4, GPIO.OUT)def pwm(self,pwm): '''初始化PWM(脈寬調(diào)制),返回PWM對(duì)象'''EN_pwm = GPIO.PWM(pwm, 500)EN_pwm.start(0)return EN_pwmdef changespeed(self,pwm,speed):'''通過(guò)改變占空比改變馬達(dá)轉(zhuǎn)速'''pwm.ChangeDutyCycle(speed)def clockwise(self,in1_pin,in2_pin):'''馬達(dá)順時(shí)針轉(zhuǎn)的信號(hào)'''GPIO.output(in1_pin, 1)GPIO.output(in2_pin, 0)def counter_clockwise(self,in1_pin,in2_pin):'''馬達(dá)逆時(shí)針轉(zhuǎn)的信號(hào)'''GPIO.output(in1_pin, 0)GPIO.output(in2_pin, 1)def stop_car(self,in1_pin,in2_pin):'''馬達(dá)制動(dòng)的信號(hào)'''GPIO.output(in1_pin, 0)GPIO.output(in2_pin, 0)#使能信號(hào)為低電平,或者高電平(占空比設(shè)為100,IN1和IN2都為0或1時(shí))馬達(dá)制動(dòng)def destroy(self,A,B):'''結(jié)束程序時(shí)清空GPIO狀態(tài)'''A.stop()B.stop()GPIO.cleanup() # Release resourceif __name__ == '__main__': # 本模塊單獨(dú)測(cè)試時(shí)運(yùn)行使用try:smpcar = SMPcar() #創(chuàng)建樹莓派小車對(duì)象smpcar.setGPIO() #初始化引腳ENA_pwm=smpcar.pwm(smpcar.ENA) #初始化使能信號(hào)PWM,A為左邊車輪ENB_pwm=smpcar.pwm(smpcar.ENB) #初始化使能信號(hào)PWM,B為右邊車輪while True:'''通過(guò)輸入的命令改變馬達(dá)轉(zhuǎn)動(dòng)'''cmd = raw_input("Command, E.g. ff30ff30 :")direction = cmd[0] #只輸入字母b時(shí),小車剎車A_direction = cmd[0:2] #字符串0/1兩位為控制A(左邊車輪)方向信號(hào)B_direction = cmd[4:6] #4/5位為控制B(右邊車輪)方向信號(hào)A_speed = cmd[2:4] #字符串2/3兩位為控制A(左邊車輪)速度信號(hào)B_speed = cmd[6:8] #字符串6/7兩位為控制B(右邊車輪)速度信號(hào)print (A_direction,B_direction,A_speed,B_speed) #測(cè)試用if A_direction == "ff": #控制A(左邊車輪)順時(shí)針信號(hào)smpcar.clockwise(smpcar.IN1,smpcar.IN2)if A_direction == "00": #控制A(左邊車輪)逆時(shí)針信號(hào)smpcar.counter_clockwise(smpcar.IN1,smpcar.IN2)if B_direction == "ff": #控制B(右邊車輪)順時(shí)針信號(hào)smpcar.clockwise(smpcar.IN3,smpcar.IN4)if B_direction == "00": #控制B(右邊車輪)逆時(shí)針信號(hào)smpcar.counter_clockwise(smpcar.IN3,smpcar.IN4)if direction == "b": #小車剎車,IN1和IN2都為0,馬達(dá)制動(dòng)smpcar.stop_car(smpcar.IN1,smpcar.IN2)smpcar.stop_car(smpcar.IN3,smpcar.IN4)continue #跳出本次循環(huán)# 通過(guò)輸入的兩位數(shù)字設(shè)置占空比,改變馬達(dá)轉(zhuǎn)速smpcar.changespeed(ENA_pwm,int(A_speed))smpcar.changespeed(ENB_pwm,int(B_speed))except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy() will be executed.smpcar.destroy(ENA_pwm,ENB_pwm)finally:smpcar.destroy(ENA_pwm,ENB_pwm)??第3步: 小車行進(jìn)控制模塊,文件名為moving_control.py,設(shè)計(jì)小車的移動(dòng)行為,方向控制分為:原地左轉(zhuǎn)彎、原地右轉(zhuǎn)彎、直線前進(jìn)、直線后退、剎車,而向前左偏移開進(jìn)或右偏移開進(jìn)等,由左右兩邊不同的速度(油門)來(lái)控制。
moving_control.py:
??第4步: 編寫SBUS信號(hào)接收解析模塊,文件名為sbus_receiver_pi.py,與樹莓派基礎(chǔ)實(shí)驗(yàn)39:解析無(wú)線電接收機(jī)PWM、SBUS信號(hào)中的Python2程序有所不同,下面的程序在Python3中運(yùn)行,并標(biāo)注了兩者的不同之處。
sbus_receiver_pi.py:
??第5步: 編寫樹莓派智能小車的主程序,文件名為smartcar.py,將這4個(gè)Python文件放入一個(gè)文件夾后,只運(yùn)行本文件就可以了。
smartcar.py:
操控演示視頻:
https://www.bilibili.com/video/BV1Q5411L75a/
最近太忙,這篇文章拖了很久才完成,當(dāng)中克服了一個(gè)個(gè)不懂的技術(shù)難點(diǎn)和BUG,不過(guò)終于實(shí)現(xiàn)了遙控小車的想法,成功將無(wú)線電遙控和樹莓派結(jié)合起來(lái)。
辛苦是值得的,學(xué)到不少東西,后面將陸續(xù)把各種傳感器加入進(jìn)來(lái),實(shí)現(xiàn)智能化。
這個(gè)項(xiàng)目的代碼90%是我原創(chuàng)瞎寫的,有需要參考的同學(xué)可以下載:
樹莓派智能小車項(xiàng)目python源代碼下載
總結(jié)
以上是生活随笔為你收集整理的树莓派综合项目2:智能小车(三)无线电遥控的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python批量爬取小说(一步一步实现,
- 下一篇: 【技术】电脑管家的ARP防火墙提示安装驱