超声波“摇头”避障,左右两路红外线感..-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 8249|回复: 2

超声波“摇头”避障,左右两路红外线感..

[复制链接]
发表于 2017-8-1 12:25 | 显示全部楼层 |阅读模式
能够通过超声波“摇头”避障,并且能用左右两路红外线感应处理“突发障碍”的智能小车

很多朋友制作了超声波避障智能小车,有的带有舵机的“摇头”功能,有的没有。不过可惜超声波测量平面物体相对比较准确,对于细长形的物体,经常无法形成有效的反射,因此测量不到,使得智能小车容易“卡”在桌子、凳子脚下或其他障碍物下面。
又由于超声波一般装在车头,对于左右两侧出现的“障碍”无法处理。所以我在小车底盘左右两侧加装了红外线感应,基本达到小车在房间了到处走,不会“卡死”的效果,也能够及时处理突然在车身左右出现的障碍物,行走时速度快,比较灵活。

本人使用某国内厂家的小车底盘,他们自己生产的HJduino控制板,拓展板(兼容Arduino),红外感测器,通用的超声波。我不是厂家的人,没必要在这里给他做广告,只是本人穷,在两百多块左右的价位选择这个厂家的东西还是比较合适的。

红外感应器的感测距离我自己可以调到6cm至7cm左右,但是这仪器“怕太阳光”。即使没有直接被阳光直射到,白天在室内也可能被太阳辐射热影响到红外信号,小车失灵。一般是晚上八点之后,小车的红外感应比较灵敏、准确。

从理论上说,在小车上多装几个超声波或者红外线是没有问题的。
我也计划过买一台小孩开的玩具车(可以坐人的那种)来改装成“自动行驶”避障车,但是由于时间、精力、财力等问题,目前实现不了。希望有朋友可以做出来。

个人拍的一些视频已经上传到优酷,有兴趣的朋友可以去看看。
智能小车超声波找出路2—在线播放—优酷网,视频高清在线观看  http://v.youku.com/v_show/id_XMjkzNzQzMjE5Mg==.html?spm=a2h3j.8428770.3416059.1
智能小车超声波避障1—在线播放—优酷网,视频高清在线观看  http://v.youku.com/v_show/id_XMjkzNzQyODc1Mg==.html?spm=a2h3j.8428770.3416059.1
智能小车超声波找出路3—在线播放—优酷网,视频高清在线观看  http://v.youku.com/v_show/id_XMjkzNzQzMjU2OA==.html?spm=a2h3j.8428770.3416059.1
智能小车从角落里出来—在线播放—优酷网,视频高清在线观看  http://v.youku.com/v_show/id_XMjkzNzQzMjUyOA==.html?spm=a2h3j.8428770.3416059.1
智能小车自主走出角落—在线播放—优酷网,视频高清在线观看  http://v.youku.com/v_show/id_XMjkzNzQyODc5Mg==.html?spm=a2h3j.8428770.3416059.1
智能小车超声波舵机避障4—在线播放—优酷网,视频高清在线观看  http://v.youku.com/v_show/id_XMjkzNzQzMTU2MA==.html?spm=a2h3j.8428770.3416059.1
智能小车超声波舵机避障3—在线播放—优酷网,视频高清在线观看  http://v.youku.com/v_show/id_XMjkzNzQzMTU1Mg==.html?spm=a2h3j.8428770.3416059.1
视频管理-全部视频  http://vm.tudou.com/video/list
视频管理-全部视频  http://vm.tudou.com/video/list
我的自频道-优酷视频  
优酷用户1475903255365918
http://i.youku.com/i/UNTg2NjM1Njk2?spm=a2hww.20023042.uerCenter.5~5!2~A

我拍视频时是用手机随便拍的,没有分清是“1路”避障还是“3路”避障。个人感觉3路避障灵活些,不过我做的1路避障效果也还可以。

以下是源代码:

//ARDUINO 超声波(舵机)加红外线智能避障小车      L = 左   R = 右    F = 前    B = 后

