基于Arduino控制的网格循迹小车

1.元器件选型

电子元器件清单

序号

标号

名称

规格

数量

1

/

Arduino板

/

1

2

/

驱动模块

LM298N

1

3

/

巡线模块

5

机械零部件清单

序号

标号

名称

规格

数量

1

M1

直流电机

/

2

2

M2

2

3

/

车轮

/

4

4

/

硅胶轮胎

25*2.5

4

序号

标号

名称

规格

数量

1

/

连接导线

红色

n

2

/

黑色

n

 小车:采用4个直流减速电机,一个五路循迹模块,一个12V电池组,1个LM298N驱动模块和一个arduino控制板。

3.代码部分:

#include<SoftwareSerial.h>

#include<FlexiTimer2.h>//中断函数引用

#define TURNLEFT 0

#define TURNRIGHT 1

#define STOP 2

#define BACK 3

#define GO 4

#define leftrun 5

#define rightrun 6#define LMotor_1 8

#define LMotor_2 9

#define RMotor_1 10

#define RMotor_2 11

#define pwmLMotor_1 5//int ENA=6;//定义EA(PWM调速)接口

#define pwmRMotor_2 6//int ENB=5;//定义EB(PWM调速)接口

//四路红外循迹模块

#define X1 A0//定义中间第二个寻线传感器接口

#define X2 A1//定义左侧寻线传感器接口

#define X3 A2//定义中间第二个寻线传感器接口

#define X4 A3//定义左侧寻线传感器接口

#define L1 2//定义左侧中间寻线传感器接口

volatile int i;

void setup() {

  Serial.begin(9600);

  pinMode(LMotor_1,OUTPUT);

  pinMode(LMotor_2,OUTPUT);

  pinMode(RMotor_1,OUTPUT);

  pinMode(RMotor_2,OUTPUT);

  pinMode(pwmLMotor_1,OUTPUT);

  pinMode(pwmRMotor_2,OUTPUT)

  pinMode(X1,INPUT);//红外循迹

  pinMode(X2,INPUT);

  pinMode(X3,INPUT);

  pinMode(X4,INPUT);

  pinMode(L1,INPUT);

  attachInterrupt(0, attachPinInterrupt_fun_0, RISING);//interrupt为你中断通道编号,function为中断函数,mode为中断触发模式

}

 void loop(){

    xunji();

    Motorrun(GO,85);

    if (i==1){

    delay(100);

    detachInterrupt(0);

    Motorrun(STOP,0);

    delay(2000);

    Motorrun(TURNLEFT,95);

    delay(1000);

    Motorrun(STOP,0);

    delay(1000);

    attachInterrupt(0,attachPinInterrupt_fun_0,RISING);

    }

    if (i==8){

    delay(100);

    detachInterrupt(0);

    Motorrun(STOP,0);

    delay(2000);

    Motorrun(TURNLEFT,95);

    delay(1000);

    Motorrun(STOP,0);

    delay(1000);

    attachInterrupt(0,attachPinInterrupt_fun_0,RISING);

    }

    if (i==12){

    delay(100);

    detachInterrupt(0);

    Motorrun(STOP,0);

    delay(2000);

    Motorrun(TURNLEFT,95);

    delay(1000);

    Motorrun(STOP,0);

    delay(1000);

    attachInterrupt(0,attachPinInterrupt_fun_0,RISING);

    }

   if (i==14){

    delay(100);

    detachInterrupt(0);

    Motorrun(STOP,0);

    delay(2000);

    Motorrun(TURNRIGHT,95);

    delay(1000);

    Motorrun(STOP,0);

    delay(1000);

    attachInterrupt(0,attachPinInterrupt_fun_0,RISING);

   }

   if (i==25){

    delay(100);

    detachInterrupt(0);

    Motorrun(STOP,0);

    delay(2000);

    Motorrun(TURNRIGHT,95);

    delay(1000);

    Motorrun(STOP,0);

    delay(1000);

    attachInterrupt(0,attachPinInterrupt_fun_0,RISING);

   }

   if (i==27){

    detachInterrupt(0);

    Motorrun(STOP,0);

    delay(50000);

    attachInterrupt(0,attachPinInterrupt_fun_0,RISING);

   }

}

