Arduino与Proteus仿真实例-简单红外寻迹小车控制仿真

简单红外寻迹小车仿真

1、寻迹小车介绍

红外寻迹小车是一种简单的Line Flower Robot(LFR)自主导向机器人,它会随地面上的线来检测白色表面上的暗线或黑色表面上的白线。LRF跟随线,因此,机器人必须检测到线的存在,这样问题就变成了如何在 LFR 中实现线路感应机制。

我们知道,光在白色表面的反射最大,在黑色表面上的反射最小,因为黑色表面吸收的光量最大。 因此,我们将利用光的这种特性来检测线条。 要检测光,可以使用 LDR(光敏电阻)或 IR 传感器。 在本实例中,将使用 IR 传感器,因为它具有更高的精度。 为了检测线,我们在机器人的左侧和右侧放置了两个红外传感器,如下图所示。 然后我们将机器人放在线上,使线位于两个传感器的中间。

红外传感器由两个元件组成,发射器和接收器。 发射器基本上是一个 IR LED,它产生信号,而 IR 接收器是一个光电二极管,它感应发射器产生的信号。 红外传感器在物体上发射红外光,照射到黑色部分的光被吸收,因此输出较低,但照射到白色部分的光反射回发射器,然后由红外接收器检测到,从而产生模拟输出 . 使用所述原理,我们通过驱动连接到电机的轮子来控制机器人的运动,电机由微控制器控制。

在前面的文章中,对红外寻迹传感器做了详细的介绍,请参考:

本次实例将使用L293D作为直流电机的驱动模块。在前面的文章中,对LD293D的驱动做了详细的介绍,请参考:

本次寻迹小车的仿真模型如下:

在这里插入图片描述

实验使用到材料如下:

  • 直流电机及车轮分别两个
  • 红外寻迹传感器两个
  • 万向轮1一个
  • Arduino Uno 主控板一个
  • 9V电池一个
  • LM293D驱动板一个
  • 连线线若干
  • 亚克力底板一个
  • 螺丝、固定器若干

小车的配件安装参数,在这里就不做介绍了,请根据配件尺寸自行定义。

2、寻迹小车控制逻辑介绍

典型的线跟随机器人有两组电机,我们称它们为左电机和右电机。 两个电机分别根据从左右传感器接收到的信号旋转。 机器人需要执行 4 组运动,包括前进左转右转停止。 下面给出关于这些情况的描述。

1) 前进方向

在这里插入图片描述

在这种情况下,当两个传感器都在一个白色的表面上并且两个传感器之间有一条线时,机器人应该向前移动,即两个电机都应该旋转,使得机器人向前移动(实际上两个电机都应该旋转,在这里我们称电机为正旋转)。

2)左转方向

在这里插入图片描述

在这种情况下,左侧传感器位于黑线顶部,而右侧传感器位于白色部分,因此左侧传感器检测到黑线并向微控制器发出信号。 由于信号来自左侧传感器,因此机器人应转向左侧。 因此,左侧电机反向旋转,右侧电机正向旋转。 因此,机器人转向左侧。

3)右转方向

在这里插入图片描述

这种情况与左转情况类似,但在这种情况下,只有右侧传感器检测到线,这意味着机器人应该朝正确的方向转动。 为了使机器人向右转动,左侧电机向前旋转,右侧电机向后旋转,机器人向右转动。

4)停止

在这里插入图片描述

在这种情况下,两个传感器都在线上,它们可以同时检测到黑线,微控制器被反馈认为这种情况是一个停止过程。 因此,两个电机都停止,这导致机器人停止移动。

3、仿真电路原理图

在这里插入图片描述

红外寻迹传感器接线如下:

  • 左传感器:引脚2
  • 右传感器:引脚4

L293D电机接线如下:

  • 左电机:IN1,IN2,EN1分别连接引脚6、7、5
  • 右电机:IN3,IN4,EN2分别连接引脚9、10、8

4、驱动实现

LFR机器人的编程部分非常简单,只需对IO端口进行控制和逻辑判断即。

第一步,定义每个 Arduino 引脚

1
2
3
4
5
6
7
8
9
10
11
12
// 电机引脚定义
#define enA 5 // L293D EN1
#define in1 6 // L293D IN1
#define in2 7 // L293D IN2
#define in3 9 // L293D IN3
#define in4 10 // L293D IN4
#define enB 8 // L293D EN2

// 红外寻迹传感器定义
#define R\_S 4 // 右侧传感器
#define L\_S 2 // 左侧传感器

第二步,初始化引脚

setup函数中,初始化串口及引脚

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void setup(){ 
Serial.begin(9600);
pinMode(R_S, INPUT);
pinMode(L_S, INPUT);
pinMode(enA, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
pinMode(enB, OUTPUT);
digitalWrite(enA, HIGH);
digitalWrite(enB, HIGH);
}

第三步,小车逻辑实现

loop函数中,实现小车运行逻辑控制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void loop(){  
if((digitalRead(R_S) == 0)&&(digitalRead(L_S) == 0)){
forward();
Serial.println("forward");
}
if((digitalRead(R_S) == 1)&&(digitalRead(L_S) == 0)){
turnRight();
Serial.println("turn right");
}
if((digitalRead(R_S) == 0)&&(digitalRead(L_S) == 1)){
turnLeft();
Serial.println("turn left");
}
if((digitalRead(R_S) == 1)&&(digitalRead(L_S) == 1)){
stop();
Serial.println("stop");
}
}

小车前进控制函数:

1
2
3
4
5
6
7
8
9
10
11
12
// 前进
void forward(){
// 右轮正转向
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);

// 右轮正转向
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
}


小车右转控制函数:

1
2
3
4
5
6
7
8
9
10
// 右转
void turnRight(){
// 左轮反转向
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
// 右轮正转向
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
}

小车左转控制函数:

1
2
3
4
5
6
7
8
9
10
// 左转
void turnLeft(){
// 左轮正转向
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// 右轮反转向
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
}

小车停止控制函数:

1
2
3
4
5
6
7
8
9
10
// 停止
void stop(){
// 左轮停止
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
// 右轮停止
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
}

5、仿真结果

在仿真环境中,电机响应有点延时,仿真结果如下:

在这里插入图片描述

文章来源: https://iotsmart.blog.csdn.net/article/details/127863720