#include <Servo.h>
int pinLB=14;     
int pinLF=15;     
int pinRB=17;   
int pinRF=16;   

int MotorRPWM=3;
int MotorLPWM=5;

int inputPin = 9;  // 超声波接收管脚号
int outputPin =8;  // 超声波发射管脚号

const int SensorLeft = 12;      //左红外传感器管脚号
const int SensorRight = 13;     //右红外传感器管脚号
int SL;    //左
int SR;    //右

int Fspeedd = 0;      // 前进速度
int Rspeedd = 0;      // 右转速度
int Lspeedd = 0;      // 左转速度
int directionn = 0;   //方向
Servo myservo;        // 设 myservo
int delay_time = 250; // 舵机转向后稳定的时间

int Fgo = 1;         // 前进
int Rgo = 5;         // 右转
int Lgo = 3;         // 左转
int Bgo = 7;         // 后退

void setup()
{
  Serial.begin(9600);     //波特率
  pinMode(pinLB,OUTPUT);   //电机
  pinMode(pinLF,OUTPUT);
  pinMode(pinRB,OUTPUT);  
  pinMode(pinRF,OUTPUT);  
  pinMode(MotorLPWM,  OUTPUT); //PWM
  pinMode(MotorRPWM,  OUTPUT);

  pinMode(inputPin, INPUT);    // 超声波接收
  pinMode(outputPin, OUTPUT);  //超声波发射

  pinMode(SensorLeft, INPUT); //定义左红外传感器
  pinMode(SensorRight, INPUT); //定义右红外传感器

  myservo.attach(10);    // 舵机
}
void advance(int a)     // 前进
    {
     digitalWrite(pinRF,HIGH);  
     digitalWrite(pinRB,LOW);
     analogWrite(MotorRPWM,150);
     digitalWrite(pinLF,HIGH);  
     digitalWrite(pinLB,LOW);
     analogWrite(MotorLPWM,150);
     delay(a * 100);     
    }
void right(int b)        //单轮
    {
     digitalWrite(pinRB,LOW);   
     digitalWrite(pinRF,HIGH);
     analogWrite(MotorRPWM,200);
     digitalWrite(pinLB,LOW);
     digitalWrite(pinLF,LOW);
     delay(b * 100);
    }
void left(int c)         //单轮
    {
     digitalWrite(pinRB,LOW);
     digitalWrite(pinRF,LOW);
     digitalWrite(pinLB,LOW);   
     digitalWrite(pinLF,HIGH);
     analogWrite(MotorLPWM,200);
     delay(c * 100);
    }
void turnR(int d)        //双轮右转
    {
     digitalWrite(pinRB,HIGH);  
     digitalWrite(pinRF,LOW);
     analogWrite(MotorRPWM,150);
     digitalWrite(pinLB,LOW);
     digitalWrite(pinLF,HIGH);  
     analogWrite(MotorLPWM,150);
     delay(d * 100);
    }
void turnL(int e)        //双轮左转
    {
     digitalWrite(pinRB,LOW);
     digitalWrite(pinRF,HIGH);   
     analogWrite(MotorRPWM,150);
     digitalWrite(pinLB,HIGH);   
     digitalWrite(pinLF,LOW);
     analogWrite(MotorLPWM,150);
     delay(e * 100);
    }   
void stopp(int f)         //停止
    {
     digitalWrite(pinRB,LOW);
     digitalWrite(pinRF,LOW);
     digitalWrite(pinLB,LOW);
     digitalWrite(pinLF,LOW);
     delay(f * 100);
    }
void back(int g)          //后退
    {
     digitalWrite(pinRF,LOW);  
     digitalWrite(pinRB,HIGH);
     analogWrite(MotorRPWM,150);
     digitalWrite(pinLF,LOW);  
     digitalWrite(pinLB,HIGH);
     analogWrite(MotorLPWM,150);
     delay(g * 100);     
    }

