博客專欄

EEPW首頁 > 博客 > LabVIEW Arduino無線藍(lán)牙遙控智能車(項(xiàng)目篇—2)

LabVIEW Arduino無線藍(lán)牙遙控智能車(項(xiàng)目篇—2)

發(fā)布人:美男子玩編程 時(shí)間:2022-07-29 來源:工程師 發(fā)布文章

1


項(xiàng)目概述


智能小車是以輪子作為移動(dòng)機(jī)構(gòu),并且能夠?qū)崿F(xiàn)自主行駛的機(jī)器人,又被稱為輪式機(jī)器人。由于具有智能化的特點(diǎn),可以應(yīng)用于不適合人類工作的環(huán)境中,例如災(zāi)難救援、戶外探險(xiǎn)等。智能小車有別于遙控小車,因?yàn)楹笳咝枰僮魅藛T來控制其轉(zhuǎn)向、啟停和前進(jìn)后退,以及控制其速度,常見的模型小車,都屬于這類遙控車。智能小車,則可以通過計(jì)算機(jī)編程來實(shí)現(xiàn)其對(duì)行駛方向、啟停以及速度的控制,無須人工干預(yù),也可以通過修改智能小車的程序來改變它的行駛方式。


圖片


智能小車的典型特點(diǎn)有:

1、擁有至少一個(gè)微控制器,通過微控制器來實(shí)現(xiàn)對(duì)行駛方向、啟停和速度的控制。

2、擁有多個(gè)各種功能的傳感器,以獲取外界環(huán)境的情況,以供控制器做出準(zhǔn)確的決策。


2


項(xiàng)目架構(gòu)


本節(jié)將要介紹一種基于Arduino與LabVIEW的無線遙控智能小車,可以實(shí)現(xiàn)自主(巡線和避障)與遙控兩種功能,并且可以在兩種功能之間進(jìn)行切換。智能小車采用Arduino作為控制核心,上位機(jī)軟件采用LabVIEW,兩者通過APC220無線數(shù)傳模塊實(shí)現(xiàn)無線通信。無線遙控智能小車總體框圖如下圖所示:


圖片


智能小車的車體采用兩個(gè)驅(qū)動(dòng)輪、一個(gè)萬向輪的三輪式小車模型,驅(qū)動(dòng)電機(jī)采用直流減速電機(jī),電機(jī)驅(qū)動(dòng)模塊采用VNH2SP30模塊,循跡傳感器采用OPENJUMPER紅外巡線傳感器OJ-CG307,避障傳感器采用OPENJUMPER紅外避障傳感器OJ-CG303。


智能小車的巡線場(chǎng)地為白底黑線,線寬約10mm,場(chǎng)地大小約為200cm×300cm。


圖片

3


傳感器和控制器


3.1、傳感器


本節(jié)介紹的無線遙控智能小車,可以實(shí)現(xiàn)自主與遙控兩種功能,并且可以在兩種功能之間進(jìn)行切換。當(dāng)小車處于遙控狀態(tài)時(shí),操作者通過操作LabVIEW上位機(jī)軟件,利用APC220串口無線模塊向小車上的Arduino控制器發(fā)送遙控指令,從而使小車做出指定的行為動(dòng)作。而當(dāng)小車處于自主狀態(tài)時(shí)候,小車上的Arduino控制器通過四個(gè)紅外巡線傳感器和一個(gè)紅外避障傳感器獲取小車相對(duì)于黑線的位置和前面是否有障礙物的信號(hào),并根據(jù)程序中設(shè)置的邏輯來控制直流減速電機(jī),以實(shí)現(xiàn)巡線和避障的功能。


紅外巡線傳感器模塊是利用紅外對(duì)管檢測(cè)模塊本身發(fā)出的紅外線的反射光(深色反射弱,淺色反射強(qiáng)),來為循跡機(jī)器人提供白線或者黑線的跟蹤,既可以檢測(cè)白底中的黑線,也可以檢測(cè)黑底中的白線,若檢測(cè)到白線則輸出高電平,若檢測(cè)到黑線則輸出低電平。


