宜昌老张

Arduino控制下能躲开障碍物的慧鱼车

0
阅读(3169)

    我已经写了三篇  涉及慧鱼车的博文了。先看看吧。

 

一、《Arduino开发实战指南》与慧鱼遥控车

http://blog.chinaaet.com/detail/25929.html



 


二、任天堂Wii手柄遥控慧鱼车

http://blog.chinaaet.com/detail/25976.html



 

三、夏普GP2D12红外线测距传感器与LCD1602液晶

http://blog.chinaaet.com/detail/26124.html


   

     这篇《Arduino控制下能躲开障碍物的慧鱼车》博文中介绍的慧鱼车并不是被遥控的,而是有了自我思考的能力,它能够判断距离障碍物的远近,如果离障碍物太近,则会自动后退,再转弯,躲开障碍物,寻找其它出路。看视频。

    与被遥控的慧鱼车对比,自主型慧鱼车少了无线通信模块,增加了夏普GP2D12红外传感器和集成了I2C接口的LCD1602面板,红外传感器通过其支架与万向轮支座用螺钉螺母固连在一起,1602LCD面板用透明胶带粘在小车的前端。

  

能躲开障碍物的慧鱼车的程序如下:(有详细注释)

 

/*慧鱼智能车通过夏普GP2D12红外传感器测量与障碍物的距离
 
 
 
并把距离显示在LCD1602液晶面板上,
 
如果小车距离障碍物小于20cm,则小车后退,然后右转;
否则小车前行。*/
 // 声明集成了I2C接口的LCD1602编程所需库文件
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
int E_right =5; //连接小车电机1的使能端口到数字接口5
int M_right =4; //连接电机1的转向端口到数字接口4
int E_left =6;//连接小车电机2的使能端口到数字接口6
int M_left=7; //连接电机2的转向端口到数字接口7
float velocity=255;//车速调节
//设置LCD1602的I2C地址为0x27,LCD1602为两行,每行16个字符的液晶显示器
  LiquidCrystal_I2C lcd(0x27,16,2); 
  int GP2D12 = 0;//把夏普GP2D12红外测距传感器连接在模拟量端口0
  int val;   //存储从GP2D12红外测距传感器读到的值     
  float distance_float;//存储由传感器读取值,通过算式处理后的浮点型距离值
  int distance_int;//存储由传感器读取值,通过算式处理后的整数型距离值

//初始化程序        
void setup() {
  //给控制电机的数字接口设置输入输出状态  
   pinMode(M_right, OUTPUT);
   pinMode(E_right, OUTPUT);
   pinMode(M_left, OUTPUT);
   pinMode(E_left, OUTPUT);
  //LCD1602的I2C通讯初始化需要执行两次
  lcd.init(); // 给LCD的I2C通讯初始化
  delay(20);
  lcd.init(); // 给LCD的I2C通讯初始化
   delay(20);
   lcd.backlight();//点亮LCD1602背光灯   
}

void advance()//小车前进
{
     digitalWrite(M_right,HIGH);
     analogWrite(E_right,int(velocity));
     digitalWrite(M_left,HIGH);
     analogWrite(E_left,int(velocity));
}
void back()//小车后退
{
     digitalWrite(M_right,LOW);
     analogWrite(E_right,int(velocity));
     digitalWrite(M_left,LOW);
     analogWrite(E_left,int(velocity));
}
void left()//小车左转
{
     digitalWrite(M_right,HIGH);
     analogWrite(E_right,int(velocity));
     digitalWrite(M_left,HIGH);
     analogWrite(E_left,int(0));
}
void right()//小车右转
{
     digitalWrite(M_right,HIGH);
     analogWrite(E_right,int(0));
     digitalWrite(M_left,HIGH);
     analogWrite(E_left,int(velocity));
}
void Stop()//小车停止
{
     digitalWrite(E_right, LOW); //右电机停
     digitalWrite(E_left, LOW); //左电机停
}
void Display()//LCD显示子程序
{
  lcd.clear();//LCD清屏
  // 定位光标在LCD第0行、第0列
  lcd.setCursor(0, 0);
  //在LCD第0行第0列开始显示"Distance:"
  lcd.print("Distance:");
  // 定位光标在LCD第1行、第7列
  lcd.setCursor(7, 1);
  //如果传感器读取值大于80或者小于10,
  if(distance_float>80||distance_float<10)
        {
      //则在LCD第1行、第7列开始显示"OverRange"
         lcd.print("OverRange");
         //if(distance_float>80)
         //由于夏普GP2D12红外测距传感器有效测距范围是10~80cm
         //超过范围,所测距离与实际距离完全不符,
         //故针对蔽障小车实验,把范围以外的距离设置为80cm
         distance_float=80;
         //if(distance_float<10)
         //distance_float=1;      
    }
   //如果传感器读取值在10到80之间,
  else
        {        
        //把浮点型距离值取整
        distance_int=int(distance_float);
        //则在LCD第1行、第7列开始显示距离值
        lcd.print(distance_int);
        //在距离值后显示单位"cm"
        lcd.print("cm");
    } 
}

//主程序
void loop() {
  //读取GP2D12红外测距传感器模拟量数据
  val = analogRead(GP2D12); 
  //通过以下算式,把传感器读取值处理成浮点型距离值
   distance_float=2547.8/((float)val*0.49-10.41)-0.42;
   Display();//调用显示子程序
   //如果小车距离障碍物大于20cm,则小车前进,直到小于20cm
   if(distance_float>20)
   {  
       advance();
       //这个延时,是为了给LCD1602送显示数据的频率不致于太快
       //给LCD1602送显示数据的频率不致于太快,LCD1602显示不正常
        delay(200);
   }
  //如果小车距离障碍物小于20cm,则小车后退,然后右转
   if (distance_float<20)
     {
       back();
       delay(800);
       right();
       delay(1000);       
     }    
 }