void attachPinInterrupt_fun_0() {//定义侧边红外模块检测

  if (digitalRead(0) == HIGH) {

    delay(50);

      if (digitalRead(0) == HIGH) {

        i = i + 1;}  

  }

  Serial.println(i);

}

//电机运动

void Motorrun(int cmd,int value){

  analogWrite(pwmLMotor_1,value);

  analogWrite(pwmRMotor_2,value);

  switch(cmd){

    //前进

    case GO:

    digitalWrite(LMotor_1,HIGH);

    digitalWrite(LMotor_2,LOW);

    digitalWrite(RMotor_1,HIGH);

    digitalWrite(RMotor_2,LOW);

    break;

    //后退

    case BACK:

    digitalWrite(LMotor_1,LOW);

    digitalWrite(LMotor_2,HIGH);

    digitalWrite(RMotor_1,LOW);

    digitalWrite(RMotor_2,HIGH);

    break;

    //左转

    case TURNRIGHT:

    digitalWrite(LMotor_1,HIGH);

    digitalWrite(LMotor_2,LOW);

    digitalWrite(RMotor_1,LOW);

    digitalWrite(RMotor_2,HIGH);

    break;

    //右转

    case TURNLEFT:

    digitalWrite(LMotor_1,LOW);

    digitalWrite(LMotor_2,HIGH);

    digitalWrite(RMotor_1,HIGH);

    digitalWrite(RMotor_2,LOW);

    break;

    //停止

    case STOP:

    digitalWrite(LMotor_1,LOW);

    digitalWrite(LMotor_2,LOW);

    digitalWrite(RMotor_1,LOW);

    digitalWrite(RMotor_2,LOW);

    default:

    digitalWrite(LMotor_1,LOW);

    digitalWrite(LMotor_2,LOW);

    digitalWrite(RMotor_1,LOW);

    digitalWrite(RMotor_2,LOW);

  }

}

  void xunji(){

  int r,m,m2,l;

  r=digitalRead(X1);

  m=digitalRead(X2);

  m2=digitalRead(X3);

  l=digitalRead(X4);

  if(l==HIGH and m==LOW and m2==LOW and r==LOW){

    Motorrun(TURNLEFT,90);

   delay(50);

}

  if(l==LOW and m==LOW and m2==LOW and r==HIGH){

    Motorrun(TURNRIGHT,90);

    delay(50);

}

 if(l==HIGH and m==HIGH and m2==LOW and r==LOW){

    Motorrun(TURNLEFT,90);

    delay(30);

}

  if(l==LOW and m==LOW and m2==HIGH and r==HIGH){

    Motorrun(TURNRIGHT,90);

    delay(30);

 if(l==LOW and m==HIGH and m2==LOW  and r==LOW){

    Motorrun(TURNLEFT,90);

    delay(20);

}

  if(l==LOW and  m==LOW and m2==HIGH  and r==LOW){

    Motorrun(TURNRIGHT,90);

    delay(20);  

}

4.分析及改进

问题一及改进(采用四轮或三轮小车):刚开始,采用的是三轮小车,但三轮小车的稳定性,十分差劲。(干扰因素,万向轮从动轮的状态,对小车的影响较大。)后采用四个轮子,小车的稳定性得到极大的改善,小车的循迹功能变得十分稳定且流畅。  因此,建议采用四轮小车进行循迹。

问题二及改进(电机的选择):直到比赛,我们采用的是四个玩具电机,由于玩具电机不够准确且极易受到外界的干扰(电压,地面摩擦等),小车的拐弯精度调节,一度陷入困境,刚开始一直认为是代码问题,不断调试代码,比赛时依然出错。比赛后用直流减速电机,问题瞬间解决。    因此,建议采用直流减速电机。

问题三及改进(计数模块的选择):计数模块有四路循迹模块同时计数和计数或采用5个循迹模块(其中四个用来循迹,剩下一个用来计数),经过尝试,采用5路循迹模块的计数更为准确。建议采用直流减速电机,但计数模块最好可以进行遮挡,减少外界光的干扰。

问题四及改进(左右转方式选择):左右转建议采用一边正传,一边倒转。这样的转弯具有调节的灵敏度较高,且转弯处于原地转弯,定位能力也较高。

  

  • 18
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值