紅外避障傳感器****紅外線并根據(jù)反射回來的紅外光判斷前方是否存在障礙物,無障礙物時(shí)輸出高電平,有障礙時(shí)輸出低電平,在信號(hào)輸出同時(shí)有指示燈指示狀態(tài),無障礙物時(shí)LED為綠,有障礙物時(shí)為紅。同時(shí)內(nèi)置38kHz的信號(hào)發(fā)生器,抗干擾能力強(qiáng)。通過調(diào)節(jié)模塊上的2KΩ電位器,可以調(diào)節(jié)傳感器的探測(cè)距離。


紅外巡線傳感器模塊如下圖所示:


圖片


紅外避障傳感器模塊如下圖所示:


圖片


3.2、控制器


一般情況下,直流電機(jī)需要很大的驅(qū)動(dòng)電流,而像Arduino之類的控制器輸出的邏輯電平無法直接驅(qū)動(dòng)直流電機(jī),特別是大功率的減速電機(jī),所以就需要通過驅(qū)動(dòng)器件給直流電機(jī)提供工作電流。


Arduino愛好者常用的直流電機(jī)驅(qū)動(dòng)模塊主要有L298模塊和VNH2SP30模塊。

L298電機(jī)驅(qū)動(dòng)模塊價(jià)格較為便宜,而且單個(gè)L298芯片可以同時(shí)驅(qū)動(dòng)兩路直流電機(jī),所以在Arduino愛好者制作機(jī)器人小車時(shí)使用較多,但是其轉(zhuǎn)化效率較低,發(fā)熱量較大,不適合驅(qū)動(dòng)大電流直流電機(jī),當(dāng)驅(qū)動(dòng)大電流電機(jī)時(shí)容易發(fā)生芯片"假死"等故障。


圖片


VNH2SP30模塊具有驅(qū)動(dòng)電流大、轉(zhuǎn)換效率高等優(yōu)點(diǎn)但是單個(gè)VNH2SP30芯片只能驅(qū)動(dòng)一路直流電機(jī),如果驅(qū)動(dòng)兩路直流電機(jī)則需要兩個(gè)VNH2SP30芯片。 


圖片


為了使得遙控智能小車具有良好的動(dòng)力系統(tǒng),具有一定的載重能力,此處選用直流減速電機(jī)作為整個(gè)遙控智能小車的動(dòng)力來源,并選用顆粒輪胎,以提高抓地能力。


圖片



4


硬件環(huán)境


將兩個(gè)直流減速電機(jī)的兩端分別接至VNH2SP30電機(jī)驅(qū)動(dòng)模塊上的OUT1A、OUT1B和OUT2A、OUT2B,無正負(fù)極和電機(jī)轉(zhuǎn)向之分。若電機(jī)轉(zhuǎn)向相反,則在調(diào)試過程中將電機(jī)的連接線對(duì)調(diào)連接。將VNH2SP30電機(jī)驅(qū)動(dòng)模塊的+5V (IN)、GND分別接至Arduino Uno控制板上的+5V、GND,為電機(jī)驅(qū)動(dòng)模塊提供工作電壓。


將VNH2SP30電機(jī)驅(qū)動(dòng)模塊的1INA、1INB、1PWM分別接至Arduino Uno控制板上的數(shù)字端口D7、D6、D5,為電機(jī)1提供轉(zhuǎn)向和調(diào)速控制信號(hào);將VNH2SP30電機(jī)驅(qū)動(dòng)模塊的2INA、2INB、2PWM分別接至Arduino Uno控制板上的數(shù)字端口D4、D2、D3,為電機(jī)2提供轉(zhuǎn)向和調(diào)速控制信號(hào)。需要注意的是,1PWM和2PWM需要接在具有模擬輸出(PWM)功能的數(shù)字端口。


