2014-6-5 17:40:23 [显示全部楼层]
83599浏览
查看: 83599|回复: 37

[入门教程] Arduino教程14--红外遥控灯「DFR0100 」

[复制链接]
【本篇课程内容于 2024年11月14日更新】
>本系教程配套硬件套件:【新版】Arduino入门套件 DFR0100

这节我们会接触一个新的元件——红外接收管。所谓红外接收管,也就是接收红外光的电子器件。红外接收管,看着离我们很遥远的感觉!其实不然,它就在我们身边。比如我们的电视机,空调这些家电,其实它们都需要用到红外接收管。我们都知道遥控器发射出来的都是红外光,电视机上势必要有红外接收管,才能接收到遥控器发过来的红外信号。
我们这次就用红外接收管做个遥控灯,通过遥控器的红色电源键来控制LED的开关。在开始遥控灯之前,我们先来个预热实验,通过串口来了解下如何使用红外接收管和遥控器。

元件清单
Arduino教程14--红外遥控灯「DFR0100 」图1

硬件连接

红外接收模块只需要连接三根线就可以了,注意一下正负就可以了(图中表明部分)。红外接收管Vout输出接到数字引脚11。在这个基础上,加一个LED和电阻,LED使用的是数字引脚10。红外接收管仍然接的是数字引脚11(LED灯在该项目的后半部分会用上)。

Arduino教程14--红外遥控灯「DFR0100 」图2
图 1 红外遥控接收器连线图

代码示例
对于遥控红外模块,我们提供现成的IRremote库,直接在Arduino IDE中安装IRremote库(需使用该库的2.6.0版本,如图2),输入样例代码1运行即可。如果还是不是很明白如何加载库,可以回看一下项目【炫彩LED】课后作业部分,对如何加载库做了详细说明。

Arduino教程14--红外遥控灯「DFR0100 」图3
图2

样例代码1:

  1. //项目 - 红外遥控灯测试代码
  2. #include <IRremote.h>//调用IRremote.h库
  3. int RECV_PIN = 11;//定义RECV_PIN变量为11
  4. IRrecv irrecv(RECV_PIN);//设置RECV_PIN(也就是11引脚)为红外接收端
  5. decode_results results;//定义results变量为红外结果存放位置
  6. void setup()
  7. {
  8.   Serial.begin(9600); //串口波特率设为9600
  9.   irrecv.enableIRIn(); //启动红外解码
  10. }
  11. void loop() {
  12.   //是否接收到解码数据,把接收到的数据存储在变量results中
  13.   if (irrecv.decode(&results)) {
  14.     //接收到的数据以16进制的方式在串口输出
  15.     Serial.println(results.value, HEX);
  16.     irrecv.resume(); // 继续等待接收下一组信号
  17.   }
  18. }
复制代码

下载完成后,打开Arduino IDE的串口监视器(Serial Monitor),设置波特率为9600,与代码中Serial.begin(9600)相匹配。

Arduino教程14--红外遥控灯「DFR0100 」图4

Arduino教程14--红外遥控灯「DFR0100 」图5

设置完后,用Mini遥控器的按钮对着红外接收管的方向,任意按个按钮,我们都能在串口监视器上看到相对应的代码。如下图所示,按数字“0”,接收到对应16进制的代码是“FD30CF”。每个按钮都有一个特定的16进制的代码。

Arduino教程14--红外遥控灯「DFR0100 」图6

如果长按一个键不放就会出现“FFFFFFFF”。
Arduino教程14--红外遥控灯「DFR0100 」图7

在串口中,正确接收的话,应该收到以FD-开头的六位数。如果遥控器没有对准红外接收管的话,可能会接收到错误的代码。如下图所示:

Arduino教程14--红外遥控灯「DFR0100 」图8

上面这段代码我们没有像以前一样一步一步做详细说明,原因就是由于红外解码较为复杂,所幸的是,高手把这些难的工作已经做好了,提供给我们这个IRremote库,我们只需要会用就可以了,先不需要弄明白函数内部如何工作的。要用的时候,把代码原样搬过来就好了。照猫画虎,先用起来再说~
预热完之后,我们言归正传,开始制作遥控灯。

这里不建议一步一步输入代码,可以在原有的代码上进行修改,观察下相对样例代码1增加了哪些内容。

