Arduino智能小车设计(六)

111
0
2020年12月25日 09时04分
上回接寻迹功能后,这次来介绍超声波避障功能。

我们将超声波固定在舵机上,再通过对舵机的控制来实现超声波的转向。

超声波避障功能

 

示例代码

 

#include<Servo.h>
int inputPin = 8; // 定义超声波信号接收接口
int outputPin = 9; // 定义超声波信号发出接口

int STBY = 11; //控制电机驱动状态引脚

int PWMA = 3; //A电机速度控制
int AIN1 = 23; //A电机方向
int AIN2 = 22; 

int PWMB = 5; //与上述A做对应即可
int BIN1 = 25; 
int BIN2 = 24; 

Servo myservo;//定义舵机变量名
void setup()
{
  Serial.begin(9600);//设置串口波特率为9600
  myservo.attach(10);//定义舵机接口10 
  
  pinMode(inputPin, INPUT);
  pinMode(outputPin, OUTPUT);
  
  pinMode(STBY, OUTPUT);
  pinMode(PWMA, OUTPUT);
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);
  pinMode(PWMB, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
  myservo.write(90);  //初始化舵机方向
}

void loop()
{
  myservo.write(90);
  int distance=MTD();    //超声波测距
  if(distance<50)  //前方50cm处有障碍
  {
    move(1,0,1);      //小车停下
    move(2,0,1);
    delay(1000);
    myservo.write(0);  //舵机左转
    delay(500);
    int qdistance=MTD();   //测距
    if(qdistance<50)  // 左边50cm处有障碍
    {
        move(1,0,1);
        move(2,0,1);
      delay(1000);
      myservo.write(180);    //舵机右转
      delay(500);
      int qqdistance=MTD();     //测距
      if(qqdistance<20) //右边50cm处有障碍
      {
        move(1,0,1);
        move(2,0,1);
        move(1,128,1);      //左电机向前,右电机向后,以实现掉头这一过程
        move(2,128,0);
        delay(2000);        //延迟时间较长,以实现成功掉头
        move(1,0,1);
        move(2,0,1);
      }
      else     //右边50cm无障碍
      {
        delay(1000);
        move(1,100,1);    //左电机向前,右电机向后,以实现右转
        move(2,100,0);    
        delay(1000);       //延迟时间短,以实现右转
        move(1,0,1);
        move(2,0,1);
      }
    }
    else        //左边50cm处无障碍
    {
      delay(1000);         
      move(1,100,0);       //左电机向后,右电机向前,以实现左转
      move(2,100,1);
      delay(1000);
      move(1,0,1);
      move(2,0,1);
    }
  }
  else     //前方50cm处无障碍
  {
    move(1,128,1);
    move(2,128,1);
  }
 
  delay(500);//刷新时间500ms,也就是0.5s
}

int MTD(){                      //测距函数  可参考博客Arduino小车设计(三),里面有对此代码较为详细的说明
  digitalWrite(outputPin, LOW); // 使发出发出超声波信号接口低电平2ms
  delayMicroseconds(2);
  digitalWrite(outputPin, HIGH); // 使发出发出超声波信号接口高电平10ms,这里是至少10μs
  delayMicroseconds(10);
  digitalWrite(outputPin, LOW); // 保持发出超声波信号接口低电平
  int distance = pulseIn(inputPin, HIGH); // 读出脉冲时间
  distance = distance / 58; // 将脉冲时间转化为距离(单位:厘米)
  return distance;
}

void move(int motor, int speed, int direction){  //可参考博客Arduino小车设计(三),里面有对此代码较为详细的说明
  digitalWrite(STBY, HIGH); //disable standby
  
  boolean inPin1 = HIGH;

  boolean inPin2 = LOW;

  if(direction == 1){
    inPin1 = LOW;
    inPin2 = HIGH;
  }

  if(motor == 1){
    digitalWrite(AIN1, inPin1);
    digitalWrite(AIN2, inPin2);
    analogWrite(PWMA, speed);
  }
  else{
    digitalWrite(BIN1, inPin1);
    digitalWrite(BIN2, inPin2);
    analogWrite(PWMB, speed);
  }

}

 

示例代码也是根据所做的小车的具体情况,不断加以完善的。(找不到源码了,如果能做对照,真的会发现有很多不同的情况)。

虽说是完善后的,但是实际情况还是不能让人称心如意。

为什么这么说呢,如下图所示,博主做的是一个三蹦子==

 

1

 

小车是怎么控制方向的呢?是通过左右电机速度的不同来实现左右前后转动,而后面的小轮(白色)实际上起的是一个辅助左右,并没有相应的代码来控制。
如果没有实际操作过,你很难想象后面的小轮也有一定作用。

为什么这样说呢?如果一开始小车的功能是直走,而后面的小轮是朝右或朝左的,就很容易偏离方向。
你可能会说,如果一开始调整好了,那不就行了。但是在实际的操作过程中,如果发生了转弯的情况,小轮还是调整不过来,最后还是会导致小车的偏离。

我们也曾想过将速度调大的方法来让小轮强制转过来,可是只是一种想法。因为我们电池的电压实在有限(仅有6v),所以电机的速度最大也不是很给力。

下一个问题就是超声波的延迟问题,我们在测量当前方,左方和右方都有物体时,按照代码来说照理说应该掉头的。可是出现了几次正常流程,几次非正常的流程(即向右拐)。我们当时也比较疑惑,是不是延迟给的时间太少了。因为会不定时的出现,所以我们也没有根本的解决这个问题,我感觉这应该和超声波本身工作原理的延迟有关吧(猜的)。

超声波传感器是比较敏感的,前期设计时,杜邦线没有固定好,出现在超声波前方时,会让超声波测定前方有障碍物,所以一定要固定好杜邦线。

我的想法:

超声波避障整整做了一天。。。。。做着做着一天就没了,很多复杂的小问题,都是我们忽视的,导致小车并不是那么完美。一直不断不断的改善,才稍微像样。超声波避障给了我第一次在实例上的打击,也让我清楚地认识到,实践是检测一个事难度的最好方法,而不是靠想象。不要小瞧了任何东西,很多有成就的事都是有这些小东西组成的,你要尽全力完美地做好它。

发表评论

后才能评论