介绍了用Arduino制作的电脑无线遥控履带小车,这次只是做了一点改进。以后还有相关改进会继续发布出来。

此次的改进有几点:

1。电机驱动板改用Arduino专用驱动板,叠层设计的安装方便。

2。加了一层大面积平台,方便安装更多的东西。

3。改用上位机软件发命令,使用键盘的“w,s,a,d”控制小车前进,后退,左转,右转。

4。增加了个舵机云台(方便以后安装超声波、红外线、摄像头等等),使用键盘的“q,w,e”控制舵机向左,正中,向右。

5。增加了3个GP2D12红外线测距模块,1个超声波测距模块,1个寻线传感器(本实验没有使用)。

 

 

 

Arduino专用电机驱动板1A电流

有点WALL-E的感觉,哈哈~~~

 

 

 

 

 

上代码:(编译环境0011版  任意脚控制舵机函数库下载地址  库文件下载放到0011版库里)

  1. #include <Servo.h>    //调用舵机库  
  2.  
  3. Servo servo1;            //定义舵机  
  4.  
  5. //A板电机驱动板占用的数字端口。  
  6. int EN1 = 6;    
  7. int EN2 = 9;  
  8. int IN1 = 7;  
  9. int IN2 = 8;      
  10.  
  11.                          
  12. void stop(void)  
  13.         {  
  14.           digitalWrite(EN1,LOW);     
  15.           digitalWrite(EN2,LOW);        
  16.         }  
  17.           
  18. void advance_l(void)  
  19.         {  
  20.           digitalWrite(EN1,HIGH);  
  21.           digitalWrite(IN1,HIGH);      
  22.         }    
  23.           
  24. void advance_r(void)     
  25.        {  
  26.           digitalWrite(EN2,HIGH);  
  27.           digitalWrite(IN2,HIGH);  
  28.         }  
  29.  
  30. void back_off_l(void)  
  31.         {  
  32.           digitalWrite(EN1,HIGH);  
  33.           digitalWrite(IN1,LOW);     
  34.         }    
  35.           
  36. void back_off_r(void)     
  37.        {  
  38.           digitalWrite(EN2,HIGH);  
  39.           digitalWrite(IN2,LOW);  
  40.         }  
  41.  
  42.           
  43. void setup()   
  44. {   
  45.     int i;  
  46.     for(i=6;i<=9;i++)  
  47.     pinMode(i, OUTPUT);    
  48.     servo1.attach(10);                         //定义舵机端口为数字PIN10 ,可定义为任意脚  
  49.     servo1.setMaximumPulse(2200);   //定义180度的脉冲宽度,默认最大2400微秒  
  50.     Serial.begin(19200);                      //定义波特率为19200,必须和APC一致  
  51. }   
  52.    
  53.     
  54.    
  55. void loop()   
  56. {   
  57.   int x,delay_en;  
  58.   char val;  
  59.   while(1)  
  60.   {  
  61.     val = Serial.read();  
  62.     if(val!=-1)  
  63.        {  
  64.           switch(val)  
  65.            {  
  66.              case ''w''://前进  
  67.                          advance_l();  
  68.                          advance_r();  
  69.                          x=90;                 //舵机回正  
  70.                          break;  
  71.              case ''s''://后退  
  72.                          back_off_l();  
  73.                          back_off_r();  
  74.                          break;  
  75.              case ''a''://左转  
  76.                          advance_l();  
  77.                          back_off_r();  
  78.                          break;         
  79.              case ''d''://右转  
  80.                          advance_r();  
  81.                          back_off_l();  
  82.                          break;     
  83.              case ''q''=150;              //舵机旋转到150度  
  84.                          delay_en=0;  
  85.                          break;  
  86.              case ''e''=30;                //舵机旋转到30度  
  87.                          delay_en=0;  
  88.                          break;                                       
  89.            }       
  90.          if(delay_en==1)delay(30); //执行舵机时不延时  
  91.        }  
  92.     else stop();           
  93.     delay_en=1;  
  94.     servo1.write(x);                       //执行舵机命令  
  95.     Servo::refresh();                     //更新舵机  
  96.   }                             
  97. }  
  98.  

 这次又对履带小车做了功能添加,可玩性更强了,也是履带监控机器人的雏形。

