搜索
bottom↓
回复: 17

2013年江西省自选赛A题:智跑机器车,想用作毕业设计,

[复制链接]

出0入0汤圆

发表于 2014-8-20 19:36:11 | 显示全部楼层 |阅读模式
http://www.tudou.com/programs/view/mWH46E_M6vE/



小车实现转弯的时候不是很明白,用到的传感器有颜色传感器,红外探测,和漫反射避障,大神们指导下小车转弯是如何实现的,是直接控制小车的转速?

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2014-8-20 20:27:39 | 显示全部楼层
这不正是我那三个好基友的作品吗

出0入0汤圆

 楼主| 发表于 2014-8-20 20:35:49 | 显示全部楼层
tianheiGE 发表于 2014-8-20 20:27
这不正是我那三个好基友的作品吗

你是新余学院的?你认识肖峰?

出0入0汤圆

发表于 2014-8-20 20:40:53 | 显示全部楼层
左右轮是分别驱动的,原理参考轮椅

出0入0汤圆

发表于 2014-8-20 20:41:20 | 显示全部楼层
两个轮子转速不一样就转弯咯。左转则右轮加速(或者左轮减速),反之右转

出0入0汤圆

发表于 2014-8-20 20:44:04 | 显示全部楼层
好,支持      

出0入0汤圆

 楼主| 发表于 2014-8-20 20:55:39 | 显示全部楼层
xsh2005105326 发表于 2014-8-20 20:41
两个轮子转速不一样就转弯咯。左转则右轮加速(或者左轮减速),反之右转 ...

通过PWM控制速度么?PWM不是很懂,

出0入0汤圆

 楼主| 发表于 2014-8-20 20:55:58 | 显示全部楼层

出0入0汤圆

 楼主| 发表于 2014-8-20 20:57:03 | 显示全部楼层
jingshi_yun 发表于 2014-8-20 20:40
左右轮是分别驱动的,原理参考轮椅

原理知道,但是不知道怎么控制,PWM么?

出0入0汤圆

发表于 2014-8-20 21:13:37 | 显示全部楼层
搁浅的风度 发表于 2014-8-20 20:57
原理知道,但是不知道怎么控制,PWM么?

这种应用,步进电机比较合适

出0入0汤圆

 楼主| 发表于 2014-8-20 21:40:34 | 显示全部楼层
jingshi_yun 发表于 2014-8-20 21:13
这种应用,步进电机比较合适

步进电机是调频,直流电机可以调幅。

出0入0汤圆

发表于 2014-8-20 21:44:38 | 显示全部楼层
搁浅的风度 发表于 2014-8-20 20:55
通过PWM控制速度么?PWM不是很懂,

最简单就是开关量控制,一个电机停,一个电机转,就是转弯咯

出0入0汤圆

发表于 2014-8-20 21:45:15 | 显示全部楼层
搁浅的风度 发表于 2014-8-20 20:35
你是新余学院的?你认识肖峰?

我们多是同班同学

出0入0汤圆

 楼主| 发表于 2014-8-20 22:02:36 | 显示全部楼层
tianheiGE 发表于 2014-8-20 21:45
我们多是同班同学

好吧,这么巧,他是我同学的同学

出0入0汤圆

 楼主| 发表于 2014-8-20 22:04:34 | 显示全部楼层
xsh2005105326 发表于 2014-8-20 21:44
最简单就是开关量控制,一个电机停,一个电机转,就是转弯咯

额,这个.....是比较简单,我看过别人的程序是可以控制左轮或右轮转过一个角度,不知道是怎么实现的

出0入0汤圆

发表于 2014-8-20 22:32:08 | 显示全部楼层
搁浅的风度 发表于 2014-8-20 22:04
额,这个.....是比较简单,我看过别人的程序是可以控制左轮或右轮转过一个角度,不知道是怎么实现的 ...

一种是步进电机,脉冲数决定转过角度;还有一种是普通电机+码盘,实现闭环控制

出0入0汤圆

 楼主| 发表于 2014-8-21 09:14:52 | 显示全部楼层
