找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 3765|回復(fù): 3
收起左側(cè)

基于Arduino UNO的智能自主避障小車(chē)和藍(lán)牙遙控小車(chē)制作 代碼與教程

[復(fù)制鏈接]
ID:1012298 發(fā)表于 2022-4-19 12:14 | 顯示全部樓層 |閱讀模式
Hello,大家好!今天我要給大家分享一下我近期制作的一個(gè)arduino的小項(xiàng)目----智能避障小車(chē)。之前在某站上無(wú)意間刷到某位博主制作的一款智能避障小車(chē),覺(jué)得很有意思,便打算自己也只做一個(gè)來(lái)玩玩,于是便寫(xiě)了一款我自己理解的避障小車(chē),在此基礎(chǔ)上,我還增加了藍(lán)牙遙控功能,二者可以相互切換,提高其趣味性。和其他的避障小車(chē)類(lèi)似,這款也是超聲波來(lái)進(jìn)行距離避障,代碼相對(duì)其他大神來(lái)說(shuō)顯得比較表層,但這也相對(duì)來(lái)說(shuō)顯得更加好理解一些,廢話不多說(shuō),看代碼。!

一、代碼

/*********************************/                  //調(diào)取藍(lán)牙模塊庫(kù),調(diào)取伺服電機(jī)庫(kù)

#include <SoftwareSerial.h>                          //調(diào)取庫(kù)函數(shù)
#include <Servo.h>                                   //聲明調(diào)用Servo.h庫(kù)
SoftwareSerial BT(A0, A1);                           //新建對(duì)象,接收腳為A0--TXD,發(fā)送腳為A1--RXD
Servo servo;                                         //創(chuàng)建一個(gè)舵機(jī)對(duì)象

/*********************************/                  //定義驅(qū)動(dòng)模塊串口及變量

int TrigPin = 2;                                     //發(fā)出超聲波
int EchoPin = 3;                                     //收到反射回來(lái)的超聲波                                                                                                   
int Input1 = 4;                                      //定義uno的pin5向Input1輸出
int Input2 = 5;                                      //定義uno的pin5向Input2輸出
int Input3 = 6;                                      //定義uno的pin5向Input3輸出
int Input4 = 7;                                      //定義uno的pin5向Input4輸出
int pos = 118;                                       //創(chuàng)建變量,存儲(chǔ)從模擬端口讀取的值
float cm;                                            //因?yàn)闇y(cè)得的距離是浮點(diǎn)型的,單位為cm
int xuan;                                            
int choice;                                          //小車(chē)功能選擇

/********************* ************/                 //控制函數(shù)部分

void stop()                                          //小車(chē)停止
{
   digitalWrite(Input1,LOW);                         //給低電平
   digitalWrite(Input2,LOW);                         //給低電平
   digitalWrite(Input3,LOW);                         //給低電平
   digitalWrite(Input4,LOW);                         //給低電平
   delay(50);  
}

void forward()                                       //小車(chē)前進(jìn)
{
   digitalWrite(Input1,HIGH);                        //給高電平
   digitalWrite(Input2,LOW);                         //給低電平
   digitalWrite(Input3,HIGH);                        //給高電平
   digitalWrite(Input4,LOW);                         //給低電平
   delay(50);
}

void backward()                                      //小車(chē)后退
{
   digitalWrite(Input1,LOW);                         //給低電平
   digitalWrite(Input2,HIGH);                        //給高電平
   digitalWrite(Input3,LOW);                         //給低電平
   digitalWrite(Input4,HIGH);                        //給高電平
   delay(50);  
}

void turnleft()                                      //小車(chē)左轉(zhuǎn)
{
   digitalWrite(Input1,HIGH);                        //給高電平
   digitalWrite(Input2,LOW);                         //給低電平
   digitalWrite(Input3,LOW);                         //給低電平
   digitalWrite(Input4,HIGH);                        //給高電平
   delay(50);  
}

void turnright()                                     //小車(chē)右轉(zhuǎn)
{
   digitalWrite(Input1,LOW);                         //給低電平
   digitalWrite(Input2,HIGH);                        //給高電平
   digitalWrite(Input3,HIGH);                        //給高電平
   digitalWrite(Input4,LOW);                         //給低電平
   delay(50);
}

