跟踪鞋子的小车-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 6184|回复: 1

[报名] 跟踪鞋子的小车

 关闭 [复制链接]
发表于 2016-10-7 07:19 | 显示全部楼层 |阅读模式
学习arduino几个月,代码和硬件搭建可能有一些不合理的地方,希望各位多多指正。
暑假突然想到可以用小型的光源来引导小车跟踪鞋子,于是就着手准备材料了。初步的想法是将光源固定在鞋子上,走路时小车就会一直跟在身后。
这里使用了arduino uno作为主控板,DFRobot的小车底盘以及L298驱动扩展版,夏普距离传感器和一个小型充电宝。
小车两侧安置红外传感器用以判断方向,由于使用的发射器的范围不大,为防止发射器和传感器不在一个水平线上,每一侧我都安装了两个。另外在小车第二层的底部固定了一个红外测距,用以在方向调整完后判断并调整与发射器的距离。大致的调整过程如下:
首先调整方向,当左侧传感器返回数值远大于右侧时,说明小车左侧更靠近发射器,因此控制小车左转使其正对发射器,当右侧传感器返回数值远大于右侧时,则控制小车右转。
方向调整完毕以后读取红外测距的数值,当距离小于等于10厘米时小车后退,距离在10厘米和17厘米之间静止不动,距离超过17厘米则前进。

2种特殊情况:
1.小车距离鞋子太近,即使转动很小,两侧的传感器数值变化仍然很大,容易陷入左转-右转-左转-右转的死循环中,因此当距离小于5厘米时调整距离优先,后退之后再判断方向。
2.当发射器于小车的距离过大时,左右红外传感器的返回数值皆为0,小车将停止之前的动作并静止不动,等待发射器再次接近。


由于小车判定方向时只需要接受红外光源一小段时间,因此红外发射器不需要持续发射,因此买了一个兼容arduino的小型红外发射模块,以前做项目时用的小型号主控板,每0.1s给一个20ms的高电平,这样电流不会超过限定值。由于设定小车每个动作持续0.2s,判断+执行一个动作的总时间不会超过0.3s,一秒内可以完成三次调整。


目前由于小车太重,速度跟不上,行走时很容易跟丢。这里先发一个拿鞋子引路的视频,各位谅解哈





以下是代码(编程水平有限,判断条件的子函数写的有点乱):

[mw_shl_code=cpp,true]/*
接线:
距离传感器A0
左下红外传感器A2
左上红外传感器A3
右下红外传感器A4
右上红外传感器A5
每个传感器都接扩展板上的vcc和gnd
*/
char E1 = 10;
char M1 = 12;
char E2 = 11;
char M2 = 13;

char disPin = A0;  
char IRLL = A2;  
char IRLU = A3;
char IRRL = A4;
char IRRU = A5;

int valLL;
int valRL;
int valLU;
int valRU;
int t = 200;
int current;
double dis;

void setup() {
   
  //Serial.begin(9600);
  pinMode(disPin, INPUT);
  pinMode(IRLL, INPUT);
  pinMode(IRRL, INPUT);
  pinMode(IRLU, INPUT);
  pinMode(IRRU, INPUT);
   
}

