搜尋程式碼

第27/31课:汽车-5 SunFounder智能车使用Arduino跟随你的手 | Robojax

第27/31课:汽车-5 SunFounder智能车使用Arduino跟随你的手 | Robojax

介紹

你有冇試過想整一部可以對你嘅存在作出直觀反應嘅機械人?呢個項目將一部標準嘅SunFounder智能車改造成一部跟住你隻手郁嘅手勢控制車。佢唔使用遙控器或者智能手機應用程式,而係結合超聲波同紅外線感應器嚟偵測你隻手嘅位置同距離,令你可以用簡單自然嘅動作嚟控制佢向左、向右或者向前行。

27-SunFounder-Car-5-Follow-Hand

呢個項目係Robojax Arduino課程(第27/31課)嘅一部分,並且使用SunFounder 3合1 Arduino套件嚟搭建。佢係一個好好嘅方法去學習感應器融合,即係多個感應器一齊運作嚟產生更複雜同更具反應性嘅行為。喺現實世界入面嘅價值在於理解點樣結合唔同類型嘅輸入嚟做決定,呢個係機械人同自動化嘅基本概念。

以下係一啲你可以用呢個邏輯嚟擴展嘅實際想法:

  • 互動展覽:整一個細型機械人展示裝置,跟住訪客嚟吸引佢哋嘅注意力。
  • 自主避障平台:修改程式碼,令部車可以喺房間入面導航,避開障礙物而唔係跟住隻手。
  • 教育機械人套件:用呢個作為基礎項目,教學生感應器整合、邏輯同摩打控制。
  • 智能送貨車:喺受控制嘅環境入面,呢個邏輯可以改編成一部細型送貨車,喺倉庫或者工廠入面跟住一個人行。

硬件同零件

呢個項目使用SunFounder 3合1 Arduino套件入面包含嘅零件。你會用到嘅核心零件包括:

  • SunFounder智能車底盤:有車輪同摩打嘅實體平台。
  • Arduino板:部車嘅「大腦」,負責執行程式碼。
  • 超聲波感應器(HC-SR04):用嚟量度部車前面物件(你隻手)嘅距離。
  • 兩個紅外線避障感應器:安裝喺左邊同右邊,用嚟偵測你隻手喺嗰兩邊嘅存在。
  • 摩打驅動器:一個模組(通常係L298N或者類似嘅),用嚟根據Arduino嘅訊號控制部車摩打嘅速度同方向。
  • 電源:電池,用嚟為Arduino同摩打供電。

接線指南

car_7_8_follow_hand

正如影片入面提到,呢個項目嘅接線同之前避障車課程入面解釋嘅係一樣。感應器同摩打全部都連接到Arduino嘅數碼同模擬引腳。如果想睇視覺參考,請參閱SunFounder智能車嘅接線圖。

程式碼定義咗每個零件使用嘅特定引腳,詳情會喺下一節講解。

程式碼解釋

呢一節會集中講解程式碼入面你可以自行調整嘅部分,方便你根據自己部車嚟修改。完整程式可以喺Robojax資源頁面下載。

喺程式最頂部,你會搵到引腳定義。如果你接線同導師唔同,呢啲就係最需要理解嘅關鍵行。

const int A_1B = 5;
const int A_1A = 6;
const int B_1B = 9;
const int B_1A = 10;

const int rightIR=7;
const int leftIR=8;

const int trigPin = 3;
const int echoPin = 4;

以下係每組引腳嘅作用:

  • 摩打引腳(A_1A、A_1B、B_1A、B_1B):呢啲係連接到摩打驅動器嚟控制兩個摩打嘅引腳。「A」同「B」標籤通常分別指左邊同右邊摩打。如果你嘅摩打驅動器連接到唔同嘅Arduino引腳,你一定要改呢啲設定。
  • 紅外線感應器引腳(rightIR、leftIR):呢啲數碼輸入引腳讀取左邊同右邊紅外線避障感應器嘅訊號。數值0代表偵測到障礙物(你隻手),而1代表路徑暢通。
  • 超聲波感應器引腳(trigPin、echoPin):trigPin係一個輸出,用嚟發送短暫嘅超聲波脈衝,而echoPin係一個輸入,用嚟讀取反射脈衝嘅持續時間嚟計算距離。

loop()函數入面,你會搵到主要行為邏輯。有一個變數你可能想調整:

int speed = 150;

呢個speed變數控制移動期間傳送到摩打嘅功率。佢可以喺0(停止)到255(最大速度)之間。你可以提高呢個數值(例如去到200)令部車快啲,或者降低佢(例如去到100)令移動更受控制、更慢。

程式碼仲包含好似moveForward()turnLeft()turnRight()嘅函數。呢啲函數用嚟控制部車嘅移動,並且會根據感應器讀數嚟被呼叫。你唔需要修改佢哋,但你可以將佢哋當作積木嚟建立自己嘅自訂行為。

「跟住你隻手」邏輯點樣運作

