Arduino红外循迹小车代码笔记和常见问题解决

您所在的位置:网站首页 红外线遥控器的灯不亮怎么办 Arduino红外循迹小车代码笔记和常见问题解决

Arduino红外循迹小车代码笔记和常见问题解决

2024-07-12 12:15| 来源: 网络整理| 查看: 265

本人刚接触Arduino不久,此代码用于参加校内的比赛,采用是4个红外传感器来检测小车是否压倒黑线,小车是有两个电机,也就是两个由电机控制的大轮,和一个可以转动的小轮用来控制方向。

在烧写小车代码之前,需要确保Arduino的配置正确,选择正确的开发板端口

并且根据实际硬件的不同来连接小车的线路。

在我们实际小车在简易路线(没有坡度,障碍等因素影响)运行的过程当中呢,我们所需要面对的情况有直线、十字路口、小幅度弯道、大幅度弯道四种常见情况,为了更好的应对这几种情况,传感器的数量多当然要更加有优势。

这里四个红外传感器,也就是我们的循迹模块的情况(1为检测到黑线)如下:

基本情况:

1.小车红外向前方向,从左往右依次是1~4: 2.小车放置赛道的时候需要将黑线最好放置在2,3传感器之间

3.当数值为1时,表示检测到了黑线

直行:当我们小车没有传感器检测到黑线时,则为一般直行情况

           当小车四个传感器全部检测到黑线时,表示遇到十字路口,依旧直行

传感器1传感器2传感器3传感器4情况0000直行1111直行

大幅度转弯:

因为我们默认小车上赛道的摆放方式是3,4传感器位于黑色赛道的两边,

当只有最外侧的1或4传感器检测到黑线的时候,就表明我们已经严重偏离了赛道,需要进行大幅度的矫正

当左侧或者右侧两个传感器都检测到黑线的时候,表示我们的小车遇到了转弯幅度更为大的弯道甚至是直角弯,这里同样需要进行大幅度转弯,甚至比上面的情况转弯幅度更大。因为在实际的调试过程当中,我发现,如何小车的转弯速度不够快,同样也会导致左侧或右侧两个传感器同时检测到黑线的情况,所以这样写也更为保险一些。

传感器1传感器2传感器3传感器4情况1000大幅度左转0001大幅度右转1100大幅度左转0011大幅度右转

小幅度转弯:当内侧传感器检测到黑线时,表示我们的小车轻微偏离轨道,则选择小幅度的进行矫正即可

传感器1传感器2传感器3传感器4情况0100小幅度左转0010小幅度右转

代码片段:

引脚定义片段,这里的引脚定义需要根据实际的板子的型号不同进行选择,我这里3,5,6,9引脚是带有~号样式的引脚,也就是可以使用PWM调速的引脚,这里只对PWM进行简单的使用说明,PWM的范围为0~255,数值越大电机转速越快。

以下为电机引脚的定义:

// 电机引脚定义 int LeftMotorGo = 3; // 左电机前进 (IN1) int LeftMotorBack = 5; // 左电机后退 (IN2) int RightMotorGo = 6; // 右电机前进 (IN3) int RightMotorBack = 9; // 右电机后退 (IN4)

和电机相同,红外线传感器也需要在Arduino中进行定义说明:

// 红外传感器引脚定义 const int Sensor1 = 4; // 第一个红外传感器 const int Sensor2 = 7; // 第二个红外传感器 const int Sensor3 = 8; // 第三个红外传感器 const int Sensor4 = 12; // 第四个红外传感器

那定义完我们的引脚之后还要进,行其他的操作,分为两个部分一个是void setup(),其另一个则是void loop()

在Arduino编程中,void setup() 用于初始化程序所需的设置和配置。它是Arduino程序的一部分,会在程序开始执行时自动调用。

在 void setup() 函数中,可以设置引脚的模式(如输入或输出),在下面的示例中,void setup() 函数执行以下操作:

配置电机引脚:通过调用 pinMode() 函数,将电机引脚(LeftMotorGo, LeftMotorBack, RightMotorGo, RightMotorBack) 设置为输出模式,用于控制电机的前进和后退。配置红外传感器引脚:通过调用 pinMode() 函数,将红外传感器引脚(Sensor1, Sensor2, Sensor3, Sensor4) 设置为输入模式,用于接收来自传感器的信号。

这两个函数有一个最基本的区别就是,void setup() 函数只在程序开始时执行一次, void loop() 函数在循环中执行代码。

示例代码:

