单片机学习小组
直播中

李玲

7年用户 1260经验值
私信 关注

怎么实现智能小车红外循迹的设计?

怎么实现智能小车红外循迹的设计?

回帖(1)

丘素莉

2022-1-18 10:49:03
Record:2021/5/12日学院举办的智能小车比赛落下帷幕,特地将比赛出现的问题和经历总结一下,以表纪念。
比赛要求蓝牙模板和超声波,测距,目标跟踪四个功能整合在一个程序上,另一项就是红外循迹加避障(不是绕碍,不过也不难)。
我先将记忆深刻的红外循迹避障程序记录下来:
首先直接上代码:

*  晶振:11.0592MHZ
  ZYWIFI0939WIFI控制智能机器人杜邦线接线方法,请一定照做,否则可能不工作,并烧毁小车。
  J3 接到实验板 P4                                           J4 接实验板 P7接口
   IN1--接到--实验板上的P1.2                       IN5--接到--实验板上的P2.1
   IN2--接到--实验板上的P1.3                       IN6--接到--实验板上的P2.0
   EN1--接到--实验板上的P1.4
   EN2--接到--实验板上的P1.5
   IN3--接到--实验板上的P1.6
   IN4--接到--实验板上的P1.7
   
   J5 接实验班P3接口
   OUT1--接到--实验板上的P3.2                          OUT3--接到--实验板上的P3.4
   OUT2--接到--实验板上的P3.3                                          OUT4--接到--实验板上的P3.5
   VCC-- 接到--实验班上的VCC                                          GND--接到--实验板上的GND
   
******************************************************************/
#ifndef _LED_H_
#define _LED_H_


    //定义小车驱动模块输入IO口
   ***it L293D_IN1=P1^2;
   ***it L293D_IN2=P1^3;
   ***it L293D_IN3=P1^4;
   ***it L293D_IN4=P1^5;
   ***it L293D_EN1=P1^6;
   ***it L293D_EN2=P1^7;
       

        /***蜂鸣器接线定义*****/
    ***it BUZZ=P2^3;

    #define Left_1_led        P3_7         //左传感器  
       
    #define Right_1_led       P3_6         //右传感器
       
        #define mid_1_led         P0^0   //中间循迹

        #define Left_2_led        P3_4         //左避障传感器  
       
    #define Right_2_led       P3_5         //右避障传感器   
   
        #define Left_moto_pwm          P1_6         //PWM信号端

        #define Right_moto_pwm          P1_7         //PWM信号端
       
        #define Left_moto_go      {P1_2=1,P1_3=0;}  //左电机向前走
        #define Left_moto_back    {P1_2=0,P1_3=1;}         //左边电机向后转
        #define Left_moto_Stop    {P1_2=0,P1_3=0;}         //左边电机停转                     
        #define Right_moto_go     {P1_4=1,P1_5=0;}        //右边电机向前走
        #define Right_moto_back   {P1_4=0,P1_5=1;}        //右边电机向后走
        #define Right_moto_Stop   {P1_4=0,P1_5=0;}              //右边电机停转   

        unsigned char pwm_val_left  =0;//变量定义
        unsigned char push_val_left =0;// 左电机占空比N/20
        unsigned char pwm_val_right =0;
        unsigned char push_val_right=0;// 右电机占空比N/20
        bit Right_moto_stop=1;
        bit Left_moto_stop =1;
        unsigned  int  time=0;
   