Arduino控制器與驅(qū)動(dòng)及電機(jī)部分的硬件連接,如下圖所示:


圖片


將一個(gè)APC220模塊與Arduino Uno控制板相連接,連接方式如下:


APC220 TXD→Arduino Uno控制板RXD,APC220 RXD→Arduino Uno控制板TXD,APC220 VCC→Arduino Uno控制板5V,APC220 GND→Arduino Uno控制板GND。


將另一塊APC220模塊通過FT232RL轉(zhuǎn)接板相連接,連接方式如下:


APC220 TXD→FT232RL轉(zhuǎn)接板RXD,APC220 RXD→FT232RL轉(zhuǎn)接板TXD,APC220 VCC→FT232RL轉(zhuǎn)接板5V,APC220 GND→FT232RL轉(zhuǎn)接板GND。

將四個(gè)紅外巡線傳感器依次連接至Arduino Uno控制板的數(shù)字端口D8、D9、D10、D11,并在將紅外巡線傳感器安裝至智能小車底盤時(shí),對(duì)應(yīng)于左2、左1、右1和右2。將紅外避障傳感器連接至Arduino Uno控制板的數(shù)字端口D12,并將其安裝在小車車頭的前端。



5


Arduino功能設(shè)計(jì)


4個(gè)紅外巡線傳感器在智能小車底盤上的安裝示意圖如下圖所示:


圖片


初始狀態(tài)為黑線位于左1和右1傳感器之間,表明小車處于黑線中間部分;當(dāng)左1傳感器檢測(cè)到黑線時(shí),表明小車相對(duì)于黑線略微偏向右側(cè),需要小幅度左轉(zhuǎn)以修正偏差;當(dāng)左2傳感器檢測(cè)到黑線時(shí),表明小車相對(duì)于黑線偏向右側(cè)較多,需要大幅度左轉(zhuǎn)以修正偏差;當(dāng)右1傳感器檢測(cè)到黑線時(shí),表明小車相對(duì)于黑線略微偏向左側(cè),需要小幅度右轉(zhuǎn)以修正偏差;當(dāng)右2傳感器檢測(cè)到黑線時(shí),表明小車相對(duì)于黑線偏向左側(cè)較多,需要大幅度右轉(zhuǎn)以修正偏差。


遙控部分的調(diào)速將速度分為5檔,分別為低速、中低速、中速、中高速和高速,通過VNH2SP30電機(jī)驅(qū)動(dòng)模塊的PWM輸入信號(hào)實(shí)現(xiàn)在五檔之間切換與調(diào)速。

Arduino Uno控制器程序代碼如下所示:




















































































































































































































