宜昌老张

具有避障和寻线功能的Arduino小车

0
阅读(12319)

     创客对于成年人来说,多半是科技娱乐,或者是一种是一种向往科技的人生态度,总是希望自己不仅可以看到或者听到科技的资讯,还希望能够亲身制作科技玩意,从而更好地体验科技。

    说到科技娱乐,也就是做东西,不需要什么指标,高兴即可,所以做些容易的,也是OK的。这次带来的作品又是Arduino与乐高结合的小车,小车具有简单的避障和寻线功能。

    避障传感器是夏普GP2Y0A21红外测距传感器,它是模拟量传感器,该传感器测距范围为10cm~80cm。Arduino模拟量信号的数据范围是0~1023,要对这个数据做一个距离值转换算法,才能得到小车与前方障碍物有多少cm。这个算法是“2547.8/((float)val*4*0.49-10.41)-0.42”,注意当障碍物在较远处,得到的距离值会是“负值”,所以要在程序中,要把这些的负值让它无效。

    寻线传感器是DFRobot公司的飞思卡尔Mini光电传感器,它可以帮助进行白线或者黑线的跟踪,可以检测白底中的黑线,也可以检测黑底中的白线。Mini寻线传感器红外探头输出经过门电路整形,以保证提供稳定的TTL输出信号,使寻线更准确更稳定。它的体积很小,可根据实际情况选择数量使用,并可灵活布局在智能车底面的任意位置。这个作品,我用了两个寻线传感器,由于数量不够,所以只能做简单的寻线工作。

     小车由两个型号为DF15SR的360度舵机驱动,舵机驱动的好处是它不需要专门的驱动板,直接连到DFrobot公司XBee传感器扩展板的数字端口即可,方便省心。

    这个作品的电源有两套,一套是5节充电电池组成,装在乐高Technic套件的电池盒中,给舵机供电,另一套是7.4V 900mAH的锂聚合物电池专门给Arduino逻辑部分供电,两套电源可以保证Arduino程序不受舵机电流的影响。

     看一下小车的底面图和细节图。

 

  


    Arduino电控与LEGO积木的结合,关键是如何把Arduino可控电机安装到乐高积木上?电机与乐高积木的配合有两个方面的安装工作,第一是电机输出轴与乐高积木的结合,第二是电机机身与乐高积木的结合,而且把两者上的乐高积木安装好后,积木之间的孔距最好是在X和Y轴两个方向上,都为乐高孔距的整数倍(乐高标准孔距为8mm),这样才能顺当地带动乐高齿轮传动链的运行。

    这个作品用的标准尺寸360度舵机是一种Arduino可控电机。舵机输出轴与乐高积木的结合,我是用舵机自带的圆盘连接器零件与乐高皮带轮零件用自攻螺钉固定在一起,对于舵机机身与乐高积木的结合就要专门根据舵机机身尺寸和安装孔位定制一个适配乐高积木的安装板。

    我的这个小车模型中使用的连接板是从美国货mindsensors公司网站通过Paypal支付,海淘回来的,这个标准舵机安装板名为:Hitec Standard Servo Mounting kit for NXT ,网址:http://www.mindsensors.com/index.php?module=pagemaster&PAGE_user_op=view_page&PAGE_id=117&MMN_position=41:41   

   现在淘宝上已经有这样类似的安装板,可以买到,大家不妨看看,

     http://item.taobao.com/item.htm?spm=a1z10.3.w17-588610910.11.1KxUMe&id=16193890181&

   对于Arduino可控的直流电机和步进电机有没有办法,不需自己加工,就可以通过云工厂购买的现成零件实现Arduino与LEGO的结合,答案是有的。可以购买MakeBlock的金属积木,因为MakeBlock套件里有常用规格的直流电机和步进电机,自然有安装这些电机的连接板,而MakeBlock金属积木又与乐高塑料积木是兼容,所以得到了MakeBlock的电机连接板就可以实现直流电机和步进电机与乐高积木的结合。只有解决了Arduino可控电机与乐高机械积木的结合,我们才能充分把乐高丰富的硬件资源和网络资讯为Arduino所用。


    下面的内容谈谈Arduino小车的避障和寻线程序设计。

    Arduino避障程序任务:接受GP2Y0A21红外测距传感器的采集数据,并把此数据转换为距离值。如果小车距离前方障碍物小于20cm,则机器人停止、后退、转弯,再前进,直到它又遇到障碍物,再重复执行避障动作。