/************************************************************************/       
//延时函数       
   void delay(unsigned int k)
{   
     unsigned int x,y;
         for(x=0;x            for(y=0;y<200;y++);
}
/************************************************************************/
//前速前进
     void  run(void)
{
     push_val_left=20;         //速度调节变量 0-20。。。0最小,20最大
         push_val_right=20;
         Left_moto_go ;   //左电机往前走
         Right_moto_go ;  //右电机往前走
}

//后退函数
     void  backrun(void)
{
     push_val_left=12;         //速度调节变量 0-20。。。0最小,20最大
         push_val_right=12;
         Left_moto_back;   //左电机往后走
         Right_moto_back;  //右电机往后走
}

//左转
     void  leftrun(void)
{         
     push_val_left=14;
         push_val_right=20;
         Right_moto_go ;  //右电机往前走
     Left_moto_go   ;  //左电机后走
}
      //急左转
     void  moreleft(void)
{         
     push_val_left=15;
         push_val_right=15;
         Right_moto_go ;  //右电机往前走
     Left_moto_back   ;  //左电机后走
}

//右转
     void  rightrun(void)
{
         push_val_left=20;
         push_val_right=14;
     Left_moto_go  ;   //左电机往前走
         Right_moto_go    ;  //右电机往后走       
}
//急右转
     void  moreright(void)
{
         push_val_left=16;
         push_val_right=16;
     Left_moto_go  ;   //左电机往前走
         Right_moto_back    ;  //右电机往后走       
}

//停止
     void  stop(void)
{         
     
         Right_moto_Stop ;  //右电机停止
     Left_moto_Stop  ;  //左电机停止
}

/************************************************************************/
/*                    PWM调制电机转速                                   */
/************************************************************************/
/*                    左电机调速                                        */
/*调节push_val_left的值改变电机转速,占空比            */
                void pwm_out_left_moto(void)
{  
   if(Left_moto_stop)
   {
    if(pwm_val_left<=push_val_left)
               {
                     Left_moto_pwm=1;
//                     Left_moto_pwm1=1;
                   }
        else
               {
                 Left_moto_pwm=0;
//                     Left_moto_pwm1=0;
                   }
        if(pwm_val_left>=20)
               pwm_val_left=0;
   }
   else   
          {
           Left_moto_pwm=0;
//           Left_moto_pwm1=0;
                  }
}
/******************************************************************/
/*                    右电机调速                                  */  
   void pwm_out_right_moto(void)
{
  if(Right_moto_stop)
   {
    if(pwm_val_right<=push_val_right)
              {
               Right_moto_pwm=1;
//                   Right_moto_pwm1=1;
                   }
        else
              {
                   Right_moto_pwm=0;
//                   Right_moto_pwm1=0;
                  }
        if(pwm_val_right>=20)
               pwm_val_right=0;
   }
   else   
          {
           Right_moto_pwm=0;
//           Right_moto_pwm1=0;
              }
}
      
/***************************************************/
///*TIMER0中断服务子函数产生PWM信号*/
        void timer0()interrupt 1   using 2
{
     TH0=0XFc;          //1Ms定时
         TL0=0X18;
         time++;
         pwm_val_left++;
         pwm_val_right++;
         pwm_out_left_moto();
         pwm_out_right_moto();
}       

/*********************************************************************/       

#endif
        #include                  //包含51单片机头文件,内部有各种寄存器定义
        #include                  //包含HL-1蓝牙智能小车驱动IO口定义等函数
     
//主函数
        void main(void)
{       

        unsigned char i;
        unsigned char flag; //  标记点
    P1=0X00;   //关电机       

                         TMOD=0X01;
                TH0= 0XFc;                  //1ms定时
                 TL0= 0X18;
                   TR0= 1;
                ET0= 1;
                EA = 1;                           //开总中断


        while(1)        //无限循环
        {
                            if(Left_2_led==0 || Right_2_led==0) //遇到障碍物

                         {         
     
                             backrun();
                                         delay(1);
                                         stop();
              }
         
                         //有信号为0  没有信号为1
                                   if(Left_1_led==1&&mid_1_led==1&&Right_1_led==1)//亮的时候为0,1才检测到黑线
                           {                                                         
                                      run();
                           }
            
                                              
                          if(Left_1_led==1&&mid_1_led==1&&Right_1_led==0)          
                                  {
                                           leftrun();
                                          flag=0;
                                          delay(1);                  
                                       
                             }
                         
                          if(Left_1_led==0&&mid_1_led==1&&Right_1_led==1)               
                                  {          
                                      rightrun();
                                          flag=1;                  
                                          delay(1);       
                                  }
                          
                         
                          if(Right_1_led==1&&Left_1_led==1)               
                                  {          
                                      run();                  
                                  }
                        if(Left_1_led==0&&mid_1_led==0&&Right_1_led==0)//亮的时候为0,1才检测到黑线
                           {                                                         //跑出赛道
                             if(flag==1)
                                 {                                                //右急转
                                   moreright();
                                 }
                                   if(flag==0)
                                 {                                                //左急转
                                   moreleft();
                                 }   
                           }

         }
}
我们在基础的代码上进行的修改,让它的速度尽量发挥到极致,这个小车在淘宝上买的,大概两百多,感兴趣的话可以买一辆挺好玩的。
根据小车传感器原理图我们可以知道P3.6,P3.7,P0.0为三个红外循迹传感器,P3.4,P3.5为左右避障传感器大家要根据原理图进行更改,需要原理图的可以私聊我,在调试小车时,就因为没有认真看原理图在代码编写的时候一直出问题,还有一定一定一定要将代码放在准确的文件夹里,我好多次就是改代码改了一下午没找到错误,后来才发现代码写到另一个备份的文件夹里,白白浪费一个下午的时间。
代码部分,我们在原代码的基础上增加了flag函数,这是为了在速度极高的情况之下,小车就有跑出赛道的可能却依然能跑回赛道(这也就意味着没检测到黑线小车就会跑了)。正是这个flag函数的存在使得可以将小车的硬件发挥到极致,所以我们把PWM调速调到最高小车也不会跑离赛道太多(会有一丢丢的跑出去),避障的话我加了一个后退的函数,避免速度太快直接撞上。至少电机反转减速倒退然后保持一定距离。
下面就是测试哪个速度能将跑出最快的成绩了,我们用黑色胶带在宿舍自己搞了一个赛道然后测试时间:


最左边是前进速度左右电机都为20,左右电机在转向的时候都是向前走,依靠两边的速度差进行转向(测试过一边电机向后一边向前转,不过速度不太理想);后面最好速度为一圈11.3秒,可能存在一些偶然误差,不过这确实是比较理想的数据了。
然后静静等待比赛结果了,不管怎样这五天和同学一起研究挺开心的,不论结果如何不断冲刺吧!
举报

更多回帖

发帖
×
20
完善资料,
赚取积分