#define forward_command   0x00   //前進(jìn)命令#define back_command      0x10   //后退命令#define left_command       0x20   //左轉(zhuǎn)命令#define right_command      0x30   //右轉(zhuǎn)命令#define stop_command      0x40   //停止命令 #define speed_1           0x50   //低速命令#define speed_2           0x60   //中低速命令#define speed_3           0x70   //中速命令#define speed_4           0x80   //中高速命令#define speed_5           0x90   //高速命令 byte comdata[3]={0};   //定義數(shù)組數(shù)據(jù),用于存放串口命令數(shù)據(jù)int flag = 0;           //遙控/自動(dòng)標(biāo)志位,默認(rèn)為遙控模式 int INA1 = 7;int INB1 = 6;int PWM1 = 5;      //定義電機(jī)1的轉(zhuǎn)向和速度的控制引腳int INA2 = 4;int INB2 = 2;int PWM2 = 3;      //定義電機(jī)2的轉(zhuǎn)向和速度的控制引腳 int Trace_sensor_X1=8;int Trace_sensor_X2=9;int Trace_sensor_Y1=10;int Trace_sensor_Y2=11;      //定義四個(gè)紅外循跡傳感器的引腳int Avoidance_sensor=12;     //定義紅外避障傳感器的引腳 void receive_data(void);      //接收串口命令數(shù)據(jù)void test_do_data(void);      //測(cè)試串口命令數(shù)據(jù)是否正確,并執(zhí)行命令 void forward(void);        //前進(jìn)子函數(shù)void back(void);           //后退子函數(shù)void turn_Left(void);        //左轉(zhuǎn)子函數(shù)void turn_Right(void);       //右轉(zhuǎn)子函數(shù)void stop_car(void);             //停止子函數(shù) void Automatic_mode(void);      //自動(dòng)模式子函數(shù) void setup(){  Serial.begin(9600);             //初始化串口波特率為9600  pinMode(INA1, OUTPUT);  pinMode(INB1, OUTPUT);  pinMode(PWM1, OUTPUT);      //設(shè)置電機(jī)1的控制引腳為輸出狀態(tài)  pinMode(INA2, OUTPUT);  pinMode(INB2, OUTPUT);  pinMode(PWM2, OUTPUT);      //設(shè)置電機(jī)2的控制引腳為輸出狀態(tài)   pinMode(Trace_sensor_X1, INPUT);  pinMode(Trace_sensor_X2, INPUT);  pinMode(Trace_sensor_Y1, INPUT);  pinMode(Trace_sensor_Y2, INPUT); //設(shè)置紅外循跡傳感器的控制引腳為輸入狀態(tài)  pinMode(Avoidance_sensor,INPUT); //設(shè)置紅外避障傳感器的控制引腳為輸入狀態(tài)   analogWrite(PWM1,150); //left motor  analogWrite(PWM2,150); //ringt motor    //將電機(jī)速度設(shè)置為中速檔位} void loop(){  if (Serial.available() > 0)      //不斷檢測(cè)串口是否有數(shù)據(jù)   {        receive_data();            //從串口緩沖區(qū)接收串口命令數(shù)據(jù)        test_do_data();            //測(cè)試串口命令數(shù)據(jù)是否正確并執(zhí)行命令   }   if(flag==1)            //判斷是否為自動(dòng)模式狀態(tài)   {   Automatic_mode();                 //執(zhí)行自動(dòng)模式  analogWrite(PWM1,150); //left motor   analogWrite(PWM2,150); //ringt motor     //將電機(jī)速度切換至中速檔位   }} void receive_data(void)   //從串口緩沖區(qū)接收串口命令數(shù)據(jù){   int i ;   for(i=0;i<3;i++)   //命令長(zhǎng)度為3個(gè)字節(jié),每次讀取3個(gè)字節(jié)   {      comdata[i] =Serial.read();   //讀取一個(gè)字節(jié)的數(shù)據(jù)      //延時(shí)一會(huì),讓串口緩存準(zhǔn)備好下一個(gè)字節(jié),不延時(shí)可能會(huì)導(dǎo)致數(shù)據(jù)丟失,       delay(2);   }} void test_do_data(void)      //測(cè)試串口命令數(shù)據(jù)是否正確并執(zhí)行命令{  if(comdata[0] == 0x55)            //0x55為命令幀頭,判斷幀頭是否正確   {     if(comdata[1] == 0xAA)        //0xAA為遙控模式命令     {  flag=0;               //切換至遙控模式         switch (comdata[2])         //匹配遙控模式中的具體命令          {            case forward_command:      //前進(jìn)命令                 forward();                 break;            case back_command:         //后退命令           back();                 break ;            case left_command:          //左轉(zhuǎn)命令           turn_Left();                 break ;            case right_command:         //右轉(zhuǎn)命令           turn_Right();                 break ;            case stop_command:         //停止命令           stop_car();                 break ;      case speed_1:               //低速命令           analogWrite(PWM1,50);           analogWrite(PWM2,50);                   break;            case speed_2:                //右轉(zhuǎn)命令           analogWrite(PWM1,100);            analogWrite(PWM2,100);                  break ;            case speed_3:                //右轉(zhuǎn)命令     analogWrite(PWM1,150);      analogWrite(PWM2,150);                  break ;            case speed_4:                //右轉(zhuǎn)命令     analogWrite(PWM1,200);      analogWrite(PWM2,200);                  break ;      case speed_5:                //右轉(zhuǎn)命令           analogWrite(PWM1,250);     analogWrite(PWM2,250);                  break ;          }                    }      if(comdata[1] == 0xFF)        //0xFF為自主模式命令      {        flag=1;               //切換至自主模式        comdata[2] = 0;               //清空命令數(shù)據(jù)      }   }} void Automatic_mode(void)     //自主模式,循跡和避障{  int State_value=0;  if(digitalRead(Avoidance_sensor)==0)   //避障功能,有障礙物則后退左轉(zhuǎn)  {    back();    delay(1000);    turn_Left();    delay(500);  }  //讀取紅外循跡傳感器組的狀態(tài)  State_value=digitalRead(Trace_sensor_X2)*8+digitalRead(Trace_sensor_X1)*4+digitalRead(Trace_sensor_Y1)*2+digitalRead(Trace_sensor_Y2);  switch (State_value)     //匹配狀態(tài),并調(diào)整位置         {            case 8:               //大幅度偏左,大角度右轉(zhuǎn)    turn_Right();    delay(200);                   break;            case 4:               //小幅度偏左,小角度右轉(zhuǎn)    turn_Right();          delay(100);                   break ;            case 2:               //小幅度偏右,小角度左轉(zhuǎn)    turn_Left();    delay(100);                   break ;            case 1:               //大幅度偏右,大角度左轉(zhuǎn)    turn_Left();    delay(200);                   break ;            default:               //其他狀態(tài),前進(jìn)    forward();    break;          }    } void forward(void)    //前進(jìn){  digitalWrite(INA1, LOW);   digitalWrite(INB1, HIGH);   digitalWrite(INA2, LOW);   digitalWrite(INB2, HIGH); }void back(void)    //后退{(lán)  digitalWrite(INA1, HIGH);   digitalWrite(INB1, LOW);   digitalWrite(INA2, HIGH);   digitalWrite(INB2, LOW); }void turn_Left(void)    //左轉(zhuǎn){  digitalWrite(INA1, LOW);   digitalWrite(INB1, HIGH);   digitalWrite(INA2, HIGH);   digitalWrite(INB2, LOW); }void turn_Right(void)    //右轉(zhuǎn){  digitalWrite(INA1, HIGH);   digitalWrite(INB1, LOW);   digitalWrite(INA2, LOW);   digitalWrite(INB2, HIGH); }void stop_car(void)    //停止{  digitalWrite(INA1, LOW);   digitalWrite(INB1, LOW);   digitalWrite(INA2, LOW);   digitalWrite(INB2, LOW); }



