2016年9月18日 星期日

[MeArm.Rover] 避障車(一)

避障車是利用發射超音波開始計時,到超音波碰觸物體後反射,接收器接到訊號為止,經由計算這段時間的多寡來推算距離。


一、準備材料

我們在上一回做過 MeArm.Rover 循跡車( http://pizgchen.blogspot.tw/2016/09/mearmrover_16.html )之後,不必拆卸任何零件,只要加裝一片超音波固定板,就可以實現避障車的功能。

機構件

超音波固定板 * 1
M3x10 螺絲 * 1
M3 螺帽 * 1


建議您可以把壓克力表面的保護紙撕除。另外,從超音波固定板剝除的那兩個圓圈(圖片上方)不要丟掉,您可以拿來當墊片使用。


機電零件

HC-SR04 超音波模塊 * 1


杜邦線 母母頭 * 4



二、開始組裝

Step1 將 HC-SR04 超音波模塊插入固定板的洞。超音波模塊的 pin 腳朝上或朝下您可以自行決定。



Step2 將上述組件固定到車體底板。




三、電路接線

Arduino         HC-SR04
5V                 VCC
GND             GND
D12               Trig
D13               Echo


四、程式碼

我們先來了解一下如何用超音波測量距離。超音波感測器有 2 種,一種是發射和接收同體,也就是該裝置同時具有發射和接收功能,在外觀上您只能看到 1 個圓柱形的金屬;另一種就像 HC-SR04 這樣,發射和接收是分開的,在外觀上您可以看到 2 個圓柱形的金屬。

在 Arduino IDE 裡有內建範例,您可以將它開啟並瀏覽一下程式碼

下拉功能表 File > Examples > 06.Sensors > Ping


您可以發現該程式碼只使用一個 pin 同時作為發射與接收,可見這個程式不適合我們使用。

所以,我將它修改如下,請您將它 Upload 到 Arduino 裡,開啟 Serial Monitor,將 Serial Monitor 下方的 baud 設為 9600,就可以看到量測的距離。

const int TrigPin = 12;
const int EchoPin = 13;

void setup() {
  Serial.begin(9600);
  pinMode(TrigPin, OUTPUT);
  pinMode(EchoPin, INPUT);
}

void loop() {
  long duration, inches, cm;

  digitalWrite(TrigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(TrigPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(TrigPin, LOW);

  duration = pulseIn(EchoPin, HIGH);
  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);

  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();

  delay(500);
}

long microsecondsToInches(long microseconds) {
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds) {
  return microseconds / 29 / 2;
}


這個模組號稱偵測的距離可以達4公尺,不過最大偵測距離建議還是應以實測為準。至於程式中如何將感測的時間算成距離,您可以參考 Cooper Maa 的文章。

在我們學會使用 HC-SR04 量測距離之後,就可以來做避障功能了,請您將下方的程式 Upload 到 Arduino 裡。

const int motor_RB = 5;
const int motor_RF = 6;
const int motor_LB = 9;
const int motor_LF = 10;
const int TrigPin = 12;
const int EchoPin = 13;
int intFast, intLow;

void setup() {
  Serial.begin(9600);
  pinMode(motor_RB, OUTPUT);
  pinMode(motor_RF, OUTPUT);
  pinMode(motor_LB, OUTPUT);
  pinMode(motor_LF, OUTPUT);
  pinMode(TrigPin, OUTPUT);
  pinMode(EchoPin, INPUT);
  intFast = 255;
  intLow = 130;
}

void loop() {
  long duration, inches, cm;

  digitalWrite(TrigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(TrigPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(TrigPin, LOW);

  duration = pulseIn(EchoPin, HIGH);
  cm = microsecondsToCentimeters(duration);
  /*
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  */
  if (cm > 10)
    Forward(intFast);
  else {
    Backward(intLow, 1000);
    Right(intLow, 500);
  }
  delay(50);
}

void Forward(int v) {
  analogWrite(motor_RF, v);
  analogWrite(motor_RB, 0);
  analogWrite(motor_LF, v);
  analogWrite(motor_LB, 0);
}

void Backward(int v, int ms) {
  analogWrite(motor_RF, 0);
  analogWrite(motor_RB, v);
  analogWrite(motor_LF, 0);
  analogWrite(motor_LB, v);
  delay(ms);
}

void Right(int v, int ms) {
  analogWrite(motor_RF, 0);
  analogWrite(motor_RB, v);
  analogWrite(motor_LF, v);
  analogWrite(motor_LB, 0);
  delay(ms);
}

void Left(int v, int ms) {
  analogWrite(motor_RF, v);
  analogWrite(motor_RB, 0);
  analogWrite(motor_LF, 0);
  analogWrite(motor_LB, v);
  delay(ms);
}

long microsecondsToCentimeters(long microseconds) {
  return microseconds / 29 / 2;
}

這裡只做簡單的判斷,所以在避障功能方面不是非常精確,如要達到更精準的避障功能,需要有更多、更精確的感測器,例如影像辨識。最重要的還是演算法,這是我們未來努力的目標。


技術資料

Cooper Maa http://coopermaa2nd.blogspot.tw/2012/09/hc-sr04.html
避障車 http://www.shs.edu.tw/works/essay/2014/03/2014031221512216.pdf


採購資訊

HC-SR04 超音波模塊 http://goods.ruten.com.tw/item/show?21628077202119




沒有留言:

張貼留言