基于Arduino的红外遥控智能小车软件实现

一、使用库函数详解

  • 使用IRremote.h库,该库为支持Arduino红外线通信的函数库,用于传送和接收红外线信号。该函数库可以使用Arduion UNO板的任意数字引脚作为接收端口。
  • 每家厂商都有自己专用的红外线通信协议(protocol),IRremote.h函数库支持多种通信协议,如:NEC、Philips RC5、Philips RC6、SONY等,如果遇到不文持的通信协议,就返回UNKNOWN 编码类型。另外,每个键都有独特的代码,通常是12-32个位。按住按键不放时,不同厂商会有不同的重复代码,有些是传送相同的按键代码,有些则是传送特殊的重复代码。

1.IRecv()函数

  • 函数作用:创建一个红外线接收对象,并且用来接收红外线对象,名称可以由用用户自定义。
  • 参数:receivePin必须设置,用来设置 Arduino UNO板接收红外线信号的数字引脚。
  • 返回值:无。
  • 例子:IRrecv irrecv(2) //创建 irrecv对象,数字引脚2为红外接收端口。

2.enablePin()函数

  • 函数作用:启用红外线接收,即开启红外线的接收过程,每隔50ms 会产生一次定时器中断,用来检测红外线的接收状态。
  • 参数:无。
  • 返回值:无。
  • 例子:irrecv.enablePin() //启用红外线接收

3.decode()函数

  • 函数作用:decode()函数的作用是接收并解码红外线信号。
    必须使用数据类型decode_results来定义一个接收信号的存储地址,例如:
    decode_results results。如果接收到红外线信号,就返回true,将信号解码后再存储在results变量中;如果没有红外线信号,就返回false。所返回的红外线信号包含解码类型decode_type和按键代码 value等。
  • 参数:decode_results。
  • 返回值:bool。
  • 例子:irrecv.decode(&results) //接收并解码红外线信号

4.resume()函数

  • 函数作用:在使用 decode()函数接收完红外线信号后,必须使用resume()函数来重置IR红外接收器,才能再接收另一个红外线信号。
  • 参数:无。
  • 返回值:无。
  • 例子:irrecv.resume() //重置 IR 接收器

二、软件开发环境

1. 函数库下载

  • IRremote.h函数库可以到官方网址https://www.pjrc.com/teensy/下载。
  • 也可直接下载本人上传的资源(亲测好使!):
    IRremote 2.8.0版本下载链接: https://download.csdn.net/download/weixin_42255385/89885768?spm=1001.2014.3001.5503
  • 注意:如果使用高版本的IRremote函数库,可能会出现只能接收一次红外信号或者无法接受红外信号问题,建议使用上述低版本2.8.0函数库。

2.函数库安装

在这里插入图片描述

1)打开Arduino IDE软件,依次点击“项目”->“导入库”->“添加.ZIP库”。

在这里插入图片描述

2)选中下载的Arduino-IRemote-2.8.0.zip文件,点击“打开”按钮,Arduino IDE会自动将压缩包解压并安装到/libraries文件夹中。

三、红外远程遥控智能车实现源码

#include<IRremote.h>
int RECV_PIN = 2;//红外信号接收端口
IRrecv irrecv(RECV_PIN);
decode_results results;
long FORWARD=0xFF18E7;//前进代码
long BACK=0xFF4AB5;//后退代码
long RIGHT=0xFF5AA5;//右转代码
long LEFT=0xFF10EF;//左转代码
long PAUSE=0xFF38C7;//停止代码

//右电机控制
#define ENA 6
#define inPinA1 7
#define inPinA2 8
//左电机控制
#define ENB 5
#define inPinB1 12
#define inPinB2 13

//由于硬件原因导致左右电机转速不同,需根据实际情况进行小车直线行驶调节,确定左右电机速度
const int speedA = 115;//右电机速度
const int speedB = 128;//左电机速度
// const int speedA = 80;//右电机 慢速
// const int speedB = 93;//左电机 慢速