6


LabVIEW功能設(shè)計(jì)


LabVIEW上位機(jī)部分需要完成以下功能:

1、當(dāng)從遙控狀態(tài)切換至自主狀態(tài)時(shí),向下位機(jī)Arduino控制器發(fā)送自主狀態(tài)命令,Arduino控制器通過讀取紅外巡線傳感器和紅外避障傳感器,以實(shí)現(xiàn)巡線和避障的功能。

2、當(dāng)從自主狀態(tài)切換至遙控狀態(tài)時(shí),向下位機(jī)Arduino控制器發(fā)送遙控狀態(tài)命令,Arduino控制器通過讀取LabVIEW軟件發(fā)來的操作命令,并實(shí)現(xiàn)指定的動(dòng)作和行為,包括前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)、停止和調(diào)速。


6.1、前面板設(shè)計(jì)


LabVIEW前面板分為遙控模式和模式切換兩個(gè)部分,遙控模式部分用于控制小車的運(yùn)行狀態(tài),包括前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)、停止和調(diào)速;模式選擇部分用于切換遙控模式和自主模式。


無線遙控智能小車的LabVIEW上位機(jī)前面板,如下圖所示:


圖片


6.2、程序框圖設(shè)計(jì)


LabVIEW上位機(jī)主程序的結(jié)構(gòu)為順序結(jié)構(gòu)+While循環(huán)+事件結(jié)構(gòu)。首先,通過設(shè)置的串口號(hào)來初始化串口通信;然后,程序進(jìn)入While循環(huán)和事件結(jié)構(gòu),不斷地檢測(cè)是否有事件得到響應(yīng)并執(zhí)行;事件結(jié)構(gòu)有“模式選項(xiàng)"、“前進(jìn)”、“后退”、“左轉(zhuǎn)"、“右轉(zhuǎn)"、“停止"和“"調(diào)速"。最后,關(guān)閉串口通信。在程序框圖中,我們需要對(duì)串口進(jìn)行配置,并將根據(jù)不同的按鍵按下通過串口發(fā)出不同的命令,下位機(jī)Arduino Uno收到串口收據(jù),解析出其中的命令代碼后執(zhí)行相應(yīng)的命令。