void detection()        //测量3个方向
    {      
      int delay_time = 200;   // 舵机转向后稳定的时间
      ask_pin_F();            // 读取前方距离

      if(Fspeedd < 30)         // 假如前方距离小于30厘米
      {
        stopp(5);               
        ask_pin_L();            // 读取左边距离
        delay(delay_time);      // 等待舵机稳定
        ask_pin_R();            // 读取右边距离  
        delay(delay_time);      // 等待舵机稳定

        if(Lspeedd > Rspeedd)   //假如左边距离大于右边距离
        {
         directionn = Lgo;      //向左走
        }

        if(Lspeedd <=Rspeedd)   //假如 左边距离小于或等于右边距离
        {
         directionn = Rgo;      //向右走
        }

        if (Lspeedd < 15&& Rspeedd < 15)   //假如左边距离和右边距离均小于15厘米
        {
         directionn = Bgo;      //后退        
        }         
      }
      else                      //假如前方距离不小于30厘米   
      {
        directionn = Fgo;        //前进     
      }            
    }   
void ask_pin_F()   // 测量前方距离
    {
      myservo.write(90);
      digitalWrite(outputPin,LOW);   // 超声波发射低电平2μs
      delayMicroseconds(2);
      digitalWrite(outputPin,HIGH);  // 超声波发射高电平10μs
      delayMicroseconds(10);
      digitalWrite(outputPin,LOW);    // 维持超声波发射低电平
      float Fdistance =pulseIn(inputPin, HIGH);  //读取相差时间
      Fdistance=Fdistance/5.8/10;       //将时间转化为距离(单位:厘米)
      Fspeedd = Fdistance;              // 将距离输入前进速度
    }
void ask_pin_L()   // 测量左边距离
    {
      myservo.write(5);
      delay(delay_time);
      digitalWrite(outputPin,LOW);   
      delayMicroseconds(2);
      digitalWrite(outputPin,HIGH);  
      delayMicroseconds(10);
      digitalWrite(outputPin,LOW);   
      float Ldistance =pulseIn(inputPin, HIGH);  
      Ldistance=Ldistance/5.8/10;      
      Lspeedd = Ldistance;              // 将距离输入左转速度
    }
void ask_pin_R()   // 测量右边距离
    {
      myservo.write(177);
      delay(delay_time);
      digitalWrite(outputPin,LOW);  
      delayMicroseconds(2);
      digitalWrite(outputPin,HIGH);  
      delayMicroseconds(10);
      digitalWrite(outputPin,LOW);   
      float Rdistance =pulseIn(inputPin, HIGH);  
      Rdistance=Rdistance/5.8/10;      
      Rspeedd = Rdistance;              // 将距离输入右转速度
    }

void loop()
{
    myservo.write(90);  //让舵机回到预备位置,准备下一次的测量
    detection();        //测量角度,并且判断向哪边移动

      SL = digitalRead(SensorLeft);
      SR = digitalRead(SensorRight);

   if(directionn == 7)  //假如方向 = 7  后退           
   {
     back(8);                    
     turnL(2);                   //稍微左转,防止卡死
   }
   if(directionn == 5)           //假如方向 = 5    右转   
   {
     back(4);
     turnR(6);                  
   }
   if(directionn == 3)          //假如方向 = 3   左转   
   {
     back(4);      
     turnL(6);                  
   }
   if(directionn == 1)          //假如方向= 1   前进      
   {
    advance(1);  
     if (SL == HIGH & SR ==LOW)  // 如果右边红外线感测到物体,单轮向左
        {  
          left(6);
        }
   else if (SR == HIGH & SL ==LOW) // 如果左边红外线感应到物体,向右
        {  
          right(6);      
        }   
   else if (SR == LOW & SL == LOW)//  如果两个红外线均感应到物体,后退
        {  
          back(4);         
        }   
   }
}



发表于 2019-5-10 12:50 | 显示全部楼层
有问题想问您
发表于 2019-8-30 13:05 | 显示全部楼层
厉害厉害,顶!!!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 11:44 , Processed in 0.074771 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表