#include <Servo.h> //申明舵机库文件
float distance_float;//存储由传感器读取值,通过算式处理后的浮点型距离值
int GP2D12 = 0;//把夏普GP2D12红外测距传感器连接在模拟量端口0
int val;   //存储从GP2D12红外测距传感器读到的采样值
Servo myservo1; //定义左舵机对象
Servo myservo2; //定义右舵机对象 
int power1 =93;   //定义变量,用于存储360度舵机功率值
int power2 =93; //360度舵机功率值范围为0~180,零速功率值为93
int randNumber;  //定义随机数变量
void setup() 
{ 
  myservo1.attach(7);  // 连接左舵机到Arduino数字端口7
  myservo2.attach(9); //连接右舵机到Arduino数字端口9
} 
void advance()//小车前进
{
    power1=180; 
    power2=0;
    myservo1.write(power1);             
    myservo2.write(power2);
}
void back()//小车后退
{
    power1=0;  
    power2=180;     
    myservo1.write(power1);            
    myservo2.write(power2); 
}
void left()//小车左转
{
    power1=93;  
    power2=0;     
    myservo1.write(power1);            
    myservo2.write(power2); 
}
void right()//小车右转
{
    power1=180;  
    power2=93;     
    myservo1.write(power1);            
    myservo2.write(power2); 
}
void Stop()//小车停止
{
    power1=93;  
    power2=93;     
    myservo1.write(power1);            
    myservo2.write(power2); 
}
void loop() {
  //GP2Y0A21红外测距传感器测距范围为10cm~80cm
  //读取GP2D12红外测距传感器模拟量数据
  val = analogRead(GP2D12); 
  //通过以下算式,把传感器读取值处理成浮点型距离值
   distance_float=2547.8/((float)val*0.49-10.41)-0.42;   
   //如果小车距离障碍物大于20cm,则小车前进,直到小于20cm
   //如果小车距离障碍物小于20cm,则小车后退,然后右转或者左转。
   //当小车距离障碍物大于80cm,或者更远处,红外传感器会计算得到“负”值。
   if (distance_float<=20 && distance_float>0)
     {
       Stop();  //小车停止0.2s
       delay(200);
       back();  //小车后退0.8s
       delay(800);
       randNumber = random(10);
       //小车随机向左或者向右转动,2s
       if(randNumber<5)
       {
         right(); //向右转动,2s
         delay(2000);
       }
       else
       {
         left(); //向左转动,2s
         delay(2000);
       }       
     } 
    else //否则
       advance();//小车前进
 }

    Arduino寻线程序任务:小车的两个驱动轮朝前,牛角万向轮在后,两个寻线传感器位于驱动轮之前,它们用来判断小车是否沿着黑线前行。寻线传感器检测到黑色输出低电平,检测到白色输出高电平。左右寻线传感器安装间距小于黑线的宽度。如果右寻线传感器脱离黑线,则小车左偏,以使右传感器回归黑线之间。如果左寻线传感器脱离黑线,则小车右偏,以使左传感器回归黑线之间。

#include <Servo.h> //申明舵机库文件
int IR_left=2;//定义左侧寻线传感器,连接它到Arduino数字端口2
int IR_right=4;//定义右侧寻线传感器,连接它到Arduino数字端口4
int Left,Right;
Servo myservo1; //定义左舵机对象
Servo myservo2; //定义右舵机对象 
int power1 =93;   //定义变量,用于存储360度舵机功率值
int power2 =93;  //360度舵机功率值范围为0~180,零速功率值为93
//初始化
void setup() 
{ 
  myservo1.attach(7);  // 连接左舵机到Arduino数字端口7
  myservo2.attach(9); //连接右舵机到Arduino数字端口9
  pinMode(IR_right,INPUT);
  pinMode(IR_left, INPUT);   
} 
void advance()//小车前进
{
    power1=180;  
    power2=0;     
    myservo1.write(power1);            
    myservo2.write(power2); 
}

void left()//小车左偏
{
    power1=93;  
    power2=0;     
    myservo1.write(power1);            
    myservo2.write(power2); 
}
void right()//小车右偏
{
    power1=180;  
    power2=93;     
    myservo1.write(power1);            
    myservo2.write(power2); 
}
void Stop()//小车停止
{
    power1=93;  
    power2=93;     
    myservo1.write(power1);            
    myservo2.write(power2); 
}
void loop() {  
   //读寻线传感器的信号
    Right=digitalRead(IR_right);
    Left=digitalRead(IR_left);    
    //如果右、左两个红外为低电平
    //说明小车没有偏离黑色跑道
    if(Right==LOW &&  Left==LOW)
    advance();//小车前进
    //如果右寻线为高电平,说明小车向右偏离跑道
    else if(Right==HIGH && Left==LOW )
    left();//小车左转
    //如果左寻线为高电平,说明小车向左偏离跑道
    else if(Right==LOW && Left==HIGH)
    right();//小车右转       
    else //如果左右寻线都偏离跑道,
    Stop();//小车停止
 }

      创客们在体验科技,做一些智能车模型,但真正的科技一定是跑在最前面。现实的电动车将来一定大行其道,就像正在崛起的Tesla(特斯拉)电动车。

      特斯拉电动汽车受到了众多明星大腕和投资者的追捧,而其生产商、被媒体称做汽车业“苹果”的特斯拉公司,带着硅谷的基因,以入侵者的姿态颠覆了传统汽车制造业,带给人们全新的驾驶理念。大家看看视频,了解正在发生的事,了解电动车,现代工厂以及工业机器人。


 视频网址:http://player.youku.com/player.php/sid/XNTQ2NDgyNTky/v.swf