测试发现 遥控器的角度不一样 或者有反射 导致解析的码也不一样
程序
/*
* IRrecvDemo-LED
* =====================功能说明=====================
* 演示如何利用Arduino开发板接收红外遥控器控制信号,
* 并利用接受到的信号遥控Arduino开发板上的红外LED。
* Arduino所接收到的红外遥控器信号内容也将通过串口监视器显示出来。
*
* 本程序基于Ken Shirriff开发的IRremote库。如需获得该库文件
* 可前往以下网址获得:
* http://arcfn.com (Ken Shirriff个人博客)
* http://www.taichi-maker.com/homepage/download/ (太极创客官网)
*
* =====================电路连接======================
* 红外接收器 1838B OUT 引脚 --- Arduino Uno 11 引脚
* 红外接收器 1838B VCC 引脚 --- Arduino Uno +5V 引脚
* 红外接收器 1838B GND 引脚 --- Arduino Uno GND 引脚
*
* 如需获得详细电路连接说明图,请参阅太极创客网站:
* http://WWW.TAICHI-MAKER.COM
*
* 此示例程序为配合太极创客制作的
* 《零基础入门学用ARDUINO教程-智能应用篇》使用
*
*/
#include <IRremote.h>
#define RECV_PIN 11
IRrecv irrecv(RECV_PIN); // 红外遥控初始化
decode_results results; // 储存接收到的红外遥控信息
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(9600);
Serial.println("Enabling IRin");
irrecv.enableIRIn(); // 启动红外接收
Serial.println("Enabled IRin");
}
void loop() {
/*
decode()库函数用于判断红外接收器所接收到的红外信号是否可以被解析。
如可以成功解析,则返回非零数值。并将解析结果存储于results中。
如无法成功解析,则返回零。
每一次解析完成,都需要调用resume()函数从而让Arduino开始准备接收下一个红外
遥控指令。
*/
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX); // results.value为红外遥控信号的具体数值
if(results.value == 0xF7C03F) //如果控制信息数值为F7C03F
{
Serial.println("Command Received: Turn On LED.");
digitalWrite(LED_BUILTIN, HIGH);
}
if(results.value == 0xF740BF) //如果控制信息数值为F740BF
{
Serial.println("Command Received: Turn Off LED.");
digitalWrite(LED_BUILTIN, LOW);
}
irrecv.resume(); // 恢复接收下一个红外遥控信号
}
delay(100);
}
买的一个红外解码模块 接受的数据 00 FF 45
发送数据
A2 F1 00 FF 49
arduino 接受 红外解码模块发送红外 数据 FF926D
arduino 接受 按键发送红外 数据 FF00926D
电视遥控器测试1
红外遥控解码器能读出数据 40 BF 04
arduino 能读出数据 2FD20DF
利用红外遥控解码器发送得到的16进制数据 A2 F1 40 BF 04 arduino能解码出 原始码 2FD20DF
遥控器2 红外解码模块不能读出数据
arduino 能读出红外数据 6A68351E
经过以上阶段的测试 遥控器的编码 不一致
具体的协议类型 大家可以百度
https://wenku.baidu.com/view/edd46df9c77da26925c5b05c.html
NEC
SONY
PANASONIC
JVC
RC5 RC6 .....
最恶心的就是自定义的协议 比如 下面这个遥控器 TCL
于是我又在网上找资料
重新写了一个程序进行解码
/*
* 学霸型红外遥控器
* 太极创客 http://www.taichi-maker.com/
* Ver. 1.2 - 01/07/2017
* =====================功能说明=====================
* 利用Arduino开发板记录并“重放”红外遥控信号
* 用户可以使用家中控制电器用的红外遥控器对准本装置的
* 红外接收器,本装置可将接收到的红外遥控信号记录至EEPROM。
* 当用户按下"发射"按键时,红外LED会发射记录的红外遥控信号
* 从而控制家中电器。
*
* 本示例程序主要内容借鉴Ken Shirriff 的 IRremote 库示例程序IRrecord。
*
* 本程序基于Ken Shirriff开发的IRremote库。如需获得该库文件
* 可前往以下网址获得:
* http://arcfn.com (Ken Shirriff个人博客)
* http://www.taichi-maker.com/ (太极创客官网)
*
* =====================电路连接======================
* 红外接收器 1838B OUT 引脚 --- Arduino Uno 引脚 11
* 红外发射 LED 正极 --- Arduino Uno 引脚 3
* 按键开关 --- Arduino Uno 引脚 12
*
* 如需获得详细电路连接说明图,请参阅太极创客网站:
* http://WWW.TAICHI-MAKER.COM
*
* 此示例程序为配合太极创客制作的
* 《零基础入门学用ARDUINO教程-智能应用篇》使用
* 版本更新说明
* V1.1 使用put get来 进行EEPROM存取
* V1.2 针对IRrecord代码进行优化
*/
#include <IRremote.h>
#include <EEPROM.h>
#define codeTypeEAddr 0 // 存放红外信号编码类型EEPROM地址
#define codeLenEAddr 1 // 存放红外信号编码长度EEPROM地址
#define toggleEAddr 2 // 存放红外信号RC5/RC6类型EEPROM地址
#define codeValueEAddr 3 // 存放红外信号数值EEPROM地址
#define RECV_PIN 11 // 红外接收器 OUT 引脚 --- Arduino 引脚11
#define BUTTON_PIN 12 // 按键开关 --- Arduino 引脚12
#define STATUS_PIN LED_BUILTIN // 状态显示LED --- 开发板内置LED
IRrecv irrecv(RECV_PIN); // 红外遥控接收器对象
IRsend irsend; // 红外遥控发射对象
decode_results results; // 储存接收到的红外遥控信息
void setup() {
Serial.begin(9600);
irrecv.enableIRIn(); // 启动红外接收
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(STATUS_PIN, OUTPUT);
delay(10);
loadEepromValues(); // 从EEPROM中读取红外信号信息(具体信息请见函数部分)
}
// 红外信号存储变量
int codeType; // 红外信号编码类型
unsigned long codeValue; // 存放红外信号数值(如果不是raw型)
unsigned int rawCodes[RAWBUF]; // raw型信号
int codeLen; // 红外信号编码长度
int toggle; // 红外信号RC5/RC6类型
// 记录收到的红外信号
void storeCode(decode_results *results) {
codeType = results->decode_type;
int count = results->rawlen;
if (codeType == UNKNOWN) { //如果收到的信号是无法识别的协议,则存储为raw型数据
Serial.println("Received unknown code, saving as raw");
codeLen = results->rawlen - 1;
// 存储raw型信号:
// 将首个数值放弃(间隙)
// 将信号转化为毫秒
// 细微调整信号内容,将信息变短将空档间隙变长从而取消红外接收信号的扰动
for (int i = 1; i <= codeLen; i++) {
if (i % 2) {
// 信号
rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS;
Serial.print(" m");
}
else {
// 空档间隙
rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS;
Serial.print(" s");
}
Serial.print(rawCodes[i - 1], DEC);
}
Serial.println("");
}
else {
if (codeType == NEC) { //如果是NEC协议类型
Serial.print("Received NEC: ");
if (results->value == REPEAT) {
// Don't record a NEC repeat value as that's useless.
Serial.println("repeat; ignoring.");
return;
}
}
else if (codeType == SONY) { //如果是SONY协议类型
Serial.print("Received SONY: ");
}
else if (codeType == PANASONIC) { //如果是PANASONIC协议类型
Serial.print("Received PANASONIC: ");
}
else if (codeType == JVC) { //如果是JVC协议类型
Serial.print("Received JVC: ");
}
else if (codeType == RC5) { //如果是RC5协议类型
Serial.print("Received RC5: ");
}
else if (codeType == RC6) { //如果是RC6协议类型
Serial.print("Received RC6: ");
}
else {
Serial.print("Unexpected codeType "); //无法识别信号
Serial.print(codeType, DEC);
Serial.println("");
}
Serial.println(results->value, HEX); //输出信号数值
codeValue = results->value;
codeLen = results->bits;
}
writeEepromVal(); //将收到的信号信息储存于eeprom
}
// 发射红外信号
void sendCode(int repeat) {
if (codeType == NEC) { //如果是NEC协议信号
if (repeat) { //且如果是发射重复信号
irsend.sendNEC(REPEAT, codeLen); //发射NEC协议的重复信号
Serial.println("Sent NEC repeat");
}
else {
irsend.sendNEC(codeValue, codeLen); //否则发射NEC协议红外指令信号
Serial.print("Sent NEC ");
Serial.println(codeValue, HEX); //串口监视器输出红外指令信号数值
}
}
else if (codeType == SONY) { // 发射的信号是SONY协议
irsend.sendSony(codeValue, codeLen); // 发射SONY协议红外指令信号
Serial.print("Sent Sony ");
Serial.println(codeValue, HEX);
}
else if (codeType == PANASONIC) { // 发射的信号是PANASONIC协议
irsend.sendPanasonic(codeValue, codeLen); // 发射PANASONIC协议红外指令信号
Serial.print("Sent Panasonic");
Serial.println(codeValue, HEX);
}
else if (codeType == JVC) { // 发射的信号是JVC协议
irsend.sendJVC(codeValue, codeLen, false); // 发射JVC协议红外指令信号
Serial.print("Sent JVC");
Serial.println(codeValue, HEX);
}
else if (codeType == RC5 || codeType == RC6) { // 发射的信号是RC5或RC6协议
if (!repeat) {
// 新按键按下后反转toggle位
toggle = 1 - toggle;
}
// 将toggle位放入信号代码中发送
codeValue = codeValue & ~(1 << (codeLen - 1));
codeValue = codeValue | (toggle << (codeLen - 1));
if (codeType == RC5) { // 发射的信号是RC5协议
Serial.print("Sent RC5 ");
Serial.println(codeValue, HEX);
irsend.sendRC5(codeValue, codeLen);
}
else { // 发射的信号是RC6协议
irsend.sendRC6(codeValue, codeLen);
Serial.print("Sent RC6 ");
Serial.println(codeValue, HEX);
}
}
else if (codeType == UNKNOWN /* i.e. raw */) {
// 假设信号频率 38 KHz
irsend.sendRaw(rawCodes, codeLen, 38);
Serial.println("Sent raw");
}
}
int lastButtonState; // 此变量用于判断发射红外信号的按键开关所处的状态
void loop() {
int buttonState = !digitalRead(BUTTON_PIN); // 读取当前的按键开关状态(检查用户是否按下了按键开关)
if (lastButtonState == HIGH && buttonState == LOW) { // 如果按键开关是被按下后再抬起的
Serial.println("Released"); // 通过串口监视器输出"按键抬起"
irrecv.enableIRIn(); // 启动红外接收器信号接收
}
if (buttonState) { // 如果按键开关处于被按下的状态
Serial.println("Pressed, sending"); // 通过串口监视器输出"按键按下"
digitalWrite(STATUS_PIN, HIGH); // 闪烁状态显示红外LED告知用户当前"学霸遥控器"正在发射红外信号(点亮LED)
sendCode(lastButtonState == buttonState); // 更新按键开关状态变量
digitalWrite(STATUS_PIN, LOW); // 闪烁状态显示红外LED告知用户当前"学霸遥控器"正在发射红外信号(熄灭LED)
delay(50); // 信号发射间歇
} else if (irrecv.decode(&results)) { // 如果按键开关处于没有被按下的状态,则实时检查红外接收器并对接收到的信号进行解码
// 如果接收到的红外信号可以通过decode函数成功解码
digitalWrite(STATUS_PIN, HIGH); // 闪烁状态显示红外LED告知用户当前"学霸遥控器"正在发射红外信号(点亮LED)
storeCode(&results); // 将解码的红外信号信息进行储存(非EEPROM储存)
irrecv.resume(); // 恢复红外接收器
digitalWrite(STATUS_PIN, LOW); // 闪烁状态显示红外LED告知用户当前"学霸遥控器"正在发射红外信号(熄灭LED)
}
lastButtonState = buttonState; // 更新按键开关状态变量
}
// 通过EEPROM读取红外信号信息
// 每次Arduino通电后,都会从EEPROM中读取存储的红外信号信息。
// 从而确保"学霸遥控器"在断电后依然可以保持上一次运行时所存储的
// 红外信号信息。
void loadEepromValues(){
codeType = EEPROM.read(codeTypeEAddr);
delay(10);
codeLen = EEPROM.read(codeLenEAddr);
delay(10);
toggle = EEPROM.read(toggleEAddr);
delay(10);
toggle = EEPROM.read(toggleEAddr);
delay(10);
EEPROM.get(codeValueEAddr, codeValue);
}
// 将红外信号信息储存于EEPROM
// 每一次"学霸遥控器"接收到新的红外遥控信号
// 都将最新接收的红外遥控器储存于EEPROM
// 从而确保信号信息不会因为Arduino断电而丢失
void writeEepromVal(){
EEPROM.write(codeTypeEAddr, codeType);
delay(10);
EEPROM.write(codeLenEAddr, codeLen);
delay(10);
EEPROM.write(toggleEAddr, toggleEAddr);
delay(10);
EEPROM.put(codeValueEAddr, codeValue);
delay(10);
}
按键 接3.3v 拉高
于是下载查看现象
发现了恶心的一项
遥控器什么玩意