void Left()                                          //舵機(jī)左轉(zhuǎn)
{
   while(pos < 180)
    {
      pos++;
      servo.write(pos);                              //寫(xiě)入舵機(jī)角度      
      delay(15);                                     //延時(shí)使舵機(jī)轉(zhuǎn)到相應(yīng)角度   
    }
}

void Right()                                         //舵機(jī)右轉(zhuǎn)
{
   while(pos > 60)
    {
      pos--;
      servo.write(pos);                                 
      delay(15);                                       
    }
}

void Ranging()                                       //測(cè)量距離
{
   digitalWrite(TrigPin, LOW);                       //低電平發(fā)一個(gè)短時(shí)間脈沖去TrigPin
   delayMicroseconds(2);                             //delayMicroseconds在更小的時(shí)間內(nèi)延時(shí)準(zhǔn)確,delayMicroseconds是毫秒級(jí)計(jì)時(shí)單位
   digitalWrite(TrigPin, HIGH);                      //通過(guò)這里控制超聲波的發(fā)射
   delayMicroseconds(10);                           
   digitalWrite(TrigPin, LOW);                       //通過(guò)這里控制停止超聲波的發(fā)射
   cm = pulseIn(EchoPin, HIGH) / 58.0;               //將回波時(shí)間換算成cm ,其中pulseIn(接收信號(hào)引腳,高低電平)函數(shù)用來(lái)接收反射回來(lái)的聲波
   cm = (int(cm * 100.0)) / 100.0;                   //保留兩位小數(shù)
   Serial.print("Distance:");
   Serial.print(cm);
   Serial.print("cm");
   Serial.println();
   //以上四句在串口監(jiān)視器中輸出
   delay(1000);
}

/****************************************************/

void setup()
{
   Serial.begin(9600);                               //與電腦串口相連,波特率為9600
   servo.attach(9);                                  //9號(hào)引腳輸出電機(jī)控制信號(hào),僅能使用PWM引腳
   pinMode(Input1, OUTPUT);                          //Input1引腳設(shè)置為輸出模式
   pinMode(Input2, OUTPUT);                          //Input2引腳設(shè)置為輸出模式
   pinMode(Input3, OUTPUT);                          //Input3引腳設(shè)置為輸出模式
   pinMode(Input4, OUTPUT);                          //Input4引腳設(shè)置為輸出模式
   pinMode(TrigPin, OUTPUT);                         //發(fā)出超聲波串口設(shè)置為輸出
   pinMode(EchoPin, INPUT);                          //接受超聲波接口設(shè)為輸入
   BT.begin(9600);                                   //設(shè)置波特率為9600
}

void loop()
{
  switch(choice)
    {
       case 'X' :                                    //選擇避障
         Ranging();                                  //測(cè)量距離
         if(cm > 10.0)                               //沒(méi)有碰到障礙物
           forward();
         else                                        //碰到障礙物
           {
             backward();                             //小車(chē)后退
             delay(200);                             //延時(shí)確定后退距離
             stop();                                 //小車(chē)停止
             Right();                                //舵機(jī)右轉(zhuǎn)
             Ranging();                              //測(cè)量距離
             servo.write(118);                       //舵機(jī)回中
             if(cm > 10.0)                           //如果右邊滿(mǎn)足條件
               {
                 turnright();                        //小車(chē)右轉(zhuǎn)
                 delay(200);                         //延時(shí)確定轉(zhuǎn)彎角度
               }
             else                                    //如果右邊不滿(mǎn)足
               {
                 Left();                             //舵機(jī)左轉(zhuǎn)
                 Ranging();                          //測(cè)量距離
                 servo.write(118);                   //舵機(jī)回中
                 turnleft();                         //小車(chē)左轉(zhuǎn)
                 delay(200);                         //延時(shí)確定轉(zhuǎn)彎角度
               }
           }
      case 'Y' :                                     //選擇遙控
        while(BT.available())                        //藍(lán)牙識(shí)別字符
          {
             xuan = BT.read();                       //藍(lán)牙讀取字符
             switch(xuan)
               {
                 case 'A' :                                
                   forward();                        //調(diào)取前進(jìn)函數(shù)
                 case 'B' :                                 
                   backward();                       //調(diào)取后退函數(shù)  
                 case 'C' :                                
                   turnleft();                       //調(diào)取左轉(zhuǎn)函數(shù)
                 case 'D' :                              
                   turnright();                      //調(diào)取右轉(zhuǎn)函數(shù)   
                 case 'E' :                                
                   stop();                           //調(diào)取停止函數(shù)
               }
          }   
    }
}
代碼看起來(lái)是不是很通俗易懂呢!!