xsh2005105326 发表于 2014-8-20 22:32
一种是步进电机,脉冲数决定转过角度;还有一种是普通电机+码盘,实现闭环控制 ...

***************************************************/       
#include "INCLUDES.h"

sbit AOB_L = P3^7;
sbit BOB_L = P3^6;
sbit AOB_R = P3^0;
sbit BOB_R = P3^1;

sbit bianjie = P1^5;   //外边界检测
sbit led  = P1^2;      //调试灯

uint cont;       //计数值
uint cont_old;   //前一次计数值

uchar direction_flag; //方向标示


//                           while(1)           //调试程序
//                                       {
//                   CAR_STOP();
//                                                                   led = 0;                                                          
//                }       
//                                                          


uchar a;         
uchar b;
uchar c;
uchar d;
uchar e;
uchar f;
uint s;

void first_one(void);
void obstacle_A_area(void);
void turn_B(void);
void turn_CC(void);
void last_vie(void);

void display_12864(uint time ,uint line);


void main(void)
{  
         LCD12864_Init();
         print(0x80,0,"小车运动时间:");           //         第一行显示
         print(0x88,0,"小车行驶总路程:");                 //         第三行显示
       
   control_Init();  //  计数初始化
         PWM_INIT();      //  PWM配置
         exn_Init();      //  外部中断配置
       
         clear_velue();
       
/***********调试参数****************/       
        a = 0;
        line_velue = 0;   
        b = 0;
        c = 0;
        d = 0;

                  CCAP1L=0x33;
            CCAP1H=0x33;  //pwm1,P1.4
                  CCAP0L=0x33;  //pwm0,p1.3
            CCAP0H=0x33;  //越大低电平时间越久       

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

       
        while(1)
        {
     switch (a)
    {
/**************第一段平整区******************/
             case 0 :                                      
                                   first_one();
                        break;
/****************第一个转弯区********************/                                         
             case 1 :                                   
                             turn_CC();
                        break;

/**************进入第一个障碍区***************/
                         case 2 :
                                    obstacle_A_area();
                              break;
/**************进入第二个转弯区**********************/
                         case 3 :
                                   turn_B();
                              break;
/***************进入第二个障碍区*********************************/
                         case 4 :
                                   obstacle_A_area();
                              break;
/****************进入第三个转弯区*************************************/
       case 5 :
                                   turn_CC();
                              break;
/****************进入第三个障碍区***************************************/                         
                         case 6 :
                                  obstacle_A_area();
                              break;
/*****************进入第四个转弯区****************************************************/
                         case 7 :
                                  turn_B();
                              break;
/*****************进入最后平整区**************************************************************/
                         case 8 :
                                  last_vie();
                              break;
/******************停止*******************/
                         case 9 :
                                  CAR_STOP();
                                  EA = 0;
                              break;

             default:
                   break;
    }
               
                if(time_flag == 0)
                {
                        s = velue_IN0();
                        display_12864(time_velue, s);  //隔1秒刷屏一次
                        time_flag = 1;
                       
                }
               
  }
       
}


/*******************子函数区*************************/

/***********第一个平整区*********/
void first_one(void)
{

switch (f)
{
        uchar n;
        case 0 :
                clear_velue();  //为下个状态直走做准备
                f++;   
                break;
       
         case 1 :         
       if((right_A == 0) && (right_B == 0)
                                 && (left_A == 0) && (left_B == 0))
        {
                                        control_direction(0,0);
                                }                                       
                           if((right_A == 1) ||(right_B == 1))   //右边检测到
                                 {
            f = 2;
                                          cont_old = velue_IN1();
                                 }
                         
                                 if((left_A == 1) || (left_B == 1)) // 左边传感器检测到
                                 {  
            f = 3;
                                          cont_old = velue_IN1();
                                 }
                                 if(line_velue == 2)
                                 {
                                                f = 4;
                                         CCAP1L=0x38;
           CCAP1H=0x38;  //pwm1,P1.4
                 CCAP0L=0x38;  //pwm0,p1.3
           CCAP0H=0x38;  //越大低电平时间越久
                                         clear_velue();
                                         cont_old = velue_IN1();
         }
                    break;
                                 
                case 2 :            
                                 Left_back();   //左轮后退       
                           cont = velue_IN0();    //左转一个小角度
                           n = cont - cont_old;
                           if(n > 3)
                                 {           
               f = 0;
         }          
                          break;
                          
                        case 3 :            
                                 Right_back();   //右轮后退       
                           cont = velue_IN1();    //右转一个小角度
                           n = cont - cont_old;
                           if(n > 3)
                                 {
            f = 0;
         }                                 
                    break;
                         case 4 :
                         control_direction(6,0);
                   cont = velue_IN0();   
                         n = cont - cont_old;
                         if(n > 7)
                         {
           a++;
                                   d = 0;
                         }
                                 break;
                                 
        default:
                break;
  }
}