void setup() { // 设置电机引脚为输出 pinMode(LeftMotorGo, OUTPUT); pinMode(LeftMotorBack, OUTPUT); pinMode(RightMotorGo, OUTPUT); pinMode(RightMotorBack, OUTPUT); // 设置红外传感器引脚为输入 pinMode(Sensor1, INPUT); pinMode(Sensor2, INPUT); pinMode(Sensor3, INPUT); pinMode(Sensor4, INPUT); }

在定义完之后,我们就来谈谈如何来实际控制我们小车电机的转速,这里我们引入另一个函数, analogWrite(),通过这个函数我们可以轻松的控制脉冲宽度调制 (PWM) 的方式输出模拟信号,从而来实现控制小车电机的转速。同样我们为了代码看起来更加简洁我们定义一个void 类型的函数以便于后面更加简单直观的控制我们的小车。

void Motor_Speed(int Left1_Speed, int Left2_Speed, int Right1_Speed, int Right2_Speed) { analogWrite(LeftMotorGo, Left1_Speed); analogWrite(LeftMotorBack, Left2_Speed); analogWrite(RightMotorGo, Right1_Speed); analogWrite(RightMotorBack, Right2_Speed); }

这个函数接收四个数值,分别对应四个速度,我们使用 analogWrite函数将接收的速度(PWM)传输到LeftMotorGo等四个变量上去。

在完成这一步的工作之后,我们就要进入我们的void loop() 函数当中去,让我们的小车开始实现循迹的功能:

那么在这里先简单介绍一下小车实现转弯的几种方式吧

1.正转+停转

2.正转+反转

3.停转+反转

一般就是这几种方式,我所选择的是2.正转+反转,因为我在调试的过程中发现,这种转弯方式更加的快速,对与轨道的吸附能力更强,冲出的情况较少。

以下为示例代码:

void loop() { //读取红外传感器的值 int sensorValue1 = digitalRead(Sensor1); int sensorValue2 = digitalRead(Sensor2); int sensorValue3 = digitalRead(Sensor3); int sensorValue4 = digitalRead(Sensor4); //根据红外传感器的值控制小车的运动 if (sensorValue1 == 0 && sensorValue2 == 1 && sensorValue3 == 0 && sensorValue4 == 0) { //轻微偏离轨道,差速 Motor_Speed(85, 0, 255, 0); //delay(25); //延迟一段时间,调整转弯幅度 } else if(sensorValue1 == 0 && sensorValue2 == 0 && sensorValue3 == 1 && sensorValue4 == 0) { //轻微偏离轨道,差速 Motor_Speed(240, 0, 85, 0); //delay(25); //延迟一段时间,调整转弯幅度 } else if(sensorValue1 == 1 && sensorValue2 == 0 && sensorValue3 == 0 && sensorValue4 == 0) { //严重偏离轨道,反转 Motor_Speed(0, 155, 255, 0); //delay(75); //延迟一段时间,调整转弯幅度 } else if(sensorValue1 == 0 && sensorValue2 == 0 && sensorValue3 == 0 && sensorValue4 == 1) { //严重偏离轨道,反转 Motor_Speed(255, 0, 0, 155); //delay(75); //延迟一段时间,调整转弯幅度 } else if(sensorValue1 == 1 && sensorValue2 == 1 && sensorValue3 == 0 && sensorValue4 == 0) { //直角转弯,更大的转弯幅度 Motor_Speed(0, 245, 255, 0); delay(40); //延迟一段时间,调整转弯幅度 } else if(sensorValue1 == 0 && sensorValue2 == 0 && sensorValue3 == 1 && sensorValue4 == 1) { //直角转弯,更大的转弯幅度 Motor_Speed(250, 0, 0, 255); delay(40); //延迟一段时间,调整转弯幅度 } else { //除了左右转,就只剩下直走 Motor_Speed(240, 0, 255, 0); } }

上面这一段代码并不复杂我们先对四个红外传感器进行了初始化

int sensorValue1 = digitalRead(Sensor1); int sensorValue2 = digitalRead(Sensor2); int sensorValue3 = digitalRead(Sensor3); int sensorValue4 = digitalRead(Sensor4);

然后使用了if(){}和else if(){}来实现小车循迹不同情况的判断,判断条件上述表格已经写出。在注释里,你会发现我有delay()函数,这个函数的作用是加一个延时,让小车在执行动作后停顿一下,具体时间具体设置,如果需要可以根据实际比赛情况进行调整。

在else条件当中,我将其他情况设置为了直走。

到此为止就是全部代码的展示,我也会在结尾附上全部的代码,在实际调试的过程中同样也会遇到很多实际的问题,这里我只说明一些我在调试的时候所遇到的问题,光是使用代码让小车直接实现良好的循迹当然不显示,想要有一个良好的循迹效果需要大家根据实际情况进行反复的调试,这个过程也相当有意思。

1.当你发现下车在经过黑线的时候红外传感器并没有反应,则需要调整红外传感器的灵敏度,一般在红外传感器上都会有一个类似与螺丝的地方,旋动它就可以调整灵敏度。

2.当你发现小车在拐弯过程中,小车检测到了黑线(红外指示灯闪烁)但是并未进行转弯操作,这种就是冲出现象,是小车的转弯力度太小了,小车还没来的及转弯就已经冲出去了。解决这个有两种方法:一是调大转弯差速,二是降低小车行驶速度。

3.小车正常直行无问题,但内侧接触到黑线之后,小车开始剧烈摆动,频繁接触到黑线,甚至冲出赛道。这种情况就是小幅度转弯时候的差速过于大,让小车转弯太过导致的,解决方法就是调小差速喽。

如果还有其余问题的话也欢迎积极交流分享,我暂时想到的问题就这么多。

小白第一次写博客,有什么写的不对,不好的地方欢迎大家指出,我虚心求教嘿嘿!

完整代码展示:

// 电机引脚定义 int LeftMotorGo = 3; // 左电机前进 (IN1) int LeftMotorBack = 5; // 左电机后退 (IN2) int RightMotorGo = 6; // 右电机前进 (IN3) int RightMotorBack = 9; // 右电机后退 (IN4) // 红外传感器引脚定义 const int Sensor1 = 4; // 第一个红外传感器 const int Sensor2 = 7; // 第二个红外传感器 const int Sensor3 = 8; // 第三个红外传感器 const int Sensor4 = 12; // 第四个红外传感器 void setup() { // 设置电机引脚为输出 pinMode(LeftMotorGo, OUTPUT); pinMode(LeftMotorBack, OUTPUT); pinMode(RightMotorGo, OUTPUT); pinMode(RightMotorBack, OUTPUT); // 设置红外传感器引脚为输入 pinMode(Sensor1, INPUT); pinMode(Sensor2, INPUT); pinMode(Sensor3, INPUT); pinMode(Sensor4, INPUT); } void Motor_Speed(int Left1_Speed, int Left2_Speed, int Right1_Speed, int Right2_Speed) { analogWrite(LeftMotorGo, Left1_Speed); analogWrite(LeftMotorBack, Left2_Speed); analogWrite(RightMotorGo, Right1_Speed); analogWrite(RightMotorBack, Right2_Speed); } void loop() { //读取红外传感器的值 int sensorValue1 = digitalRead(Sensor1); int sensorValue2 = digitalRead(Sensor2); int sensorValue3 = digitalRead(Sensor3); int sensorValue4 = digitalRead(Sensor4); //根据红外传感器的值控制小车的运动 if (sensorValue1 == 0 && sensorValue2 == 1 && sensorValue3 == 0 && sensorValue4 == 0) { //轻微偏离轨道,差速 Motor_Speed(85, 0, 255, 0); //delay(25); //延迟一段时间,调整转弯幅度 } else if(sensorValue1 == 0 && sensorValue2 == 0 && sensorValue3 == 1 && sensorValue4 == 0) { //轻微偏离轨道,差速 Motor_Speed(240, 0, 85, 0); //delay(25); //延迟一段时间,调整转弯幅度 } else if(sensorValue1 == 1 && sensorValue2 == 0 && sensorValue3 == 0 && sensorValue4 == 0) { //严重偏离轨道,反转 Motor_Speed(0, 155, 255, 0); //delay(75); //延迟一段时间,调整转弯幅度 } else if(sensorValue1 == 0 && sensorValue2 == 0 && sensorValue3 == 0 && sensorValue4 == 1) { //严重偏离轨道,反转 Motor_Speed(255, 0, 0, 155); //delay(75); //延迟一段时间,调整转弯幅度 } else if(sensorValue1 == 1 && sensorValue2 == 1 && sensorValue3 == 0 && sensorValue4 == 0) { //直角转弯,更大的转弯幅度 Motor_Speed(0, 245, 255, 0); delay(40); //延迟一段时间,调整转弯幅度 } else if(sensorValue1 == 0 && sensorValue2 == 0 && sensorValue3 == 1 && sensorValue4 == 1) { //直角转弯,更大的转弯幅度 Motor_Speed(250, 0, 0, 255); delay(40); //延迟一段时间,调整转弯幅度 } else { //除了左右转,就只剩下直走 Motor_Speed(240, 0, 255, 0); } }



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3