關(guān)鍵詞:遙控小車;Arduino;直流電機(jī);L298N電機(jī)驅(qū)動(dòng)板;串口藍(lán)牙模塊
一、簡(jiǎn)介
本項(xiàng)目使用Arduino實(shí)現(xiàn)了一個(gè)最小功能的藍(lán)牙遙控小車。
- 整車效果圖 -
- 電路原理圖 -
制作流程主要分為四個(gè)部分:1.組裝小車;2.燒寫代碼;3.調(diào)試藍(lán)牙;4.整車測(cè)試。其中,前三個(gè)部分的耦合性很低,每個(gè)部分可以獨(dú)立操作和調(diào)試。
二、實(shí)現(xiàn)過(guò)程
1. 組裝小車
所需環(huán)境:十字螺絲刀 × 1
- 車身零件全家福 -
1.1 電機(jī)繞線及固定
直流電機(jī)
本項(xiàng)目使用直流電機(jī)(即常見(jiàn)的玩具四驅(qū)車的馬達(dá))作為小車的驅(qū)動(dòng)裝置,直流電機(jī)的特點(diǎn)是:只要電機(jī)的兩極有電勢(shì)差,電機(jī)就可以運(yùn)轉(zhuǎn),反接則逆轉(zhuǎn),兩極電勢(shì)差為零時(shí)停止運(yùn)轉(zhuǎn)。
電極繞線
這款直流電機(jī)沒(méi)有預(yù)先引出導(dǎo)線,所以需要我們手工連接導(dǎo)線:
首先,把杜邦線裸露出銅線的一段塞入電機(jī)銅電極的小孔中;
然后把探出的那部分銅線彎折一下,用指尖壓住彎折處兩段的銅線,旋轉(zhuǎn)幾圈,讓兩段銅線纏繞在一起;
這樣保證了銅線和電極的充分接觸,省去了焊接的麻煩。
注:沒(méi)有要求電極和不同顏色導(dǎo)線的對(duì)應(yīng)關(guān)系,可以隨意連接。
測(cè)試電機(jī)
把兩個(gè)電機(jī)和4根杜邦線連接完畢之后就可以對(duì)電機(jī)進(jìn)行簡(jiǎn)單的測(cè)試:只要把杜邦線的兩頭接觸18650鋰電池的兩極即可,可以觀察到電機(jī)開(kāi)始快速轉(zhuǎn)動(dòng),如果調(diào)換電池的電極,會(huì)發(fā)現(xiàn)電機(jī)發(fā)生反轉(zhuǎn)。
固定電機(jī)
把兩個(gè)固定電機(jī)用的插銷插到車底盤上對(duì)應(yīng)的空槽中,然后將長(zhǎng)螺絲穿過(guò),用手輕輕旋上螺母。
- 固定電機(jī) -
1.2 固定驅(qū)動(dòng)板和萬(wàn)向輪
L298N工作原理
由上文的內(nèi)容可知,直流電機(jī)只要一極接高電平,一極接低電平即可轉(zhuǎn)動(dòng),大家也知道Arduino的數(shù)字輸出引腳可以直接輸出高電平或低電平,但我們一般不直接將Arduino連接到直流電機(jī)上,因?yàn)锳rduino板的電流負(fù)載是有限的,直接連接電極容易引發(fā)電流過(guò)載,導(dǎo)致Arduino板被燒壞,所以我們選用L298N這塊轉(zhuǎn)接驅(qū)動(dòng)板,作為Arduino和電機(jī)之間的橋梁。
針腳對(duì)應(yīng)關(guān)系如下圖,其中in1 ~ in4對(duì)應(yīng)OUT1~OUT4,我們將Arduino的數(shù)字輸出針腳接到in1 ~ in4上,即可將對(duì)應(yīng)的高低電平信號(hào)映射到OUT1~OUT4的接線柱上,從而控制電機(jī)。L298N除了有轉(zhuǎn)換信號(hào)的功能外,內(nèi)部還有穩(wěn)壓模塊,可以接受7 ~ 12V的輸入,然后轉(zhuǎn)換出一個(gè)5V的輸出,分別對(duì)應(yīng)這下部的3個(gè)接線柱,我們之后會(huì)將18650電池組的正極接到7 ~ 12V輸入的接線柱上,負(fù)極接地,然后用L298N提供的5V輸出和接地作為正負(fù)極來(lái)為Arduino板供電。
- L298N針腳對(duì)應(yīng)關(guān)系圖 -
固定驅(qū)動(dòng)板和接線
固定驅(qū)動(dòng)板的方法很簡(jiǎn)單,我們只用兩組螺絲螺母,固定到下圖所示的位置,注意螺絲不要扭太緊。
- 固定驅(qū)動(dòng)板 -
把杜邦線固定到接線柱上
使用螺母固定好L298N之后,需要將電極引出的杜邦線的針腳固定到L298N的接線柱上,方法是先用螺絲刀松開(kāi)接線柱內(nèi)的螺絲,然后塞入杜邦線的針腳,最后再用螺絲上緊,如下圖:
- 將杜邦線固定到接線柱上 -
這部分完成。
1.3 裝配18650電池盒和電源開(kāi)關(guān)
18650鋰電池
18650型鋰電是電子產(chǎn)品中比較常用的可充電鋰電池,單節(jié)電壓一般為3.7V,常在充電寶或筆記本電腦的電池中作為電芯使用。其型號(hào)的定義法則為:如18650型,即指電池的直徑為18mm,長(zhǎng)度為65mm,0代表是圓柱體型的電池。
選用原因
由于Arduino UNO的標(biāo)準(zhǔn)輸入電壓為5 ~ 9V,L298N驅(qū)動(dòng)板的輸入電壓為7 ~ 12V,所以本項(xiàng)目選用了兩節(jié)18650鋰電池串聯(lián)(串聯(lián)后總電壓為7.4V)的方式作為小車的電源,同時(shí)給Arduino和電機(jī)驅(qū)動(dòng)板供電。
安裝電池盒,連接開(kāi)關(guān)
- 安裝電池盒和開(kāi)關(guān) -
給船型開(kāi)關(guān)的兩個(gè)引腳纏線,這部分需要耐心些,注意兩個(gè)引腳的導(dǎo)線不要接觸到一起,否則開(kāi)關(guān)就會(huì)失效。
- 這部分需要耐心些 -
最后用一個(gè)螺絲螺母的組合穿過(guò)底板(注意穿過(guò)的孔的位置)固定電池盒和用于支撐Arduino的銅柱(用螺母固定),還要在L298N的接線柱上增添兩條用于給Arduino供電的杜邦線,安裝的時(shí)候注意牢固。
- 注意孔的位置 -
1.4 固定Arduino,連接剩余杜邦線
固定Arduino,根據(jù)原理圖連線
然后可以用一個(gè)螺絲固定Arduino到車身上,并根據(jù)電路原理圖連接從L298N給Arduino供電的杜邦線。
- 連接供電線路 -
- 連接給L298N的信號(hào)線 -
1.5 通電調(diào)試
無(wú)程序測(cè)試電機(jī)方法
可以用Arduino板上固定的3.3V和GND輸出測(cè)試L298N。
- 用Arduino固定的3.3V和GND輸出測(cè)試L298N -
- 按照原理圖連線 -
2. 燒寫代碼
2.1 使用Arduino IDE向開(kāi)發(fā)板上傳代碼
連接Arduino和PC機(jī),使用Arduino IDE打開(kāi)本項(xiàng)目的代碼文件,在【工具】菜單中選擇所需要上傳的端口,然后點(diǎn)擊上傳
2.2 使用Arduino IDE串口工具進(jìn)行調(diào)試
底部狀態(tài)欄顯示上傳成功后,保持Arduino和PC機(jī)連接的狀態(tài),點(diǎn)擊右上角的串口監(jiān)視器,出現(xiàn)一個(gè)小程序框
- 上傳成功后,打開(kāi)串口監(jiān)視器 -
串口監(jiān)視器程序框的頂部是一個(gè)輸入欄,在這里我們可可以對(duì)上傳到板上的程序進(jìn)行測(cè)試,在輸入欄輸入“w”后,點(diǎn)擊【發(fā)送】按鈕,會(huì)發(fā)現(xiàn)文本框里可以從Arduino得到相應(yīng)的反饋(這是在源代碼中設(shè)置的),然后還可以依次測(cè)試發(fā)送“a”、“d”、“s”、“x”這幾種消息,如均正常,則程序無(wú)誤。
使用了鍵盤的W、A、S、D、X鍵位的布局來(lái)與前進(jìn)、左轉(zhuǎn)、右轉(zhuǎn)、停止和后退這幾個(gè)概念做對(duì)應(yīng)
- 在串口監(jiān)視器中測(cè)試 -
2.3 連接車身調(diào)試
如果小車車身安裝好了,這時(shí)可以把Arduino和小車車上的引腳按照原理圖連接好,然后還通過(guò)上一個(gè)步驟的方法,在PC機(jī)上用串口監(jiān)視器給Arduino發(fā)送消息,觀察輪胎的運(yùn)轉(zhuǎn)情況,看是否按照程序的描述運(yùn)轉(zhuǎn),如果不能,可能是在電機(jī)的引腳或者連線的時(shí)候出現(xiàn)偏差,解決方法有三種:
修改源代碼中控制輪的變量與數(shù)字引腳的對(duì)應(yīng)關(guān)系
修改Arduino到L298N信號(hào)線的連線
修改L298N和電機(jī)之間的連線
每種方法都可以解決小車不能按照規(guī)定接受消息的方式運(yùn)轉(zhuǎn)的問(wèn)題,請(qǐng)同學(xué)們自由選擇。
- 燒錄代碼和測(cè)試 -
校正輪胎轉(zhuǎn)動(dòng)方向。
3. 調(diào)試藍(lán)牙
關(guān)于HC-05和調(diào)試
HC-05是一個(gè)串口藍(lán)牙通信模塊,內(nèi)部的芯片上封裝了藍(lán)牙通信協(xié)議以及用于調(diào)試的AT指令集,功能是:可以通過(guò)藍(lán)牙接受數(shù)據(jù),再?gòu)拇谕ㄐ艆f(xié)議從針腳發(fā)送出去,也可以從串口接受消息,再經(jīng)過(guò)芯片用藍(lán)牙發(fā)送出去,相當(dāng)于通信無(wú)線到有線通信的一個(gè)橋梁。
AT指令是應(yīng)用于終端設(shè)備與PC應(yīng)用之間的連接與通信的指令。AT即Attention。每個(gè)AT命令行中只能包含一條AT指令;對(duì)于AT指令的發(fā)送,除AT兩個(gè)字符外,最多可以接收1056個(gè)字符的長(zhǎng)度(包括最后的空字符)。
我們將藍(lán)牙模塊(HC-05)通過(guò)轉(zhuǎn)換器(TTL轉(zhuǎn)USB)連接到電腦上, 在電腦上使用串口調(diào)試軟件(CoolTerm)向藍(lán)牙模塊發(fā)送特定的AT指令來(lái)對(duì)藍(lán)牙模塊的一些參數(shù),比如設(shè)備名稱、配對(duì)碼、主從角色等等。
3.1 將 串口藍(lán)牙模塊(HC-05) 與PC相連接
使用 USB轉(zhuǎn)TTL模塊 連接 HC-05,連線如下圖
- 連線:GND--GND;5V--5V;RX--TX;TX--RX -
- 要按住RST鍵連接USB,才能進(jìn)入AT調(diào)試模式 -
按住藍(lán)牙模塊上的RST鍵,插入PC機(jī)的USB口,松開(kāi)RST鍵,進(jìn)入AT指令調(diào)試模式,標(biāo)志是藍(lán)牙模塊上的紅色指示燈慢速閃爍。
如果不按住RST鍵直接連接USB口的話,紅色指示燈會(huì)快速閃爍,標(biāo)志進(jìn)入藍(lán)牙連接模式。
3.2 打開(kāi)CoolTerm,建立串口通信連接
將藍(lán)牙模塊連接到PC上后,查看設(shè)備管理器,打開(kāi)CoolTerm軟件,點(diǎn)擊【Options】圖標(biāo)進(jìn)入選項(xiàng)設(shè)置,【Port】選項(xiàng)選擇設(shè)備管理器中CH340對(duì)應(yīng)的端口(根據(jù)電腦的不同,不一定是COM5),【Baudrate】修改為 38400,然后點(diǎn)擊底部的【OK】確定。
- 進(jìn)入設(shè)置,修改端口和波特率 -
設(shè)置完成后,點(diǎn)擊軟件上方的【Connect】圖標(biāo)。
3.3 使用AT指令調(diào)整藍(lán)牙模塊的參數(shù)
【Connect】成功后,依次點(diǎn)選菜單欄上的【Connection】→【Send String】,會(huì)出現(xiàn)一個(gè)消息發(fā)送框,通過(guò)這個(gè)可以向藍(lán)牙模塊發(fā)送AT指令,如下圖:
- 輸入“AT+回車” -
注意,使用AT指令的時(shí)候一定要回車到第二行再點(diǎn)擊【Send】發(fā)送。
AT指令集
分別輸入如下指令,查看設(shè)備的當(dāng)前狀況:
“AT”:回復(fù)“OK”,說(shuō)明設(shè)備正常。
“AT+UART”:查看設(shè)備的串口通信參數(shù),本實(shí)驗(yàn)?zāi)K藍(lán)牙模式的波特率為9600。
“AT+ADDR”:查看設(shè)備的藍(lán)牙地址。
“AT+ROLE”:查看設(shè)備的主從轉(zhuǎn)臺(tái),“0”為從模式,“1”為主模式。
“AT+PSWD”:查看設(shè)備當(dāng)前的配對(duì)碼,默認(rèn)是1234。
“AT+NAME”:查看設(shè)備當(dāng)前的名稱,默認(rèn)是 HC-05。
“AT+RESET”:重啟設(shè)備。
用AT指令配置設(shè)備
發(fā)送完上述AT指令查看完設(shè)備信息后,需要根據(jù)你的情況修改一些設(shè)備信息,方法是,在相應(yīng)的AT指令后加“=”號(hào),輸入要修改的信息即可,本項(xiàng)目主要修改信息如下例:
“AT+ROLE=0”:設(shè)置藍(lán)牙設(shè)備為從模式。
“AT+PSWD=123456”:修改配對(duì)碼為123456,用戶自定義。
“AT+NAME=Carduino”:修改名稱為Carduino,用戶自定義。
“AT+UART=9600,0,0”:修改藍(lán)牙工作狀態(tài)波特率為9600,無(wú)停止位和校驗(yàn)位。
- 注意!每次都要回車到第二行再點(diǎn)擊“Send” -
由于硬件存在一定的缺陷,HC-05藍(lán)牙模塊在設(shè)置【NAME】參數(shù)時(shí)會(huì)有些問(wèn)題,可能需要多設(shè)置幾次。
如果改名不成功,請(qǐng)使用“AT+ADDR”查詢藍(lán)牙設(shè)備地址,在手機(jī)上根據(jù)搜索到的設(shè)備地址來(lái)連接藍(lán)牙模塊。
3.4 下載安裝BlueSPP軟件,設(shè)置按鍵消息
BlueSPP是一個(gè)手機(jī)端的藍(lán)牙串口通訊通信工具,可以連接藍(lán)牙設(shè)備,通過(guò)串行通訊協(xié)議發(fā)送消息。
打開(kāi)APP
- 進(jìn)入BlueSPP -
連接設(shè)備
- 點(diǎn)右上角圖標(biāo)搜索設(shè)備 -
連接
- 輸入事先配置的配對(duì)碼 -
APP首頁(yè)可以在聊天窗口中向設(shè)備發(fā)送消息
- 可以發(fā)送消息 -
右滑,進(jìn)入自定義鍵盤頁(yè)面,每個(gè)按鈕的“名稱”可定義,按鈕對(duì)應(yīng)的“按下”,“松開(kāi)”事件都可配置成發(fā)送特定消息
- 配置按鈕“前進(jìn)” -
- 配置按鈕“左轉(zhuǎn)” -
- 配置按鈕“后退” -
- 配置結(jié)束 -
按鍵名稱按下發(fā)送松開(kāi)發(fā)送
前進(jìn)w
后退xs
左轉(zhuǎn)aw
右轉(zhuǎn)dw
停止s
上表為筆者的配置,大家可以根據(jù)自己的控制習(xí)慣進(jìn)行設(shè)置。
4. 整車測(cè)試
終于到激動(dòng)人心的最終環(huán)節(jié)了
4.1 給Arduino連接藍(lán)牙模塊
- 連接藍(lán)牙 -
4.2 使用獨(dú)立電源測(cè)試
打開(kāi)開(kāi)關(guān),L298N、Arduino、和HC-05藍(lán)牙模塊上的能正常閃爍,就可以在手機(jī)端用BlueSPP連接藍(lán)牙,讓小車下地開(kāi)始真正的遙控測(cè)試了。
三、參考代碼
char serial_data; // 將從串口讀入的消息存儲(chǔ)在該變量中
int wheel_R_1 = 5; // 右輪in1對(duì)應(yīng)Arduino 5號(hào)引腳
int wheel_R_2 = 6; // 右輪in2對(duì)應(yīng)Arduino 6號(hào)引腳
int wheel_L_1 = 9; // 左輪in1對(duì)應(yīng)Arduino 9號(hào)引腳
int wheel_L_2 = 10; // 左輪in2對(duì)應(yīng)Arduino 10號(hào)引腳
void setup(){
// 配置所有控制輪的引腳為輸出
pinMode(wheel_L_1, OUTPUT);
pinMode(wheel_L_2, OUTPUT);
pinMode(wheel_R_1, OUTPUT);
pinMode(wheel_R_2, OUTPUT);
// 配置串口波特率
Serial.begin(9600);
}
void loop(){
if(Serial.available()){
// 將從串口讀入的消息存儲(chǔ)在該變量中
serial_data = Serial.read();
// 按照 w a s d x 在鍵盤上的布局來(lái)控制車
// 如果接收到 w ,直行
if( serial_data == 'w' ){
move_ahead( );
Serial.println('The car is moving ahead!');
}
// 如果接收到 x ,后退
else if( serial_data == 'x'){
move_backwards( );
Serial.println('The car is moving backwards!');
}
// 如果接收到 a ,左轉(zhuǎn)
else if( serial_data == 'a'){
turn_left( );
Serial.println('The car is turning left!');
}
// 如果接收到 d ,右轉(zhuǎn)
else if( serial_data == 'd'){
turn_right( );
Serial.println('The car is turning right!');
}
// 如果接收到 s ,停止
else if( serial_data == 's'){
stop();
Serial.println('The car is stopping!');
}
}
}
// 定義直行函數(shù)
void move_ahead(){
digitalWrite( wheel_L_1, HIGH);
digitalWrite( wheel_L_2, LOW);
digitalWrite( wheel_R_1, HIGH);
digitalWrite( wheel_R_2, LOW);
}
// 定義后退函數(shù)
void move_backwards(){
digitalWrite( wheel_L_1, LOW);
digitalWrite( wheel_L_2, HIGH);
digitalWrite( wheel_R_1, LOW);
digitalWrite( wheel_R_2, HIGH);
}
// 定義左轉(zhuǎn)函數(shù)
void turn_left(){
digitalWrite( wheel_L_1, LOW);
digitalWrite( wheel_L_2, LOW);
digitalWrite( wheel_R_1, HIGH);
digitalWrite( wheel_R_2, LOW);
}
// 定義右轉(zhuǎn)函數(shù)
void turn_right(){
digitalWrite( wheel_L_1, HIGH);
digitalWrite( wheel_L_2, LOW);
digitalWrite( wheel_R_1, LOW);
digitalWrite( wheel_R_2, LOW);
}
void stop(){
digitalWrite( wheel_L_1, LOW);
digitalWrite( wheel_L_2, LOW);
digitalWrite( wheel_R_1, LOW);
digitalWrite( wheel_R_2, LOW);
}