呢個項目嘅神奇之處在於Arduino點樣解讀三個感測器嘅數據。邏輯好直接,而且會喺loop()函數入面不斷執行。

首先,車仔會用超聲波感測器量度正前方物件嘅距離。然後,佢會檢查兩個紅外線感測器,睇吓左邊或者右邊有冇物件。決策過程如下:

  1. 向前行:如果超聲波感測器量度到嘅距離大過5厘米但細過10厘米,車仔就會向前行。咁就形成一個「最佳區域」,車仔會跟住你隻手行。
  2. 轉左:如果距離唔喺嗰個區域,車仔就會檢查紅外線感測器。如果左邊感測器被擋住(你隻手喺左邊)而右邊感測器暢通,車仔就會轉左。
  3. 轉右:相反,如果右邊感測器被擋住而左邊暢通,車仔就會轉右。
  4. 停低:如果以上條件都唔符合——例如你隻手太遠或者太近——車仔就會停低。

呢套簡單嘅規則令車仔可以動態咁對應你隻手嘅位置,創造出流暢同直觀嘅跟隨行為。

現場項目示範

喺影片示範入面,導師會即場展示車仔嘅行為。串流監視器用嚟顯示超聲波感測器讀到嘅距離。當車仔閒置而你隻手離得好遠(例如36厘米),佢會保持停低。當你將隻手放喺車仔前面5-10厘米嘅區域,佢就會開始向前行。

示範仲會突出轉向邏輯。當你將隻手放喺車仔左邊,左邊紅外線感測器就會觸發,車仔就會轉左。同樣,將隻手放喺右邊就會令車仔轉右。車仔會繼續跟住你隻手移動,只有當你隻手離開佢嘅感測範圍或者太近嗰陣先會停低。咁就確認咗感測器融合同邏輯運作正常,創造出一個反應靈敏同好玩嘅項目。

章節

  • [00:00] 跟手智能車簡介
  • [00:35] 關於Robojax Arduino課程同套件
  • [01:41] 項目概覽同程式碼設定
  • [02:19] 引腳定義同設定嘅解釋
  • [03:19] 跟住你隻手嘅程式碼邏輯
  • [05:48] 車仔實際運作嘅現場示範
  • [07:28] 最終示範同性能檢討

圖片

Car 7 8 follow hand
Car 7 8 follow hand
27 SunFounder Car 5 follow hand
27 SunFounder Car 5 follow hand
898-Lesson 27/31: Car-5 SunFounder Smart Car Follows Your Hand
語言: C++
/*
Lesson 27/31: Car-5 SunFounder Smart Car Follows Your Hand
Get this code and watch video Download and resource page https://robojax.com/RJT610
YouTube video https://www.youtube.com/watch?v=mcbJlE7-8ro

*/
const int A_1B = 5;
const int A_1A = 6;
const int B_1B = 9;
const int B_1A = 10;

const int rightIR=7;
const int leftIR=8;

const int trigPin = 3;
const int echoPin = 4;

void setup() {
  Serial.begin(9600);

  //motor
  pinMode(A_1B, OUTPUT);
  pinMode(A_1A, OUTPUT);
  pinMode(B_1B, OUTPUT);
  pinMode(B_1A, OUTPUT);

  //IR obstacle
  pinMode(leftIR,INPUT);
  pinMode(rightIR,INPUT);
  
  //ultrasonic
  pinMode(echoPin, INPUT);
  pinMode(trigPin, OUTPUT);
}

void loop() {

  float distance = readSensorData();

  int left = digitalRead(leftIR);  // 0: Obstructed   1: Empty
  int right = digitalRead(rightIR);
  int speed = 150;

  if (distance>5 && distance<10){
    moveForward(speed);
  }else if(!left&&right){
    turnLeft(speed);
  }else if(left&&!right){
    turnRight(speed);
  }else{
    stopMove();
  }
}

float readSensorData() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  float distance = pulseIn(echoPin, HIGH) / 58.00; //Equivalent to (340m/s*1us)/2
  return distance;
}

void moveForward(int speed) {
  analogWrite(A_1B, 0);
  analogWrite(A_1A, speed);
  analogWrite(B_1B, speed);
  analogWrite(B_1A, 0);
}

void moveBackward(int speed) {
  analogWrite(A_1B, speed);
  analogWrite(A_1A, 0);
  analogWrite(B_1B, 0);
  analogWrite(B_1A, speed);
}

void turnRight(int speed) {
  analogWrite(A_1B, speed);
  analogWrite(A_1A, 0);
  analogWrite(B_1B, speed);
  analogWrite(B_1A, 0);
}

void turnLeft(int speed) {
  analogWrite(A_1B, 0);
  analogWrite(A_1A, speed);
  analogWrite(B_1B, 0);
  analogWrite(B_1A, speed);
}

void stopMove() {
  analogWrite(A_1B, 0);
  analogWrite(A_1A, 0);
  analogWrite(B_1B, 0);
  analogWrite(B_1A, 0);
}

資源與參考資料

文件📁

Arduino 函式庫 (zip)