void loop() {
   
  valLL = analogRead(IRLL);
  valRL = analogRead(IRRL);
  valLU = analogRead(IRLU);
  valRU = analogRead(IRRU);

  current = checkStatus(valLL, valLU, valRL, valRU);
   
  switch (current) {

    case 1:
     turnL(130);
     /*Serial.print("Turn Left -- leftLower : ");
     Serial.print(valLL);
     Serial.print("  rightLower : ");
     Serial.print(valRL);
     Serial.print("  leftUpper : ");
     Serial.print(valLU);
     Serial.print("  rightUpper : ");
     Serial.println(valRU);*/  
     delay(t);
     break;
      
    case 2:
     turnR(130);
     /*Serial.print("Turn Right -- leftLower : ");
     Serial.print(valLL);
     Serial.print("  rightLower : ");
     Serial.print(valRL);
     Serial.print("  leftUpper : ");
     Serial.print(valLU);
     Serial.print("  rightUpper : ");
     Serial.println(valRU);*/
     delay(t);
     break;
      
    case 3:
    back(180,180);
     /*Serial.print("Right in the middle -- leftLower : ");
     Serial.print(valLL);
     Serial.print("  rightLower : ");
     Serial.print(valRL);
     Serial.print("  leftUpper : ");
     Serial.print(valLU);
     Serial.print("  rightUpper : ");
     Serial.print(valRU);
     Serial.print(" distance: ");
     Serial.print(dis);
     Serial.print("cm ");
     Serial.println("back");*/
     delay(t);
     break;
      
    case 4:
    brake();
     /*Serial.print("Right in the middle -- leftLower : ");
     Serial.print(valLL);
     Serial.print("  rightLower : ");
     Serial.print(valRL);
     Serial.print("  leftUpper : ");
     Serial.print(valLU);
     Serial.print("  rightUpper : ");
     Serial.print(valRU);
     Serial.print(" distance: ");
     Serial.print(dis);
     Serial.print("cm ");
     Serial.println("stop");*/
     delay(t);
     break;
      
    case 5:
    advance(180,180);
    /* Serial.print("Right in the middle -- leftLower : ");
     Serial.print(valLL);
     Serial.print("  rightLower : ");
     Serial.print(valRL);
     Serial.print("  leftUpper : ");
     Serial.print(valLU);
     Serial.print("  rightUpper : ");
     Serial.print(valRU);
     Serial.print(" distance: ");
     Serial.print(dis);
     Serial.print("cm ");
     Serial.println("advance");*/
     delay(t);
     break;
      
    case 6:
    brake();
    /* Serial.print("Out of range -- leftLower : ");
     Serial.print(valLL);
     Serial.print("  rightLower : ");
     Serial.print(valRL);
     Serial.print("  leftUpper : ");
     Serial.print(valLU);
     Serial.print("  rightUpper : ");
     Serial.print(valRU);*/
     delay(t);
     break;
      
    default:
    break;
     
  }
  
}



int checkStatus(int leftLowerValue, int leftUpperValue, int rightLowerValue, int rightUpperValue){
   
  static unsigned long last;  //记录上一次收到红外线的时间
  int carStatus = 0;
  uint16_t value = analogRead (disPin);
  dis =  2076.0 / (value - 11.0);
//任一传感器返回大于100的数值则说明收到了发射源的红外线
  if ( leftLowerValue >= 100 || leftUpperValue >= 100 || rightLowerValue >= 100 || rightUpperValue >= 100 )
  {
  
      if( leftLowerValue - rightLowerValue > 180 || leftUpperValue - rightUpperValue > 180 )
      {
             carStatus = 1;
      }
       else if ( rightLowerValue - leftLowerValue > 180 || rightUpperValue - leftUpperValue > 180 )
      {
             carStatus = 2;

      }
//若方向调整完毕,测量距离
      else
      {  
          if (dis < 100 ){
          if( dis <= 10 ) carStatus = 3;  
          else if( dis > 10 && dis < 17 ) carStatus = 4;
          else carStatus = 5;  //测量距离并作出相应的动作
         }
      }
     
  last = millis();
  if( dis <= 10 ) carStatus = 3; //方向不正但是距离过近时调整距离优先

  }

  else if(millis() - last > 500)
  {
    carStatus = 6;   //当连续500ms没有探测到红外线时说明光源过远,停止小车当前动作
  }
  
return carStatus;

}


void advance(int alspeed, int arspeed){
   
  digitalWrite(M1,LOW);
  analogWrite(E1,alspeed);
  digitalWrite(M2,HIGH);
  analogWrite(E2,arspeed);
   
}


void back(int blspeed, int brspeed){
   
  digitalWrite(M1,HIGH);
  analogWrite(E1,blspeed);
  digitalWrite(M2,LOW);
  analogWrite(E2,brspeed);
   
}


void turnR(int trspeed){
   
  digitalWrite(M1,LOW);
  analogWrite(E1,trspeed);
  digitalWrite(M2,LOW);
  analogWrite(E2,trspeed);
   
}


void turnL(int tlspeed){
   
  digitalWrite(M1,HIGH);
  analogWrite(E1,tlspeed);
  digitalWrite(M2,HIGH);
  analogWrite(E2,tlspeed);
   
}


void brake(){
   
  digitalWrite(M1,LOW);
  digitalWrite(E1,LOW);
  digitalWrite(M2,LOW);
  digitalWrite(E2,LOW);
   
}[/mw_shl_code]

最后附上实物图一张 IMG_2456-2.JPG
发表于 2016-12-11 23:12 | 显示全部楼层
不错,就是感应器距离太近
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-9-20 22:29 , Processed in 0.079860 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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