void setup() {
    
    
  // put your setup code here, to run once:
  Serial.begin(9600);
  irrecv.enableIRIn();
  pinMode(RECV_PIN, INPUT);

  pinMode(ENA, OUTPUT);
  pinMode(inPinA1,OUTPUT);
  pinMode(inPinA2,OUTPUT);
  
  pinMode(ENB,OUTPUT);
  pinMode(inPinB1,OUTPUT);
  pinMode(inPinB2,OUTPUT);
}

void loop() {
    
    
  // put your main code here, to run repeatedly:
  if(irrecv.decode(&results))
  {
    
    
    irrecv.resume();//准备接收下一个信号
    long resultValue = results.value;
    if(resultValue ==  FORWARD)
    {
    
    
      //小车前进
      Serial.print("forward: ");
      Serial.println(results.value,HEX);
      forwardPwm(speedA, speedB);
    }
    else if(resultValue == BACK)
    {
    
    
      //小车后退
      Serial.print("back: ");
      Serial.println(results.value,HEX);
      backwardPwm(speedA,speedB);
    } 
    else if(resultValue == RIGHT)
    {
    
    
      //小车右转
      Serial.print("right: ");
      Serial.println(results.value,HEX);
      forwardRight(speedB);
    } 
    else if(resultValue == LEFT)
    {
    
    
      //小车左转
      Serial.print("left: ");
      Serial.println(results.value,HEX);
      forwardLeft(speedA);
    } 
    else if(resultValue == PAUSE)
    {
    
    
      //小车停止
      Serial.print("pause: ");
      Serial.println(results.value,HEX);
      stop();
    }
  }
}
//PWM调节小车前进速度
void forwardPwm(int valueA,int valueB)
{
    
    
  forwardPwmA(valueA);
  forwardPwmB(valueB);
}
//PWM调节右电机正转
void forwardPwmA(int value)
{
    
    
  analogWrite(ENA, value);
  digitalWrite(inPinA1,LOW);
  digitalWrite(inPinA2,HIGH);
}
//PWM调节左电机正转
void forwardPwmB(int value)
{
    
    
  analogWrite(ENB, value);
  digitalWrite(inPinB1,LOW);
  digitalWrite(inPinB2,HIGH);
}
//电机停止
void stop()
{
    
    
  stopA();
  stopB();  
}
//右电机停止
void stopA()
{
    
    
  analogWrite(ENA, HIGH);
  digitalWrite(inPinA1,LOW);
  digitalWrite(inPinA2,LOW);
}
//左电机停止
void stopB()
{
    
    
  analogWrite(ENB, HIGH);
  digitalWrite(inPinB1,LOW);
  digitalWrite(inPinB2,LOW);
}

//value:0~255
//PWM调节小车后退速度
void backwardPwm(int valueA,int valueB)
{
    
    
  backwardPwmA(valueA);
  backwardPwmB(valueB);
}
//PWM调节右电机反转
void backwardPwmA(int value)
{
    
    
  analogWrite(ENA, value);
  digitalWrite(inPinA1, HIGH);
  digitalWrite(inPinA2, LOW);
}
//PWM调节左电机反转
void backwardPwmB(int value)
{
    
    
  analogWrite(ENB, value);
  digitalWrite(inPinB1, HIGH);
  digitalWrite(inPinB2, LOW);
}
//小车左转
void forwardLeft(int value)
{
    
    
  stopB();
  forwardPwmA(value);
}
//小车右转
void forwardRight(int value)
{
    
    
  stopA();
  forwardPwmB(value);
}

四、运行效果

分别按下红外遥控的数字键2(前进)、4(左转)、6(右转)、8(后退)、5(暂停)五个按键,智能小车根据远程遥控指令进行不同方向的运动。

五. 说明:

1) 红外遥控原理参考本专栏《基于Arduino的红外遥控智能小车实现方法》。
2)L298N电机驱动原理参考本专栏《基于Arduino的L298N电机驱动模块使用》。