样例代码2:

  1. #include <IRremote.h>           //调用IRremote.h库
  2. int RECV_PIN = 11;              //定义RECV_PIN变量为11   
  3. int ledPin = 10;                // LED – digital 10
  4. boolean ledState = LOW;         // ledstate用来存储LED的状态
  5. IRrecv irrecv(RECV_PIN);        
  6. //设置RECV_PIN(也就是11引脚)为红外接收端
  7. decode_results results;         //定义results变量为红外结果存放位置
  8. void setup(){
  9.   Serial.begin(9600);          //串口波特率设为9600
  10.   irrecv.enableIRIn();          //启动红外解码
  11.   pinMode(ledPin,OUTPUT);       // 设置LED为输出状态
  12. }
  13. void loop() {
  14.   //是否接收到解码数据,把接收到的数据存储在变量results中
  15.   if (irrecv.decode(&results)) {  
  16.        //接收到的数据以16进制的方式在串口输出   
  17.       Serial.println(results.value, HEX);
  18.    
  19.       //一旦接收到电源键的代码, LED翻转状态,HIGH变LOW,或者LOW变HIGH
  20.       if(results.value == 0xFD00FF){
  21.                ledState = !ledState;             //取反      
  22.                digitalWrite(ledPin,ledState);
  23. //改变LED相应状态        
  24.            }     
  25.    irrecv.resume();  // 继续等待接收下一组信号
  26.    }
  27. }
复制代码

代码回顾

程序一开始还是对红外接收管的一些常规定义,按原样搬过来就可以了。

  1. #include <IRremote.h>         //调用IRremote.h库
  2. int RECV_PIN = 11;            //定义RECV_PIN变量为11   
  3. int ledPin = 10;              // LED – digital 10
  4. boolean ledState = LOW;       // ledstate用来存储LED的状态
  5. IRrecv irrecv(RECV_PIN);
  6. //设置RECV_PIN(也就是11引脚)为红外接收端
  7. decode_results results;       //定义results变量为红外结果存放位置
复制代码

在这里,我们多定义了一个变量ledState,通过名字应该就可以看出来含义了,用来存储LED的状态的,由于LED状态就两种(1或者0),所以我们使用boolean变量类型,(可回看项目三中,表3-1列举出的数据类型)。

setup()函数中,对使用串口,启动红外解码,数字引脚模式进行设置。

到了主函数loop(),一开始还是先判断是否接收到红外码,并把接收到的数据存储在变量results中。

if (irrecv.decode(&results))

一旦接收到数据后,程序就要做两件事。第一件事,判断是否接收到了电源键的红外码。

if(results.value == 0xFD00FF)

第二件事,就是让LED改变状态。

ledState = !ledState;             //取反      
digitalWrite(ledPin,ledState);    //改变LED相应状态

这里可能对“!”比较陌生,“!”是一个逻辑非的符号,“取反”的意思。我们知道“!=”代表的是不等于的意思,也就是相反。这里可以类推为,!ledState是ledState相反的一个状态。“!”只能用于只有两种状态的变量中,也就是boolean型变量。
最后,继续等待下一组信号。

irrecv.resume();


课后练习

1、通过这个遥控项目,再结合项目【自制风扇】的风扇,能不能再给遥控器增加一个功能,既可控灯,还可控风扇。
2、DIY一个你的遥控作品吧!比如简单的会动的小人,结合我们前面的舵机,通过遥控器上不同的按键,让舵机转动不同的角度,感觉随你的控制转动,发挥你的想象做出更多Arduino作品吧!



DFRobot版权所有,欢迎转载。
转载请务必标注来源: DF创客社区+作者姓名+原文网址。

Shuuei  高级技师

发表于 2019-4-12 08:13:40

额,建议上传bz或gz的压缩包。rar类型的包Linux默认不支持,度娘搜索适用树莓派上的rar软件下载安装后均出现问题,确认非位数的问题。下载7z后解压rar也出现问题,显示文件解压错误。

后面是我是在windows解压后用filezila传输到树莓派上的,可能有些麻烦,如果使用树莓派的同学遇到相同的情况可以参照。关键词:ssh, ifconfig, sftp, filezila


回复

使用道具 举报

电工狸的折耳猫  见习技师

发表于 2022-7-1 12:37:47

