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

本人刚接触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() 函数执行以下操作:

  1. 配置电机引脚:通过调用 pinMode() 函数,将电机引脚(LeftMotorGoLeftMotorBackRightMotorGoRightMotorBack) 设置为输出模式,用于控制电机的前进和后退。
  2. 配置红外传感器引脚:通过调用 pinMode() 函数,将红外传感器引脚(Sensor1Sensor2Sensor3Sensor4) 设置为输入模式,用于接收来自传感器的信号。

这两个函数有一个最基本的区别就是,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);
  }
}

  • 26
    点赞
  • 127
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
Arduino红外循迹小车代码用于控制一个小车根据红外传感器检测到的路线进行自动行驶。以下是一段简单的代码示例: ``` // 引入红外传感器和电机驱动的库 #include <IRremote.h> #include <AFMotor.h> // 定义红外传感器引脚 #define IR_PIN 2 // 定义电机驱动引脚 AF_DCMotor motor1(1); AF_DCMotor motor2(2); // 实例化红外传感器对象 IRrecv irrecv(IR_PIN); // 定义追踪状态 int trackState = 0; void setup() { // 初始化红外传感器 irrecv.enableIRIn(); // 设置电机驱动速度 motor1.setSpeed(255); motor2.setSpeed(255); } void loop() { // 检测是否接收到红外信号 if (irrecv.decode()) { // 获取红外信号数据 decode_results results; int code = results.value; // 判断红外信号对应的动作 switch (code) { case 0xFF6897: // 表示小车需要前进 trackState = 1; break; case 0xFF9867: // 表示小车需要后退 trackState = 2; break; case 0xFFA25D: // 表示小车需要左转 trackState = 3; break; case 0xFFE21D: // 表示小车需要右转 trackState = 4; break; default: // 其他红外信号则停止小车 trackState = 0; break; } irrecv.resume(); } // 根据追踪状态控制小车行驶 switch (trackState) { case 1: // 前进 motor1.setSpeed(255); motor2.setSpeed(255); motor1.run(FORWARD); motor2.run(FORWARD); break; case 2: // 后退 motor1.setSpeed(255); motor2.setSpeed(255); motor1.run(BACKWARD); motor2.run(BACKWARD); break; case 3: // 左转 motor1.setSpeed(255); motor2.setSpeed(255); motor1.run(BACKWARD); motor2.run(FORWARD); break; case 4: // 右转 motor1.setSpeed(255); motor2.setSpeed(255); motor1.run(FORWARD); motor2.run(BACKWARD); break; default: // 停止 motor1.setSpeed(0); motor2.setSpeed(0); motor1.run(RELEASE); motor2.run(RELEASE); break; } } ``` 以上代码通过红外传感器接收红外信号,并根据不同的信号动作控制小车的运动。例如,当接收到红外信号0xFF6897时,代表小车需要前进,则设置追踪状态为1,小车则前进。根据不同的追踪状态,设置对应的电机驱动引脚的输出状态,从而控制小车的运动。当没有接收到红外信号时,小车停止运动。 请根据你的具体硬件和要求,对代码作出相应的调整和改进。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值