為了更好地實(shí)現(xiàn)通信,制定如下的通信協(xié)議:幀頭+命令碼+操作碼。0x55為幀頭,0xAA為遙控命令,0xFF為自主命令,遙控命令的操作碼:0x00為前進(jìn),0x10為后退,0x20為左轉(zhuǎn),0x30為右轉(zhuǎn),0x40為停止,0x50為速度檔1,0x60為速度檔2,0x70為速度檔3,0x80為速度檔4,0x90為速度檔5。


在“模式選項(xiàng)”事件中,通過讀取當(dāng)前選擇的模式,向Arduino控制器分別發(fā)送0x55AA和Ox55FF,分別表示切換至遙控模式和自主模式?!澳J竭x項(xiàng)”值改變事件程序框圖如下圖所示:


圖片


在“前進(jìn)"事件中,通過串口向Arduino控制器發(fā)送0x55AA00,Arduino控制器將兩個(gè)直流減速電機(jī)均設(shè)置為前進(jìn)方向?!扒斑M(jìn)"值改變事件程序框圖如下圖所示:


圖片


在“后退"事件中,通過串口向Arduino控制器發(fā)送0x55AA10,Arduino控制器將兩個(gè)直流減速電機(jī)均設(shè)置為后退方向?!昂笸?quot;值改變事件程序框圖如下圖所示:


圖片


在“左轉(zhuǎn)"事件中,通過串口向Arduino控制器發(fā)送0x55AA20,Arduino控制器將右側(cè)電機(jī)設(shè)置為前進(jìn)方向、左側(cè)電機(jī)設(shè)置為后退方向,從而實(shí)現(xiàn)左轉(zhuǎn)?!白筠D(zhuǎn)"值改變事件程序框圖如下圖所示:


圖片


在“右轉(zhuǎn)”事件中,通過串口向Arduino控制器發(fā)送0x55AA30,Arduino控制器將右側(cè)電機(jī)設(shè)置為后退方向、左側(cè)電機(jī)設(shè)置為前進(jìn)方向,從而實(shí)現(xiàn)右轉(zhuǎn)?!坝肄D(zhuǎn)"值改變事件程序框圖如下圖所示:


圖片


均在“停止"事件中,通過串口向Arduino控制器發(fā)送0x55AA40,Arduino控制器將左、右兩個(gè)電機(jī)均設(shè)置為停止?fàn)顟B(tài),從而實(shí)現(xiàn)小車的停止?!巴V?quot;值改變事件程序框圖如下圖所示:


圖片


在“速度檔位"值改變事件中,通過讀取當(dāng)前選擇的速度檔位,向Arduino控制器分別發(fā)送0x55AA50、0x55AA60、0x55AA70、0x55AA80、0x55AA90,分別表示低速、中低速、中速、中高速和高速?!八俣葯n位"值改變事件的程序框圖如下圖所示:


圖片


*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。



關(guān)鍵詞: LabVIEW

相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