概述

在这一课中,将会介绍如何用超声波模块和舵机实现坦克小车避障功能。

超声波原理

坦克小车上安装有一个超声波模块,该模块由两部分组成:超声波发射器和接收器。 超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时,通过时间差来算出超声波与障碍物之间的距离。

超声波模块是安装在SG90舵机旋转轴上的,SG90舵机可以旋转0-180,因此小车可以检测0-180范围内的障碍物,当小车检测到障碍物后,小车先停止运动,舵机旋转检测左右与障碍物距离,如果左边或右边无障碍物,小车将转向左边或右边,同时舵机回到90度位置(使超声波朝正前方);如果左右两边都有障碍物,且小车与障碍物距离在允许范围内,比较小车到左右障碍物的距离,小车转向距离大的一边运动;

软件

下载https://osoyoo.com/driver/tank_robot_lesson5.zip并解压文件,用arduino IDE打开tank_robot_lesson5.ino文件,下面对代码做简要说明。

#define SERVO     11  //servo connect to D11
#define IRPIN  13 //IR receiver Signal pin connect to Arduino pin 13
#define echo    A3 // Ultrasonic Echo pin connect to A2
#define trig    A2  // Ultrasonic Trig pin connect to A3
#define buzzer     7 //buzzer connect to D7

上面5行代码定义了舵机、红外接收器、超声波和蜂鸣器所接的GPIO口

int leftscanval, centerscanval, rightscanval, ldiagonalscanval, rdiagonalscanval;
const int distancelimit = 30; //distance limit for obstacles in front           
const int sidedistancelimit = 18; //minimum distance in cm to obstacles at both sides (the car will allow a shorter distance sideways)

定义几个变量用于存储各个方向距离以及小车与障碍物的极限距离。

/*detection of ultrasonic distance*/
int watch() {
  long howfar;
  digitalWrite(trig, LOW);
  delayMicroseconds(5);
  digitalWrite(trig, HIGH);
  delayMicroseconds(15);
  digitalWrite(trig, LOW);
  howfar = pulseIn(echo, HIGH);
  howfar = howfar * 0.01657; //how far away is the object in cm
  Serial.println((int)howfar);
  return round(howfar);
}

上面的watch()用于测量小车与障碍物之间的距离。

void auto_avoidance() {
  head.write(90); 
  delay(100);
  centerscanval = watch();
  if (centerscanval >= distancelimit) {
    set_motorspeed(LSPEED, RSPEED);
    go_ahead();
  }
  else {
    go_stop();
    alarm();
    head.write(120);
    delay(150);
    ldiagonalscanval = watch();

    head.write(180);
    delay(150);
    leftscanval = watch();

    head.write(90);
    delay(150);

    head.write(60);
    delay(150);
    rdiagonalscanval = watch();

    head.write(0);
    delay(150);
    rightscanval = watch();

    head.write(90);
    if (ldiagonalscanval >= sidedistancelimit && leftscanval >= sidedistancelimit) {
      set_motorspeed(LSPEED, RSPEED);
      go_back();
      delay(200);
      turn_left();
      delay(500);
    }
    else if (rdiagonalscanval >= sidedistancelimit && rightscanval >= sidedistancelimit) {
      set_motorspeed(LSPEED, RSPEED);
      go_back();
      delay(200);
      turn_right();
      delay(500);
    }
  }
}

在auto_avoidance()函数中转动舵机并调用watch()函数,就能检测左右及前方障碍物距离,通过测量距离与允许距离比较选择合理路径,实现超声波避障。

用usb线把坦克下车与pc连接起来,选择正确的板子型号和端口号,将程序烧录到arduino中,打开电池盒电源,将坦克小车放到地上上,遥控器对着红外接收头,按下”OK”键,小车将开始避障;按下”0″小车停止。若无法避障,请看考第一课参考第一课检查超声波及舵机安装时否正确并检查接线。