新增部分:

       1,使用本公司的上位机软件控制,带通讯协议;
       2,使用游戏手柄手动控制机器人前进、后退、转弯以及云台的控制;
       3,增加1个模拟的无线摄像头和2自由度云台;
       4,增加1个环境光线检测传感器;
       5,增加配合环境光线检测传感器的探照灯,当环境光线弱时,打开探照灯,环境光线强时,关闭探照灯;
       6,使用前面3个GP2D12做自动避障,当关闭手动控制时,自动进入自动避障模式。

 

履带监控机器人:

 

 实验代码:

 

  1. #include <Servo.h>  
  2.  
  3. Servo servo1;  
  4. Servo servo2;  
  5.  
  6. int EN1 = 6;    
  7. int EN2 = 9;  
  8. int IN1 = 7;  
  9. int IN2 = 8;      
  10.    
  11. int GP2D12_r = 0;   //右  
  12. int GP2D12_c = 1;   //中  
  13. int GP2D12_l = 2;   //左  
  14.  
  15. int R = 5;  
  16. int LED = 13;  
  17.  
  18. void stop(void)  
  19.         {  
  20.           digitalWrite(EN1,LOW);     
  21.           digitalWrite(EN2,LOW);        
  22.         }  
  23.           
  24. void advance_r(int x)  
  25.         {  
  26.           analogWrite(EN1,x);  
  27.           digitalWrite(IN1,HIGH);      
  28.         }    
  29.           
  30. void advance_l(int x)     
  31.        {  
  32.           analogWrite(EN2,x);      
  33.           digitalWrite(IN2,HIGH);  
  34.         }  
  35.  
  36. void back_off_r(int x)  
  37.         {  
  38.           analogWrite(EN1,x);  
  39.           digitalWrite(IN1,LOW);     
  40.         }    
  41.           
  42. void back_off_l(int x)     
  43.        {  
  44.           analogWrite(EN2,x);      
  45.           digitalWrite(IN2,LOW);  
  46.         }  
  47.  
  48.  
  49. void setup()  
  50. {  
  51.   int i;  
  52.   for(i=6;i<=9;i++)  
  53.   pinMode(i, OUTPUT);   
  54.   servo1.attach(10);//定义舵机控制口  
  55.   servo1.setMaximumPulse(2500);//定义旋转的时间  
  56.   servo2.attach(11);  
  57.   servo2.setMaximumPulse(2500);//定义旋转的时间  
  58.   Serial.begin(19200);//设置波特率  
  59. }  
  60.  
  61. void loop()  
  62. {  
  63.   int dataLen = 0;    //数据长度  
  64.   int start_flag = 0; //起动标志位  
  65.   int data_index=0;  
  66.   int com_index=0;    //索引初始化    
  67.   int temp_char1;  
  68.   int temp_char0;  
  69.   int i,unm,x,y;  
  70.   int state;                  //帧状态  
  71.   int SUM1,SUM2;      //效验和  
  72.   int MOTO[7],RC[9];  //电机控制寄存器和舵机控制寄存器  
  73.   int L_ir,C_ir,R_ir; //红外线寄存器    
  74.   int Serial_flag,Serial_unm;  
  75.     
  76.   while(1)  
  77.   {  
  78.     int val;  
  79.     L_ir=analogRead(GP2D12_l);  
  80.     C_ir=analogRead(GP2D12_c);  
  81.     R_ir=analogRead(GP2D12_r);  
  82.     val=analogRead(R);  
  83.     if(val<200)digitalWrite(LED,HIGH);  
  84.     else digitalWrite(LED,LOW);  
  85.     temp_char1 = Serial.read();     //读取串口数据  
  86.     if(temp_char1!=-1)   
  87.       {      
  88.        Serial_flag=1;   
  89.        Serial_unm=0;             
  90.        if(start_flag == 0)     //等待数据头 0X55,0XAA  
  91.   {  
  92.      if( temp_char1  == 170 )     
  93.   {  
  94.     if(temp_char0  == 85)  
  95.          {  
  96.                 start_flag = 1;  //收到数据头,表示一个数据包传送开始  
  97.                 MOTO[0]=85;  
  98.                 MOTO[1]=170;  
  99.                 RC[0]=85;  
  100.                 RC[1]=170;                                 
  101.                 data_index = 0;   
  102.                 com_index = 0;      
  103.    }  
  104.    }  
  105.      else temp_char0 = temp_char1;  
  106.    }  
  107.         else if( com_index < 2)  
  108.    {   
  109.       switch(com_index)     
  110.   {  
  111.       case 0 :    MOTO[2] = temp_char1;  
  112.                        RC[2] = temp_char1;  
  113.                        dataLen = temp_char1;  
  114.                        break;    
  115.       case 1 :    MOTO[3] = temp_char1;  
  116.                        RC[3] = temp_char1;  //第2个数据,读取命令字                         
  117.                        break;  
  118.     }  
  119.                com_index++;   
  120.     }  
  121.          else if(data_index < dataLen && MOTO[3]==2) //存储数据  
  122.            {   
  123.              MOTO[data_index+4] = temp_char1;  
  124.              data_index ++;  
  125.            }  
  126.          else if(data_index < dataLen && RC[3]==1) //存储数据  
  127.            {   
  128.                RC[data_index+4] = temp_char1;  
  129.               data_index ++;  
  130.            }  
  131.          else 
  132.            {  
  133.              MOTO[6] = temp_char1;  
  134.              RC[8] = temp_char1;  
  135.              state=1;   // 一帧接收完毕  
  136.              start_flag = 0;  
  137.            }                    
  138.        }  
  139.    else   
  140.       {  
  141.        Serial_unm++;  
  142.        if(Serial_unm==2000){Serial_flag=0;Serial_unm=0;}  
  143.        if(Serial_flag==0)  
  144.          {  
  145.           if(C_ir<200&& L_ir<200 && R_ir<200)  
  146.             {  
  147.                advance_l(200);            
  148.                advance_r(200);   
  149.                delay(200);   
  150.             }    
  151.           else if((C_ir<200||C_ir>200)&& L_ir>250 && R_ir<200)  
  152.             {  
  153.                advance_l(200);  
  154.                back_off_r(200);   
  155.                delay(700);   
  156.             }  
  157.           else if((C_ir<200||C_ir>200)&& L_ir<200 && R_ir>250)  
  158.             {  
  159.                advance_r(200);  
  160.                back_off_l(200);   
  161.                delay(1000);   
  162.             }  
  163.           else if(C_ir>200&& L_ir>200 && R_ir>200)    
  164.             {  
  165.                back_off_r(200);   
  166.                back_off_l(70);          
  167.                delay(1000);         
  168.              }  
  169.           }  
  170.       }     
  171.        
  172.    if(state==1)  
  173.     {       
  174.      state=0;       
  175.      if(MOTO[3]==2)  
  176.        {  
  177.          SUM1=0;    
  178.          for(i=0; i<6; i++)SUM1+=MOTO;  
  179.          SUM1%=256;  
  180.          if(SUM1==MOTO[6])  
  181.           {  
  182.             if(MOTO[4]==128&&MOTO[5]==128)stop();  
  183.             if(MOTO[4]>128)back_off_l(200);//  
  184.             else if(MOTO[4]<128)advance_l(200);//  
  185.             if(MOTO[5]>128)back_off_r(200);//  
  186.             else if(MOTO[5]<128)advance_r(200);//  
  187.             delay(80);  
  188.           }    
  189.        }    
  190.      if(RC[3]==1)  
  191.        {  
  192.          SUM2=0;  
  193.          for(i=0; i<8; i++)SUM2+=RC;  
  194.          SUM2%=256;       
  195.          if(SUM2==RC[8])  
  196.           {    
  197.             if(RC[4]>=150)x=150;  
  198.             else if(RC[4]<=30)x=30;  
  199.             else x=RC[4];       
  200.             if(RC[6]>=150)y=150;   
  201.             else if(RC[6]<=30)x=30;             
  202.             else y=RC[6];             
  203.             servo1.write(x);  
  204.             servo2.write(y);             
  205.             Servo::refresh();//刷新  
  206.           }   
  207.        }         
  208.      }  
  209.    }  
  210. }  
  211.