if(results.value == codes//该数组用来存放红外遥控器发出的红外码[i][i][i]&& i <= 9){
这一行报错:
exit status 1
invalid types 'long int[int]' for array subscript
咋整呢?
回复

使用道具 举报

Melody-王俊皓  见习技师

发表于 2022-8-24 16:31:27

电工狸的折耳猫 发表于 2022-7-1 12:37
if(results.value == codes//该数组用来存放红外遥控器发出的红外码&& i

我也是这样的问题,咋解决
回复

使用道具 举报

yoyojacky  初级技匠

发表于 2014-11-6 00:58:25

学习了。
回复

使用道具 举报

Jane  高级技匠
 楼主|

发表于 2014-11-7 09:47:52


:victory:
回复

使用道具 举报

a82107335  学徒

发表于 2015-2-9 13:52:42

回复

使用道具 举报

iatgm  见习技师

发表于 2015-5-28 22:54:06

本帖最后由 iatgm 于 2015-5-28 23:15 编辑

我遥控器对准红外接收管,也接收到错误的代码,请问一下,是怎么回事。
回复

使用道具 举报

Jane  高级技匠
 楼主|

发表于 2015-6-1 18:03:46

iatgm 发表于 2015-5-28 22:54
我遥控器对准红外接收管,也接收到错误的代码,请问一下,是怎么回事。
...

接收到错误信号的概率大吗?
回复

使用道具 举报

siska  初级技师

发表于 2015-7-17 16:11:25

构建选项已变更,全部重新构建

D:\Arduino\libraries\RobotIRremote\src\IRremoteTools.cpp:5:16: error: 'TKD2' was not declared in this scope
int RECV_PIN = TKD2; // the pin the IR receiver is connected to
                ^
编译有误。

  报告将会包含更多的信息
  "在编译时,输出详细信息"
  在 文件>首选项 中启用

这是怎么回事,代码跟LZ你的一模一样:(
回复

使用道具 举报

Jane  高级技匠
 楼主|

发表于 2015-7-17 18:19:57

siska 发表于 2015-7-17 16:11
构建选项已变更,全部重新构建

D:\Arduino\libraries\RobotIRremote\src\IRremoteTools.cpp:5:16: error:  ...

你是不是没有加载库呀?
回复

使用道具 举报

siska  初级技师

发表于 2015-7-17 23:01:14

Jane 发表于 2015-7-17 18:19
你是不是没有加载库呀?

是啊是啊,我太马虎了:loveliness:
回复

使用道具 举报

Jane  高级技匠
 楼主|

发表于 2015-7-30 11:14:44

siska 发表于 2015-7-17 23:01
是啊是啊,我太马虎了

下回就攒经验了~
回复

使用道具 举报

EricKong  学徒

发表于 2015-7-30 19:02:11

210的入门set里的IR错误率实在太高了。。。。简直不忍直视啊!!!!!!
回复

使用道具 举报

EricKong  学徒

发表于 2015-7-30 19:02:30

210的入门set里的IR错误率实在太高了。。。。简直不忍直视啊!!!!!!
回复

使用道具 举报

EricKong  学徒

发表于 2015-7-31 10:46:24

我是来认错的,是我代码的问题,与delay有关,改成如下就没问题。
   
//是否接收到解码数据,把接收到的数据存储在变量results_cur中
    if (irrecv.decode(&results_cur))
    {
        //接收到的数据以16进制的方式在串口输出
        Serial.println(results_cur.value, HEX);

        //用IR控制伺服电机
        if(results_cur.value != results_pre.value)
        {
          process_servo(results_cur.value); // 根据IR输入控制伺服电机旋转角度
          delay(10);                        // 等待伺服电机旋转角度
          results_pre = results_cur;      
        }
        
        irrecv.resume();                    // 继续等待接收下一组信号
    }
回复

使用道具 举报

Jane  高级技匠
 楼主|

发表于 2015-7-31 15:03:15

EricKong 发表于 2015-7-31 10:46
我是来认错的,是我代码的问题,与delay有关,改成如下就没问题。

哈哈哈~没事儿
回复

使用道具 举报

diaosiki  见习技师

发表于 2016-1-5 17:03:19

成功接收到红外信号如下图:
Arduino教程14--红外遥控灯「DFR0100 」图1
然而过程中仍存在疑问:在将IRremote库加载后,编译虽然成功,但是出现了这样的告警字样:

IRremote.h" 对应多个库
已使用: /Users/diaosiji/Documents/Arduino.app/Contents/Java/libraries/IRremote
未使用:/Users/diaosiji/Documents/Arduino.app/Contents/Java/libraries/RobotIRremote

请问这个问题是为什么,如何消除?
回复

使用道具 举报

Jane  高级技匠
 楼主|

发表于 2016-1-13 18:39:46

diaosiki 发表于 2016-1-5 17:03
成功接收到红外信号如下图:

然而过程中仍存在疑问:在将IRremote库加载后,编译虽然成功,但是出现了这样 ...

那是不是库没有加载对?
回复

使用道具 举报

diaosiki  见习技师

发表于 2016-1-14 16:14:47

Jane 发表于 2016-1-13 18:39
那是不是库没有加载对?

已经解决。
回复

使用道具 举报

木龙小驴  见习技师

发表于 2016-3-22 09:21:22

求大神帮助啊
我已经删掉库里带的robotremot还有irremotetool的相关文件,也能编译通过,但是遥控器什么的木有反应,用手碰一碰会打印一些数字,遥控器不好使。
是不是传感器的问题?还是需要换遥控器?
回复

使用道具 举报

ljs2016cn  学徒

发表于 2016-10-24 10:34:14

怎样加载库
回复

使用道具 举报

Jane  高级技匠
 楼主|

发表于 2016-11-1 10:32:46

回复

使用道具 举报

david.ding  见习技师

发表于 2017-2-3 13:27:35

新手学习

赞一下
回复

使用道具 举报

12下一页
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail