遙控車玩起來總是很有趣,我個(gè)人是這些遙控車的忠實(shí)粉絲, 并且已經(jīng)(仍然)廣泛地玩過它們。如今,這些汽車中的大多數(shù)都提供了巨大的扭矩來應(yīng)對(duì)崎嶇的地形,但有些東西總是滯后,它的速度??!。。 所以,在這個(gè)項(xiàng)目中,我們將 使用 Arduino 構(gòu)建一個(gè)完全不同類型的 RC 汽車,主要這輛車的目標(biāo)是達(dá)到最高速度,因此我決定為遙控車試用 無芯直流電機(jī)。這些電機(jī)通常用于無人機(jī),額定轉(zhuǎn)速為 39000 RPM 這應(yīng)該足以滿足我們對(duì)速度的渴望。該車將由一塊小型鋰電池供電,并可使用 nRF24L01 射頻模塊進(jìn)行遠(yuǎn)程控制。
遙控車用無芯直流電機(jī)
該項(xiàng)目中使用的無芯直流電機(jī)如下圖所示。您可以輕松找到它們,因?yàn)樗鼈儚V泛用于迷你無人機(jī)。只需尋找 8520 磁性微型空心杯電機(jī),您就會(huì)找到這些。
現(xiàn)在,將直流電機(jī)用于遙控車存在某些缺點(diǎn)。首先是它們提供非常低的啟動(dòng)扭矩,因此我們的遙控車應(yīng)該盡可能輕巧。這就是為什么我決定使用 SMD 組件在 PCB 上構(gòu)建整個(gè)汽車并盡可能減小電路板尺寸的原因。第二個(gè)問題是它的高速,39000 RPM(軸的 RPM)很難處理,所以我們需要在 Arduino 端使用 MOSFET 構(gòu)建的速度控制電路。第三件事是這些電機(jī)將由單個(gè)鋰聚合物電池供電,工作電壓在 3.6V 至 4.2V 之間,因此我們必須將電路設(shè)計(jì)為在 3.3V 上工作。這就是我們使用3.3V Arduino Pro mini的原因作為我們遙控車的大腦。理清了這些問題,我們來看看搭建這個(gè)項(xiàng)目所需要的材料。
所需材料
3.3V Arduino Pro Mini
Arduino納米
NRF24L01 – 2 個(gè)
操縱桿模塊
SI2302 MOSFET
1N5819 二極管
無鐵芯 BLDC 電機(jī)
AMS1117-3.3V
鋰聚合物電池
連接線
使用 Arduino 的遙控車射頻操縱桿
如前所述,遙控車將使用射頻操縱桿進(jìn)行遠(yuǎn)程控制。該操縱桿也將使用 Arduino 和 nRF24L01 RF 模塊構(gòu)建,我們還使用操縱桿模塊在所需方向控制我們的 RC。如果您對(duì)這兩個(gè)模塊完全陌生,您可以考慮閱讀使用 nRF24L01 連接 Arduino和使用 Arduino 連接操縱桿的文章,以了解它們的工作原理以及如何使用它們。要構(gòu)建您的Arduino RF 遠(yuǎn)程操縱桿,您可以按照下面的電路圖進(jìn)行操作。
RF 操縱桿電路可以使用納米板的 USB 端口供電。nRF24L01 模塊僅在 3.3V 上運(yùn)行,因此我們?cè)?Arduino 上使用了 3.3V 引腳。我在面包板上構(gòu)建了電路,如下所示,如果需要,您也可以為此創(chuàng)建一個(gè) PCB。
RF 操縱桿電路的Arduino 代碼非常簡(jiǎn)單,我們必須從操縱桿中讀取 X 值和 Y 值并通過 nRF24L01 將其發(fā)送到 RC 車。該電路的完整程序可以在本頁底部找到。我們不會(huì)對(duì)此進(jìn)行解釋,因?yàn)槲覀円呀?jīng)在上面共享的接口項(xiàng)目鏈接中討論了它。
Arduino RC 汽車電路圖
我們的遙控 Arduino 汽車的完整電路圖如下所示。電路圖還包括向我們的汽車添加兩個(gè) TCRT5000 IR 模塊的選項(xiàng)。這是為了讓我們的遙控車能夠作為線跟隨機(jī)器人工作,這樣它就可以獨(dú)立工作而不受外部控制。但是,為了這個(gè)項(xiàng)目,我們不會(huì)專注于它,請(qǐng)繼續(xù)關(guān)注另一個(gè)項(xiàng)目教程,我們將在其中嘗試構(gòu)建“Fastest Line Follower Robot”。為了便于構(gòu)建,我將兩個(gè)電路組合在一個(gè) PCB 上,您可以忽略該項(xiàng)目的 IR 傳感器和運(yùn)算放大器部分。
遙控車將由連接到終端 P1 的鋰電池供電。AMS117-3.3V用于為我們的 nRF24L01 和我們的專業(yè)迷你板調(diào)節(jié) 3.3V。我們也可以直接在原始引腳上為 Arduino 板供電,但 pro mini 上的板載 3.3V 穩(wěn)壓器將無法為我們的射頻模塊提供足夠的電流,因此我們使用了外部穩(wěn)壓器。
為了驅(qū)動(dòng)我們的兩個(gè) BLDC 電機(jī),我們使用了兩個(gè) SI2302 MOSFET。確保這些 MOSFET 可由 3.3V 驅(qū)動(dòng)非常重要。如果您找不到完全相同的部件號(hào),您可以尋找具有以下傳輸特性的等效 MOSFET
電機(jī)可以消耗高達(dá) 7A 的峰值電流(在負(fù)載下連續(xù)測(cè)試為 3A),因此 MOSFET 漏極電流應(yīng)為 7A 或更高,并且應(yīng)在 3.3V 時(shí)完全開啟。正如您在此處看到的,我們選擇的 MOSFET 即使在 2.25V 下也可以提供 10A,因此它是一個(gè)理想的選擇。
為 Arduino 遙控車制造 PCB
構(gòu)建這個(gè)項(xiàng)目的有趣部分是 PCB 開發(fā)。這里的 PCB 不僅形成電路,而且還充當(dāng)我們汽車的底盤,因此我們?yōu)樗O(shè)計(jì)了一個(gè)看起來像汽車的形狀,并且可以選擇輕松安裝我們的電機(jī)。您也可以嘗試使用上面的電路設(shè)計(jì)自己的 PCB,或者您可以使用我的 PCB 設(shè)計(jì),完成后如下所示。
如您所見,我設(shè)計(jì)的 PCB 可以輕松安裝電池、電機(jī)和其他組件。
組裝印刷電路板
我打開焊條并開始組裝電路板。由于腳印、焊盤、通孔和絲網(wǎng)印刷的形狀和尺寸都非常完美,因此組裝電路板沒有問題。從開箱開始,僅用了 10 分鐘,電路板就準(zhǔn)備好了。
焊接后的幾張電路板圖片 如下所示。
3D 打印輪子和電機(jī)支架
正如您在上圖中可能已經(jīng)注意到的那樣,我們需要對(duì)機(jī)器人的電機(jī)支架和輪子進(jìn)行 3D 建模。如果您使用了我們上面共享的 PCB Gerber 文件,那么您不妨從這個(gè)thingiverse 鏈接下載它來使用 3D 模型。
我使用 Cura 對(duì)我的模型進(jìn)行切片并使用 Tevo Terantuala 打印它們,沒有支撐和 0% 填充以減輕重量。您可以更改適合我們打印機(jī)的設(shè)置。由于電機(jī)旋轉(zhuǎn)得非???,我發(fā)現(xiàn)設(shè)計(jì)一個(gè)與電機(jī)軸緊密貼合的輪子非常困難。因此,我決定在輪子內(nèi)使用無人機(jī)葉片,如下所示
我發(fā)現(xiàn)這更可靠和堅(jiān)固,但是,嘗試不同的車輪設(shè)計(jì),并在評(píng)論部分告訴我什么對(duì)你有用。
對(duì) Arduino 進(jìn)行編程
該項(xiàng)目的完整程序(Arduino nano 和 pro mini)可以在本頁底部找到。你的RC程序的解釋如下
我們通過包含所需的頭文件來啟動(dòng)程序。請(qǐng)注意,nRF24l01 模塊需要將庫(kù)添加到您的 Arduino IDE,您可以使用此鏈接從 Github 下載 RF24 庫(kù)。除此之外,我們已經(jīng)為我們的機(jī)器人定義了最小速度和最大速度。最小和最大范圍分別為 0 到 1024。
#define min_speed 200 #define max_speed 800 #include#include "RF24.h" RF24 myRadio (7, 8);
然后在 setup 函數(shù)中,我們初始化我們的 nRF24L01 模塊。我們使用了 115 個(gè)頻段,因?yàn)樗粨砣?,并且已將模塊設(shè)置為低功耗運(yùn)行,您也可以使用這些設(shè)置。
無效設(shè)置(){ 串行.開始(9600); myRadio.begin(); myRadio.setChannel(115); //115頻段以上WIFI信號(hào) myRadio.setPALevel(RF24_PA_MIN); //MIN 功率低范圍 myRadio.setDataRate(RF24_250KBPS); //最低速度 }
接下來在主循環(huán)函數(shù)中,我們將只執(zhí)行 ReadData 函數(shù),我們將使用該函數(shù)不斷讀取從 Transmitter 操縱桿模塊發(fā)送的值。注意程序中提到的管道地址應(yīng)該和發(fā)射器程序中提到的一樣。我們還打印了我們收到的用于調(diào)試目的的值。成功讀取值后,我們將執(zhí)行 Control Car 功能,根據(jù)從
Rf 模塊接收到的值來控制我們的 RC 汽車。
無效讀取數(shù)據(jù)() { myRadio.openReadingPipe(1, 0xF0F0F0F0AA); //讀取哪個(gè)管道,40位地址 myRadio.startListening(); //停止傳輸并開始接收 if (myRadio.available()) { 而(myRadio.available()) { myRadio.read( &data, sizeof(data) ); } Serial.print("\n收到:"); 序列號(hào).println(data.msg); 收到 = data.msg; 控制車(); } }
在 Control Car 函數(shù)中,我們將使用模擬寫入函數(shù)控制連接到 PWM 引腳的電機(jī)。在我們的發(fā)射器程序中,我們將 Nano 的 A0 和 A1 引腳的模擬值轉(zhuǎn)換為 1 到 10、11 到 20、21 到 30 和 31 到 40,分別用于控制汽車的前進(jìn)、后退、左轉(zhuǎn)和右轉(zhuǎn)。下面的程序用于控制機(jī)器人的前進(jìn)方向
if (received>=1 && received <=10) // 前進(jìn) { int PWM_Value = map (收到, 1, 10, min_speed, max_speed); 模擬寫入(R_MR,PWM_Value); 模擬寫入(L_MR,PWM_Value); }
同樣的,我們也可以多寫三個(gè)函數(shù)來進(jìn)行反向、左、右控制,如下圖。
if (received>=11 && received <=20) // 中斷 { int PWM_Value = map (收到, 11, 20, min_speed, max_speed); 類比寫入(R_MR,0); 類比寫入(L_MR,0); } if (received>=21 && received <=30) // 左轉(zhuǎn) { int PWM_Value = map (收到, 21, 30, min_speed, max_speed); 模擬寫入(R_MR,PWM_Value); 類比寫入(L_MR,0); } if (received>=31 && received <=40) // 右轉(zhuǎn) { int PWM_Value = map (收到, 31, 40, min_speed, max_speed); 類比寫入(R_MR,0); 模擬寫入(L_MR,PWM_Value); }
Arduino 遙控車的工作
完成代碼后,將其上傳到您的專業(yè)迷你板上。通過 FTDI 模塊取出電池和電路板進(jìn)行測(cè)試。啟動(dòng)您的代碼,打開串行電池,您應(yīng)該會(huì)收到來自發(fā)射器操縱桿模塊的值。連接你的電池,你的電機(jī)也應(yīng)該開始旋轉(zhuǎn)。
射頻遙控操縱桿
/*將射頻值傳輸?shù)?Arduino 的代碼
*
* 引腳連接
* CE - 7
MISO - 12
MOSI - 11
SCK - 13
CS - 8
A0 - JoyX
A1 - JoyY
*/
#include
#include "RF24.h "
RF24 myRadio (7, 8);
結(jié)構(gòu)包
{
int msg = 0;
};
字節(jié)地址[][6] = {"0"};
typedef struct package 封裝;
包裝資料;
無效設(shè)置()
{
序列.開始(9600);
myRadio.begin();
myRadio.setChannel(115); //115頻段以上WIFI信號(hào)
myRadio.setPALevel(RF24_PA_MAX); //MAX power long 憤怒
myRadio.setDataRate(RF24_250KBPS); //最小速度
延遲(500);
Serial.print("遠(yuǎn)程初始化");
}
向前詮釋;
逆向;
int左;
詮釋正確;
無效循環(huán)()
{
int xValue = 模擬讀取(A0);//讀取JoyX值
int yValue = analogRead(A1); //讀取JoyY值
//Serial.print(xValue); 序列號(hào).print(" , "); Serial.println(yValue);
if (xValue>560 && xValue<1000) // 為向上過濾 JoyX
{
forward = map (xValue, 560, 1000, 1, 10); //將 Joyx-up 轉(zhuǎn)換為 0-10
//Serial.print("F="); Serial.println(轉(zhuǎn)發(fā));
data.msg = 轉(zhuǎn)發(fā);寫入數(shù)據(jù)();延遲(50);
}
if (xValue<500 && xValue > 10) // 過濾 JoyX 的 break
{
reverse = map (xValue, 10, 500, 20, 11); //將JoyX-down轉(zhuǎn)換為11-20
//Serial.print("B="); Serial.println(反向);
data.msg = 反向;寫入數(shù)據(jù)();延遲(50);
}
else if (yValue>600 && yValue<1000) // 為右過濾 JoyY
{
right = map (yValue, 600, 1000, 21, 30); //將 JoyY-right 轉(zhuǎn)換為 21-30
//Serial.print("R="); Serial.println(右);
data.msg = 對(duì);寫入數(shù)據(jù)();延遲(50);
}
else if (yValue<450 && yValue > 10) // 過濾 JoyY 為 left
{
left = map (yValue, 10, 450, 40, 31); //將JoyY-left轉(zhuǎn)換為31-40
//Serial.print("
data.msg = 左;寫入數(shù)據(jù)();延遲(50);
}
/* else
{
Serial.println("Rest");
數(shù)據(jù).msg = 0; 寫入數(shù)據(jù)();延遲(50);
}
*/
}
void WriteData()
{
myRadio.stopListening(); //停止接收并開始發(fā)送
myRadio.openWritingPipe(0xF0F0F0F0AA); //在這個(gè) 40 位地址上發(fā)送數(shù)據(jù)
myRadio.write(&data, sizeof(data));
//Serial.print("\nSent:");
//Serial.println(data.msg);
延遲(50);
}
void ReadData()
{
myRadio.openReadingPipe(1, 0xF0F0F0F066); // 讀取哪個(gè)管道,40 位地址
myRadio.startListening(); //停止傳輸并開始接收
if ( myRadio.available())
{
while (myRadio.available())
{
myRadio.read( &data, sizeof(data) );
}
Serial.print("\n收到:");
序列號(hào).println(data.msg);
}
}
無刷直流電機(jī)
/*CE - 7
MISO - 12
MOSI - 11
SCK - 13
CS - 8
最近用 nano 測(cè)試
*/
/*PIN DEFANITIONS*/
#define R_IR 3
#define L_IR 4
#define L_MR 5
#define R_MR 6
#define min_speed 200
#定義 max_speed 800
#include
#include "RF24.h"
RF24 myRadio (7, 8);
結(jié)構(gòu)包
{
int msg;
};
typedef struct package 封裝;
包裝資料;
字節(jié)地址[][6] = {"0"};
無效設(shè)置(){
pinMode(R_IR,輸入);
pinMode(L_IR,輸入);
pinMode(L_MR,輸出);
pinMode(R_MR,輸出);
串行.開始(9600);
myRadio.begin();
myRadio.setChannel(115); //115頻段以上WIFI信號(hào)
myRadio.setPALevel(RF24_PA_MIN); //MIN 功率低
范圍 myRadio.setDataRate( RF24_250KBPS ) ; //最低速度
}
int received;
無效循環(huán)(){
讀取數(shù)據(jù)();
}
void Control_Car()
{
if (received>=1 && received <=10) // 向前移動(dòng)
{
int PWM_Value = map (received, 1, 10, min_speed, max_speed);
模擬寫入(R_MR,PWM_Value);
模擬寫入(L_MR,PWM_Value);
}
if (received>=11 && received <=20) // 中斷
{
int PWM_Value = map (收到, 11, 20, min_speed, max_speed);
類比寫入(R_MR,0);
類比寫入(L_MR,0);
}
if (received>=21 && received <=30) // 右轉(zhuǎn)
{
int PWM_Value = map (received, 21, 30, min_speed, max_speed);
模擬寫入(R_MR,PWM_Value);
類比寫入(L_MR,0);
}
if (received>=31 && received <=40) // 右轉(zhuǎn)
{
int PWM_Value = map (received, 31, 40, min_speed, max_speed);
類比寫入(R_MR,0);
模擬寫入(L_MR,PWM_Value);
}
}
void ReadData()
{
myRadio.openReadingPipe(1, 0xF0F0F0F0AA); //讀取哪個(gè)管道,40位地址
myRadio.startListening(); //停止傳輸并開始接收
if ( myRadio.available())
{
while (myRadio.available())
{
myRadio.read( &data, sizeof(data) );
}
Serial.print("\n收到:");
序列號(hào).println(data.msg);
收到 = data.msg;
控制車();
}
else //如果不是來自 RF 的數(shù)據(jù)
{
//analogWrite(R_MR,0);
//analogWrite(L_MR,0);
}
}
void WriteData()
{
myRadio.stopListening(); //停止接收并開始發(fā)送
myRadio.openWritingPipe(0xF0F0F0F066);//在這個(gè) 40 位地址上發(fā)送數(shù)據(jù)
myRadio.write(&data, sizeof(data));
Serial.print("\n已發(fā)送:");
序列號(hào).println(data.msg);
延遲(300);
}
-
nRF24L01
+關(guān)注
關(guān)注
17文章
330瀏覽量
69358 -
遙控車
+關(guān)注
關(guān)注
9文章
81瀏覽量
23666 -
Arduino
+關(guān)注
關(guān)注
187文章
6459瀏覽量
186520
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論