接下來(lái)給你們介紹我理解的手機(jī)藍(lán)牙通訊和電腦串口通訊分別是(波特率):

BT.begin(9600);

Serial.begin(9600);

雖然說(shuō)二者的更深層次的含義由于學(xué)術(shù)不精,無(wú)法給出具體解釋?zhuān)?jīng)過(guò)實(shí)際檢測(cè)是正確的。

在代碼中涉及的伺服電機(jī)角度,是根據(jù)我所買(mǎi)的伺服電機(jī)結(jié)合制作時(shí)需要所測(cè)量和設(shè)定的角度,只具有參考性。各位可以根據(jù)自己買(mǎi)的伺服電機(jī)來(lái)進(jìn)行修改。

void Left()                                          //舵機(jī)左轉(zhuǎn)
{undefined
   while(pos < 180)
    {undefined
      pos++;
      servo.write(pos);                          //寫(xiě)入舵機(jī)角度      
      delay(15);                                     //延時(shí)使舵機(jī)轉(zhuǎn)到相應(yīng)角度   
    }
}

這部分控制舵機(jī)轉(zhuǎn)動(dòng)運(yùn)用while循環(huán)主要是為了能夠是舵機(jī)逐角度的變化,也可以直接用

servo.write(pos);

寫(xiě)入需要的角度,但這就會(huì)使得舵機(jī)在轉(zhuǎn)動(dòng)到所需要的角度所需時(shí)間會(huì)非常短,可能會(huì)對(duì)舵機(jī)有損耗(個(gè)人觀點(diǎn))。

二、所需材料

1.Arduino UNO板子

2.HC-SR04超聲波模塊

3.HC-06藍(lán)牙模塊

4.L298N電機(jī)驅(qū)動(dòng)板模塊

5.智能小車(chē)底盤(pán)

6.18650充電電池及電池倉(cāng)

7.杜邦線若干

以上這些材料我制作時(shí)所用到,都是可以在某1個(gè)寶上買(mǎi)到的。當(dāng)然對(duì)于小車(chē)底盤(pán),有能力的朋友,可以自己設(shè)計(jì)建模一款小車(chē)底盤(pán),然后通過(guò)3D打印機(jī)打印出來(lái)也是很好的。

手機(jī)端藍(lán)牙遙控器用的是‘手機(jī)藍(lán)牙調(diào)試器’,在應(yīng)用商店里就可以下載到。相對(duì)應(yīng)的A,B,C,D,E,X,Y在按鍵操作里編輯即可。



評(píng)分

參與人數(shù) 1黑幣 +90 收起 理由
admin + 90 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:1020048 發(fā)表于 2022-4-21 15:27 來(lái)自手機(jī) | 顯示全部樓層
樓主,還在嗎我那個(gè)藍(lán)牙模塊通過(guò)arduino的串口監(jiān)視器發(fā)送就有回應(yīng)。然后手機(jī)遙控就還是一點(diǎn)反應(yīng)都沒(méi)有。能看出這是什么問(wèn)題?
回復(fù)

使用道具 舉報(bào)

ID:1011222 發(fā)表于 2022-4-23 13:00 | 顯示全部樓層
編譯錯(cuò)誤
回復(fù)

使用道具 舉報(bào)

ID:995613 發(fā)表于 2024-6-28 22:27 | 顯示全部樓層
你好,有ad原理圖嘛
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表