ArduinoUNO-IRremote 红外线接收模块使用(还没写完)
系列文章目录
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 系列文章目录
- 前言
- 一、基本介绍
- 二、硬件连接
- 1.红外接收模块
- 2.与Arduino UNO连线
- 三、软件调试
- 1.在ARDUINO IDE中安装IRremote库
- 2.部分类与函数介绍
- 2-1 IRrecv 类
- 2-1-1 构建 IRrecv 类
- 2-1-2 IRrecv::begin
- 2-1-3 IRrecv::enableIRIn
- 2-1-4 IRrecv::disableIRIn
- 2-1-5 IRrecv::decode
- 2-2 IRData类
- 2-2-1 protocol
- 2-2-2 address
- 2-2-3 command
- 2-2-4 numberOfBits
- 2-2-5 decodedRawData
- 2-3 decode_results类
- 3.按键编码获取程序
- 4.进一步开发
- 四、常见问题
- 1.接收到“FFFFFFFF”
- 声明
前言
提示:这里可以添加本文要记录的大概内容:
一、基本介绍
红外编码传输的本质是将已知信号进行数字编码、调制到红外光波段,再进行发送的信号传输方式。在接收端以同频进行解调,即可得到传输结果。常见的传输载波频率如38kHz。
被调制的已知信号可根据不同红外传输协议进行不同的定义和编码。如常见的NEC编码,其标准编码为4字节(32位),为1byte地址+1byte地址反码+1byte数据+1byte数据反码。
红外传输具有很多优势。首先,红外光为肉眼不可见光段,在使用时可以避免产生不必要的光束,不会影响人类正常生活。其本质与可见光LED相同,正常使用下也不会对人眼造成损伤。其次红外发光二极管制造简单,价格便宜,功耗极低。因此基于红外编码传输的遥控手段被广泛应用于许多消费电子产品中。
红外传输也具有劣势。由于太阳等因素,环境中本身存在一定红外光,若频率相近,会干扰红外遥控信号。且红外光穿透性差,几乎无穿墙能力。
红外传输的编码方式简单,易于实现“学习”功能。这同时也代表其安全性差,易被劫持。
参考来自:红外遥控原理及实现 [电子森林]
二、硬件连接
1.红外接收模块
本次使用的红外接收模块如下图所示。
前面银白色的是红外接收头,整个模块的引脚定义如下表所示:
左(-) | 中 | 右(S) |
---|---|---|
GND | VCC | 信号线 |
相同定义方式还适用于其他标有(S)与(-)的传感器模块。
2.与Arduino UNO连线
本红外模块需使用5V供电,连接至UNO板上对应位置的5V与GND即可。红外模块的信号线无特殊要求,连接至任一数字引脚即可,在本文中红外模块的信号线连接至2号管脚。
GND | VCC | 信号线 |
---|---|---|
GND | +5V | 2 |
三、软件调试
1.在ARDUINO IDE中安装IRremote库
如何安装库:
本文使用的是IRremote库,其包含了许多封装好的红外控制相关的功能函数,其包含了接收、发送、解码、编码等功能,对于AVR单片机、ESP系列、RP2040都有很好的支持。
开源库地址:https://github.com/Arduino-IRremote/Arduino-IRremote
函数文档地址:https://arduino-irremote.github.io/Arduino-IRremote/classIRrecv.html
Arduino库说明:https://www.arduino.cc/reference/en/libraries/irremote/
2.部分类与函数介绍
因为我本身也没有特别完整地了解这个IRremote函数库的全部,再加上本来我发文章就比较随意。这里就主要挑了接收过程中主要用到的类和函数,想看完整文档手册的点击上方函数文档连接即可。(讲道理我感觉这种开源的组件最重要的是要会用,也没必要全看下来)
2-1 IRrecv 类
首先是最重要的IRrecv
类,它主要用于接收红外的信号。
2-1-1 构建 IRrecv 类
定义 IRrecv 类的方式有三种:
IRrecv name();
//直接定义 说实话我也不太清楚怎么用IRrecv name(IR_Recv_Pin);
//带着接收引脚定义 IR_Recv_Pin:IR模块的信号引脚IRrecv name(IR_Recv_Pin,Feedback_LED_Pin);
//带着接收引脚和反馈灯 也不太清楚没怎么用过
常用的还是第二种,name就是这个类实例化的名字,自己任起即可。IR_Recv_Pin
是指IR模块的信号线所所接的引脚。
在本文中IR_Recv_Pin = 2
。
2-1-2 IRrecv::begin
这个函数是开始红外数据接收,其函数定义如下:
void IRrecv::begin
( uint8_t aReceivePin,bool aEnableLEDFeedback = false,uint8_t aFeedbackLEDPin = USE_DEFAULT_FEEDBACK_LED_PIN
)
//上面是参数
{setReceivePin(aReceivePin);#if !defined(NO_LED_FEEDBACK_CODE)bool tEnableLEDFeedback = DO_NOT_ENABLE_LED_FEEDBACK;if (aEnableLEDFeedback) {tEnableLEDFeedback = LED_FEEDBACK_ENABLED_FOR_RECEIVE;}setLEDFeedback(aFeedbackLEDPin, tEnableLEDFeedback);#else(void) aEnableLEDFeedback;(void) aFeedbackLEDPin;#endif// Set pin mode oncepinMode(irparams.IRReceivePin, INPUT);start();
}
参数1:aReceivePin
是IR模块的信号引脚,和前文的IR_Recv_Pin
意思相同。
参数2:aEnableLEDFeedback
是否启用反馈灯,缺省值为false。
参数3:aFeedbackLEDPin
反馈灯引脚号,缺省值的USE_DEFAULT_FEEDBACK_LED_PIN 默认为 0引脚 。
这个函数主要就是定义一遍引脚和要不要启动反馈灯,最后开始数据接收。个人感觉这个函数主要是为了给前面不带引脚直接定义的IRrecv 类确定引脚和开始接收的。那个反馈灯我没有用过,
使用的话就是:
name.begin();
//或
name.begin(IR_Recv_Pin,false); //不使用反馈灯
//或
name.begin(IR_Recv_Pin,true,13); //使用反馈灯 接在13号引脚上
name就是前面实例化类的那个name
但这不是唯一的启动数据接收方式,如果在前面定义的时候就已经指定好了红外接收引脚,也可以用下面这个函数启动数据接收。
2-1-3 IRrecv::enableIRIn
这个函数是使能IR数据接收,定义如下:
void IRrecv::enableIRIn()
{start();
}
与begin函数相比只保留了最后的start,所以如果之前确定好了使用引脚。就可以直接用这个函数也可以启动数据接收。
使用方式:
name.enableIRIn(); //启动红外接收
(小声bb:其实直接start就行但我不知道为什么好多例程里都用的enableIRIn这个函数,所以其实使用下面这么启动数据转换也是可以的)
name.start(); //启动红外接收
2-1-4 IRrecv::disableIRIn
这个函数是失能IR数据接收,与2-1-3函数相对应。通过该两者配合可以实现仅在特定条件下开启数据接收。
void IRrecv::disableIRIn()
{stop();
}
和2-1-3类似,里面也就是个stop所以理论上直接stop或者用end函数(里面也只有一个stop)也可以实现停止接收的效果。
使用方式:
name.disableIRIn(); //中止红外接收
//或
name.stop(); //中止红外接收
//或
name.end(); //中止红外接收
2-1-5 IRrecv::decode
这个函数是进行红外数据的解码,同名函数有两种定义,一种不带参数,一种带一个指针参数。带参数的为较老版本的IR解码函数。(在最新版本IRremote库中,作者已经强烈不推荐使用,但是目前网上很多教程仍用的旧版decode,我个人尝使用新旧版本效果上没有什么明显的区别)
定义如下:(整个函数太长了里面一堆各种解码的内容,有兴趣的自己去IRReceive.hpp头文件里面翻吧)
bool IRrecv::decode() //新版解码函数
bool IRrecv::decode (decode_results *aResults) //旧版解码函数
相同点是bool类型的返回值代表有没有接收到红外发射码并完成解码。true是完成!
不同之处在于旧版的decode需要我们先创建一个用于接收解码结果的decode_results
类型变量,然后在解码的时候作为参数传进去,解码结果就会在这个decode_results
类型变量里。
而新版函数方式则是,在IRrecv这个类(也就是前面定义为name的)中已定义了有一个IRData
类型的成员数据,用来储存解码结果,叫做decodedIRData。(通过name.decodedIRData
可以访问到这个数据成员)
新版decode会将接收到的数据直接转换完并存入decodedIRData
这个成员中。
总的来说就是,旧版用decode_results
类型储存解码结果,但需要在程序中提前定义,并通过指针传递参数。新版用IRData
类型储存解码结果,已包含在预先定义的IRrecv类中了,叫decodedIRData
,直接调用即可。
另外,decode_results
和IRdata
类型里的数据成员名还不太一样,后面会提到。
使用方式:
//旧版本decode (不推荐!)
decode_results resultname; //定义一个decode_results类型变量 最好是在全局里
name.decode(&resultname); //接收并解码 解码结果存入resultname
//新版本decode (推荐!)
name.decode() //接收并解码 解码结果存入name.decodedIRData
2-2 IRData类
这个类用于存储红外解码结果,可由解码器进行填充。数据成员可以被打印或其他函数调取。
我觉得的常用到的就是protocol
, address
,command
, numberOfBits
, decodedRawData
.
2-2-1 protocol
解码协议,这个通过decode函数会自动确认这部分红外协议的类型并且填充这个值。
通过name.decodedIRData.protocol
可以访问到该值。它是enum枚举类型。若通过打印函数得出枚举值后,可通过 编码枚举值 查看对应的编码类型。
2-2-2 address
解码出的地址值
通过name.decodedIRData.address
可以访问到该值
2-2-3 command
解码出的按键命令值
通过name.decodedIRData.command
可以访问到该值
2-2-4 numberOfBits
数据接收的位数
通过name.decodedIRData.numberOfBits
可以访问到该值
2-2-5 decodedRawData
32位的解码原始数据。
通过name.decodedIRData.decodedRawData
可以访问到该值
在NCE协议中按
8位按键值补码 8位按键值 8位地址补码 8位地址码 排列
为方便观察建议使用十六进制读取并显示
如IRCode: E718FF00
中
按键值就是0x18 地址值就是0x00
通过前文提到的address和command也可以分别读取到相应结果
2-3 decode_results类
这个类同样也用于存储红外解码结果,由旧版的decode命令进行填充。数据成员可以被打印或其他函数调取。
主要是,确实写不动了,里面常用的也就是value,这个值和 2-2 里面的decodedRawData
一样,只不过顺序相反了。在NEC红外协议下是,8位地址值 8位地址值补码 8位按键值 8位按键值补码。
其他的就看下面的这段吧,从库的头文件里摘出来的,讲了每一项的意义和与IRData的关系。
struct decode_results {decode_type_t decode_type; // deprecated, moved to decodedIRData.protocol ///< UNKNOWN, NEC, SONY, RC5, ...uint16_t address; uint32_t value; // deprecated, moved to decodedIRData.decodedRawData ///< Decoded value / command [max 32-bits]uint8_t bits; // deprecated, moved to decodedIRData.numberOfBits ///< Number of bits in decoded valueuint16_t magnitude; // deprecated, moved to decodedIRData.extra ///< Used by MagiQuest [16-bits]bool isRepeat; // deprecated, moved to decodedIRData.flags ///< True if repeat of value is detected// next 3 values are copies of irparams values - see IRremoteint.huint16_t *rawbuf; // deprecated, moved to decodedIRData.rawDataPtr->rawbuf ///< Raw intervals in 50uS ticksuint16_t rawlen; // deprecated, moved to decodedIRData.rawDataPtr->rawlen ///< Number of records in rawbufbool overflow; // deprecated, moved to decodedIRData.flags ///< true if IR raw code too long};
顺便学个词 deprecate v. 不推荐 反对
3.按键编码获取程序
4.进一步开发
四、常见问题
1.接收到“FFFFFFFF”
在NEC协议的遥控器下,当你摁住一个键时,遥控器不会重复发送编码结果,而是会发送FFFFFFFF
,也就是“重复码”。因此,接收RAW格式时会发现是FFFFFFFF。
若采用IRremote库带的解码,程序会正确识别重复码,并解析成上一次接收到正常编码结果。
声明
该文章是自己学习摸索过程中得出的一些结论,内容不一定百分之百正确,描述语言也不一定专业,若有错误请大佬评论区指正,谢谢!
ArduinoUNO-IRremote 红外线接收模块使用(还没写完)相关推荐
- 摩根斯丹利 上海java开发_美团上海Java实习(已offer)面经(还没写完,转载)...
实习简历投的晚,笔试四月初就完成,一直没有面试.可能原部门没有hc,期间还收到一次问我要不要转前端的电话,被我拒绝了.然后4月底收到美团金融的面试邀请. 第一面5.6(一个小时10分钟) 问的问题蛮多 ...
- 程序还没写完只能当然计算器用,先发过来用着后面的慢慢写
真的是没办法,只好先发上来用着,后面的要先处理事情,等处理完接着写!! http://files.cnblogs.com/mari/starco.rar 这个是地址!!! 转载于:https://ww ...
- 自定义view--仿照 体育app,股票,基金,电商,区块链APP 数据信息栏展示(还没写完)
我是个球迷,喜欢看各种篮球 足球比赛,所以手机里面也安装了各种体育类APP,之前就发现了一个有趣的自定义view,很多场景都能通用 比如: (虎扑)体育app,球队积分/比赛数据自定view 股票,基 ...
- {YiGeZiWoJianJie}个人简历(还没写完呢)
基 本 信 息 姓 名: -- 性 别: 男 出生日期: -- 身 高: 175厘米 住址: 许昌 证件号码: *************** 婚姻状况: 未婚 健康状况: 良好 学 历: 专科 ...
- 滴眼液的ph值与胶原纤维的粘结性(还没写完)
眼药水名称 ph值 新乐敦--复方门冬泛甘滴眼液[1] 6 乐敦莹--复方硫酸软骨素滴眼液[1] 7 闪亮--萘敏维滴眼液[1] 5.0 润洁--复方硫酸软骨素滴眼液[1] 6 珍视明--四味珍层冰硼 ...
- Rime在linux下面的安装-还没写完
最新的ubuntu下面的百度输入法和搜狗输入法都有bug,相关的开发团队都懒得处理. 没办法,只好尝试使用Rime https://zhuanlan.zhihu.com/p/268951436 --- ...
- 树莓派【树莓派关机命令,putty下载与远程控制树莓派,vnc控制树莓派(还没写完)】
一.树莓派关机命令 二.采用putty远程控制树莓派 (1)连线,将树莓派的网口与电脑的网口相连 (2)把电脑的网络共享给树莓派 (3)查找树莓派IP地址 (4)利用树莓派IP连接树莓派 1)在树莓派 ...
- 数据统计与分析基础实验三:常规数学统计计算(R语言,还没写完)
数据统计与分析基础实验三:常规数学统计计算 1.随机生成一个10x15的高斯矩阵,均值为自己学号后两位,方差为1.对该矩阵分别进行LU.QR.奇异值,并展示分解结果. LU QR 奇异值 2.利用软件 ...
- 今天写了老师布置的作业,还没写完 哇哇哇 是用递归方法求n阶勒让德多项式的值 题目就不写了【因为我也不知道怎么搞 哈哈哈哈哈】我用的是整形哈
直接上答案 #include <stdio.h> int p(int n,int x)//定义一个函数P {int a;if(n==0){return 1; //这两个if是先排除n=1和 ...
- 为什么word一页没写完再写就去下一页了
如下图,有时候word会出现上一页还没写完就自动跳到下一页的情况. 解决方法 1.选中下一页的段落,右键选择"段落": 2.将换行和分页设置中,"段中不分页"和 ...
最新文章
- 锐捷交换机配置snmp版本_snmp交换机配置
- java 格式匹配,java匹配电话格式的正则表达式
- 分享大厂分布式唯一ID设计方案,快来围观
- 机器人“铁手”可以保护工厂工人免受伤害
- C++智能指针简单介绍
- python if和while的区别_python基础--while循环和if判断、基本运算符
- WindowsPhone-GameBoy模拟器开发四--Gameboy显示系统分析
- git 可视化工具_Git的基本使用(二)
- Nebula3资源子系统
- “SCSA-S学习导图+”系列:Windows下的WEB系统环境搭建
- 计算机大型机小型机的缩写,计算机可被划分为3个基本类型大型机,小型机与微型机。.doc...
- python-静态网页爬取
- 硬盘分区-增加C盘容量教程
- opencv求矩阵的逆_使用OpenCV求模拟矩阵的逆矩阵
- C语言求字母的全部组合
- python 处理snp的vcf文件,统计snp在基因的intron、exon还是上游、下游还是不在基因及基因附近
- c语言编写消防车声音程序教程,51单片机蜂鸣器模拟救护车消防车等各种报警喇叭声音的学习源代码...
- 【Vivado那些事】Xilinx的7系列的SRCC和MRCC
- 论文解读:PF磷酸:基于机器学习的磷酸化位点预测疟原虫蛋白的工具
- 关于cocos2d-x项目防止八门神器等修改工具的一种解决办法