/*************进入第1个障碍物区域(A)***************/
void obstacle_A_area(void)
{
          uchar n;
                   switch (b)
     {
                        case 0 :
                                clear_velue();               
                          b++;
                                break;
                       
/**************判断障碍物和线*******************/                       
            case 1 :               
                                if((right_A == 0) && (right_B == 0)
                                 && (left_A == 0) && (left_B == 0))  
                                {
                                    b = 2;        //直走
        }                               
                          if((right_A == 1) ||(right_B == 1))
                                {   
                                          b = 5;
                                         cont_old = velue_IN0();
                                }
                                if((left_A == 1) || (left_B == 1))
                                {   
            b = 6;
           cont_old = velue_IN1();                                       
                                }                                                       
                    break;

                        case 2 :                 
        if((BOB_R == 1) && (BOB_L == 1)
                                   && (AOB_R == 1) && (AOB_L == 1))                       
                                {
                                   control_direction(0,0);
                                         b = 1;     //继续检测
        }                                       
                                if((BOB_L == 0) || (AOB_L == 0))                                
                                {
                                                b = 3;       //右边转弯
        }
                                if((BOB_R == 0) || (AOB_R == 0))            
                                {
            b = 4;      //左边转弯
        }                                       
                   break;
                               
                        case 3 :            //向右壁障
              control_direction(0,3);       
        b = 0;                       
                   break;

                        case 4:
                    control_direction(3,0); //向左壁障
                          b = 0;
                    break;
                               
                        case 5 :            
                                 Left_back();   //左轮后退       
                           cont = velue_IN0();    //左转一个小角度
                           n = cont - cont_old;
                           if(n > 3)
                                 {
            if((BOB_R == 1) && (BOB_L == 1)
                                      && (AOB_R == 1) && (AOB_L == 1))
                                                {
               b = 0;
            }
         }          
                          break;
                          
                        case 6 :            
                                 Right_back();   //右轮后退       
                           cont = velue_IN1();    //左转一个小角度
                           n = cont - cont_old;
                           if(n > 3)
                                 {
            if((BOB_R == 1) && (BOB_L == 1)
                                      && (AOB_R == 1) && (AOB_L == 1))
                                                {
               b = 0;
            }
         }                                 
                    break;
                               
                                       
            default:
                   break;
     }
                 
                 if((line_velue == 4) || (line_velue == 8) || (line_velue == 6))//进入转弯区
                 {
                                a++;
                          c = 0;                          
                          d = 0;
     }  
                 
                 
}

/**********第二个转弯区******************/
void turn_B(void)
{   
           uchar n;
     switch (c)
     {                                  
                         case 0 :
                            c++;
                            clear_velue();
                                 break;       
                         
                         case 1 :
       if((right_A == 0) && (right_B == 0)
                                 && (left_A == 0) && (left_B == 0) && (bianjie == 0) )  
                                {
                                   c = 2;        //直走
        }               
                                                               
                           if((right_A == 1) || (right_B == 1))   //右边检测到
                                 {
            c = 5;
                                          cont_old = velue_IN1();
                                 }
                           if(bianjie == 1)  //中间传感器检测到
                                 {
                                                c = 6;
                                         cont_old = velue_IN1();
                                 }
                                 if((left_A == 1) || (left_B == 1))  // 左边传感器检测到
                                 {  
            c = 7;
                                         cont_old = velue_IN1();
                                 }                       
                    break;       
                               
             case 2 :          //
        if((BOB_R == 1) && (BOB_L == 1)
                                  && (AOB_R == 1) && (AOB_L == 1))
                                {
                                 c = 1;
                                 control_direction(0,0);
                                }
                                 if((BOB_L == 0) || (AOB_L == 0))                                
                                {
                                                c = 3;       //右边转弯  
        }
                                if((BOB_R == 0) || (AOB_R == 0))            
                                {
            c = 4;      //左边转弯
        }               
                    break;
                                 
                        case 3 :            //向右壁障
              control_direction(0,2);       
        c = 0;                       
                   break;

                        case 4:
                    control_direction(2,0); //向左壁障
                          c = 0;
                    break;
                                                                 
             case 5 :
                           Right_back();   //右轮后退
                           cont = velue_IN1();    //右转一个大角度
                           n = cont - cont_old;
                           if(n > 15)
                                 {
                                         if((BOB_R == 1) && (BOB_L == 1)
                                      && (AOB_R == 1) && (AOB_L == 1))
                                                {
               c = 0;
            }
         }                         
                    break;       
                                 
                         case 6 :               
         Right_back();   //右轮后退       
                           cont = velue_IN1();    //右转一个中角度
                           n = cont - cont_old;
                           if(n > 9)
                                 {
           if((BOB_R == 1) && (BOB_L == 1)
                                      && (AOB_R == 1) && (AOB_L == 1))
                                                {
               c = 0;
            }
         }                                
                    break;
                                 
             case 7 :
                                 Right_back();   //右轮后退       
                           cont = velue_IN1();    //右转一个小角度
                           n = cont - cont_old;
                           if(n > 5)
                                 {
           if((BOB_R == 1) && (BOB_L == 1)
                                      && (AOB_R == 1) && (AOB_L == 1))
                                                {
               c = 0;
            }
         }
                    break;
                                 
            default:
                    break;
     }       
                 if((line_velue == 9) || (line_velue == 5))
                 {
          a++;
                            b = 0;
                                        e = 0;   
     }
                 
}

/***************第三个转弯区***********************/
void turn_CC(void)
{
      uchar n;

     switch (d)
     {
                         case 0 :
                            d++;
                            clear_velue();
                                 break;       
                         case 1 :
       if((right_A == 0) && (right_B == 0)
                                 && (left_A == 0) && (left_B == 0) && (bianjie == 0))  
                                {
                                   d = 2;        //直走
        }               
                                if((left_A == 1)||(left_B == 1))   //左边检测到....
                                 {
            d = 5;
                                          cont_old = velue_IN0();
                                 }
                           if(bianjie == 1)  //中间传感器检测到
                                 {
                                                d = 6;
                                          cont_old = velue_IN0();
                                 }
                                 if((right_A == 1) || (right_B == 1))  // 左边传感器检测到
                                 {  
            d = 7;
                                         cont_old = velue_IN0();
                                 }
                    break;       
                                         
             case 2 :          //
        if((BOB_R == 1) && (BOB_L == 1)
                                  && (AOB_R == 1) && (AOB_L == 1))
                                {
                                 d = 1;
                                 control_direction(0,0);
                                }
                                if((BOB_L == 0) || (AOB_L == 0))                         //左边障碍物       
                                {
                                                d = 3;       //右边转弯
        }
                                if((BOB_R == 0) || (AOB_R == 0))            
                                {
            d = 4;      //左边转弯
        }                                                 
                    break;
                                 
                                case 3 :            //向右壁障
              control_direction(0,2);
        d = 0;                                       
                   break;

                        case 4:
                    control_direction(2,0); //向左壁障
                          d = 0;
        break;
                                                                                                 
             case 5 :
                           Left_back();   //左轮后退
                           cont = velue_IN0();    //左转一个大角度
                           n = cont - cont_old;
                           if(n > 15)
                                 {
                                         if((BOB_R == 1) && (BOB_L == 1)
                                      && (AOB_R == 1) && (AOB_L == 1))
                                                {
               d = 0;
            }
         }                         
                    break;       
                                 
                         case 6 :               
         Left_back();   //左轮后退       
                           cont = velue_IN0();    //左转一个中角度
                           n = cont - cont_old;
                           if(n > 9)
                                 {
           if((BOB_R == 1) && (BOB_L == 1)
                                      && (AOB_R == 1) && (AOB_L == 1))
                                                {
               d = 0;
            }
         }                                
                    break;
                                 
             case 7 :
                                 Left_back();   //右轮后退       
                           cont = velue_IN0();    //左转一个小角度
                           n = cont - cont_old;
                           if(n > 5)
                                 {
            if((BOB_R == 1) && (BOB_L == 1)
                                      && (AOB_R == 1) && (AOB_L == 1))
                                                {
               d = 0;
            }
         }
                    break;
                                 
            default:
                    break;
     }                       
                 
                if((line_velue == 7) || (line_velue == 3))
                 {
                                                a++;       
            b = 0;  //进入避障区                                         
                 }
}

/****************最后一个平整区*************************/
void last_vie(void)
{
          uchar n;
  switch (e)
{
        case 0 :
                clear_velue();  //为下个状态直走做准备
          CCAP1L=0x33;
    CCAP1H=0x33;  //pwm1,P1.4
          CCAP0L=0x33;  //pwm0,p1.3
    CCAP0H=0x33;  //越大低电平时间越久
                e++;   
                break;
       
         case 1 :
       if((right_A == 0) && (right_B == 0)
                                && (left_A == 0) && (left_B == 0))
                     {
                  control_direction(0,0);
                      }
                           if((right_A == 1) || (right_B == 1))  //右边检测到
                                 {
            e = 2;
                                          cont_old = velue_IN1();
                                 }
                         
                                 if((left_A == 1) ||(left_B == 1))   // 左边传感器检测到
                                 {  
            e = 3;
                                         cont_old = velue_IN1();
                                 }
                                 if(line_velue == 10)
                                 {
                                                e = 4;
                                         clear_velue();
                                         cont_old =  velue_IN1();
         }
                    break;
                case 2 :            
                                Left_back();   //左轮后退       
                           cont = velue_IN0();    //左转一个小角度
                           n = cont - cont_old;
                           if(n > 3)
                                 {           
               e = 0;
         }          
                          break;
                          
                        case 3 :            
                                Right_back();   //右轮后退       
                           cont = velue_IN1();    //左转一个小角度
                           n = cont - cont_old;
                           if(n > 3)
                                 {
            e = 0;
         }                                 
                    break;
   
                       
                case 4 :
                        control_direction(0,0);
                  cont = velue_IN0();    //最后冲过终点
                        n = cont - cont_old;
                  if(n > 25 )
                        {
                                a++;              
      }               
                break;
                       
        default:
                break;
  }   
               

}


/***************************/
/***************12864显示函数******************/
void display_12864(uint time ,uint line)
{
               
                print(0x90,0," ");                           //          第二行显示
                LCD12864_WriteData(time/100+0x30);
                LCD12864_WriteData(time/10%10+0x30);
                LCD12864_WriteData(time%10+0x30);
                print(0x90,2,"秒");
          
       
          
                print(0x98,0," ");                                  //        第四行显示
          LCD12864_WriteData(line/1000+0x30);
                LCD12864_WriteData(line/100%10+0x30);
                LCD12864_WriteData(line/10%10+0x30);
                LCD12864_WriteData(line%10+0x30);
                print(0x98,3,"厘米");
          
}


出0入0汤圆

 楼主| 发表于 2014-8-21 09:15:20 | 显示全部楼层
xsh2005105326 发表于 2014-8-20 22:32
一种是步进电机,脉冲数决定转过角度;还有一种是普通电机+码盘,实现闭环控制 ...

程序看不懂,不是我的
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 03:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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