幻生幻灭 发表于 2013-3-9 16:24:20

Arduino红外遥控系列教程2013——IRremote库进阶与调试

本帖最后由 幻生幻灭 于 2013-3-9 16:25 编辑

惯例,在开始之前,先推荐本系列的前五篇教程。
Arduino红外遥控系列教程2013——发射与接收[链接]
Arduino红外遥控系列教程2013——红外转码[链接]
Arduino红外遥控系列教程2013——红外转码扩展应用1[链接]
Arduino红外遥控系列教程2013——红外协议之NEC[译文][链接]
Arduino红外遥控系列教程2013——IRremote多协议红外遥控扩展库[译文][链接]

重磅推出
Arduino IRremote Wiki 语法手册中文版[链接]


从今年1月初开始,断断续续的学习Arduino与红外遥控。没想到已经写了五篇教程,还整理了Wiki。本来当初只是想研究下红外协议,将来好给BOXZ做通讯。没想到系统的学习下来,还能整理出些教程和心得,分享给大家,希望对红外感兴趣的玩家能有所帮助。这是第六篇,可能是本系列的最后一篇教程了,然后就要把精力转移到将其用于BOXZ的通讯之中。最后感谢作者编写的IRremote库和一直以来支持我们的极客们!

正文
IRremote库进阶与调试
这里分享一些IRremote库的使用经验,以及部分作者在原文中没有提到过的重要信息。
http://v.youku.com/v_show/id_XNTI0MTcyMzg0.html
http://v.youku.com/v_show/id_XNTI0MTcyMzg0.html

1. 兼容性
IRremote库不仅支持Arduino的大部分主板,还支持其他非常多的主板和芯片。图中绿色部分是默认的引脚。

大家也可以通过修改库IRremoteint.h文件来选择其他引脚。例如Arduino不是只能用数字引脚3,还可以使用数字引脚9作为其红外发射的输出。而这点在与其他库Timer冲突时显得格外有用,因为有时候红外不工作的可能原因之一就是定时器冲所突导致的。注意:此修改需要重启Arduino界面才能生效!笔者只测试过UNO的Pin 9。


2. 调试模式
当大家遇到接受红外编码无法识别时,可以激活这个可选的功能——DEBUG模式。如图通过修改库中IRremote.h文件,将#define DEBUG前面的注释符号“//”去掉后保存文件。关闭Arduino 界面并重启,然后下载样例代码examples\IRrecvDemo.ino。

打开串口软件,按下遥控器按键,此时所显示的内容会有天壤之别。如图,

大家可以根据每个信号(Mark)或者空格(Space)的时间长短来对接收的编码数据进行分析。

3. 协议编码的长度


4. NEC协议测量时间的定义标准。
IRremote库本身默认允许20%的容差。超过该范围则视为无效编码数据。


5. 容差
大家也可以通过修改库IRremoteint.h文件来增大容差范围。例如:测试红外接收发现经常丢码。可用前面提到过的DEBUG模式来分析测量时间是否有临界值。如有则可以考虑增大容差范围


6.红外接收状态显示
可以通过增加一条代码,实现接收红外数据时板载LED (Pin 13)闪烁,显示红外接收的状态。
irrecv.blink13(1); // 接收时闪烁板载LED 13


7. NEC的重复编码
可以在库IRremote.h文件中进行修改。


8. 新增协议
如果大家希望增加自己的协议的话,可以在库文件IRremote.cpp中添加。
通过调用私有类,可以很轻松的添加新协议,具体可以参考NEC的协议代码。

Damn_intuition 发表于 2013-3-9 22:59:28

本帖最后由 Damn_intuition 于 2013-3-9 23:00 编辑

研究的比较透彻。借花献佛。
传一份arduion控制LEGO红外接收器的avr代码,有助于真正了解红外编码协议。#include <avr/io.h>
#include <avr/delay.h>

#define PININ (_BV(1)|_BV(2)|_BV(3)|_BV(4))
#define LEFT_BV(1)
#define FORW_BV(2)
#define BACK_BV(3)
#define RIGHT _BV(4)

void setup(void)
{
    // PB0 is outout
    DDRB = _BV(0);       
    // Pull-up input pins
    PORTB = PININ;

    // 9600000/8 Hz / (2 * 16) = 37500 Hz
    OCR0A = 16;

    // toggle output compare A (=PB0)
    TCCR0A = (1 << COM0A0)|(1<<WGM01);
}

void on(void)
{
    // start timer; divide by 8
    TCCR0B = (1 << CS01);
}

void off(void)
{
    // stop timer
    TCCR0B = 0;

    // clear PB0
    PORTB = PININ;
}

void xmit( uint16_t ontime, uint16_t offtime ) {
    on();
    _delay_loop_2(ontime); // 4 * ontime clocks
    off();
    _delay_loop_2(offtime);
}

#define ONTIME(2500/4)
#define HITIME(4583/4)
#define LOTIME(1666/4)
#define BTIME   (9200/4)
#define ETIME   (625000/4)

void xmitcode(uint16_t code) {
    xmit(ONTIME,BTIME);

    for( int i = 0; i < 16; i++ ) {
       xmit(ONTIME, (code & 0x8000) ? HITIME : LOTIME );
       code = code << 1;
    }

    xmit(ONTIME,0);
    // calling _delay_loop_2 with ETIME causes an overflow
    for( int i = 0; i < 256; i++ )
       _delay_loop_2(ETIME/256);
}


#define CH1RFORBFOR 0x015b
#define CH1RFORBREV 0x0197
#define CH1RREVBFOR 0x0168
#define CH1RREVBREV 0x01a4

#define CH1RFOR   0x8117
#define CH1RREV   0x8124
#define CH1BFOR   0x8142
#define CH1BREV   0x818e

#define CH1NONE   0x010e

/*
*
*/
int main(void)
{
    setup();

    for(;;) {
      uint8_t pin = ~(PINB & PININ);

        if( pin & FORW )
          xmitcode(CH1RFORBREV);
        else if( pin & BACK )
          xmitcode(CH1RREVBFOR);
        else if( pin & LEFT )
          xmitcode(CH1RREVBREV);
        else if( pin & RIGHT )
          xmitcode(CH1RFORBFOR);
        else
          xmitcode(CH1NONE);
    }
}

我叫什么 发表于 2013-7-18 16:46:40

问下楼主我想同时发射和接收应该怎样写?#include <IRremote.h>                   // 引用 IRRemote 函式库

int RECV_PIN = 11;                      //定义红外接收器的引脚为11
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
Serial.begin(9600);
irrecv.enableIRIn();                  // 初始化红外接收器
}

void loop() {
if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);//以16进制换行输出接收代码
    Serial.println();                  //为了便于观看输出结果增加一个空行
    irrecv.resume();                  // 接收下一个值
}
}

IRsend irsend;                        // 定义 IRsend 物件来发射红外线讯号
void loop()
{
Serial.print("SendIR: ");
irsend.sendNEC(0x807F18E7, 32);             // 遥控器的红外线编码
delay(3000);                        // 等待3秒
}

舟泊烟渚 发表于 2013-8-24 01:11:24

同楼上,同时发送和接收

幻生幻灭 发表于 2013-8-26 11:09:26

舟泊烟渚 发表于 2013-8-24 01:11 static/image/common/back.gif
同楼上,同时发送和接收

http://www.geek-workshop.com/thread-3446-1-1.html

jifukui 发表于 2013-10-22 17:44:36

我和同学都是用的美的空调的遥控器我解出的码有100脉冲而他的有200个问一下这是怎么回事???
他的解码可以调动空调问一下这是怎么回事?? 是频率调的不一样吗啊???

幻生幻灭 发表于 2013-10-23 10:57:29

jifukui 发表于 2013-10-22 17:44 static/image/common/back.gif
我和同学都是用的美的空调的遥控器我解出的码有100脉冲而他的有200个问一下这是怎么回事???
他的解码可 ...

论坛搜 空调 红外

水乐天 发表于 2013-10-23 13:47:07

我来支持一下 呵呵

幻生幻灭 发表于 2013-10-23 17:15:15

水乐天 发表于 2013-10-23 13:47 static/image/common/back.gif
我来支持一下 呵呵

真不容易,能得到资深水军的支持。呵呵。

沙漠劲草 发表于 2014-1-7 13:04:28

好东东,收藏了

hua_bang_yu 发表于 2015-8-24 21:29:48

感谢楼主!

麦雨飞哥 发表于 2017-2-25 10:14:55

感谢楼主,就是 7.8项没看明白。我在用红外遥控小车项目。想用别的遥控器代替Carmp3遥控器

cymcym 发表于 2017-10-1 17:34:05

修改库IRremoteint.h文件来选择其他引脚,测试过了,Uno 和2560都不好使,除了默认引脚能发射红外信号,其他的引脚都不行

好奇吖斌 发表于 2017-11-10 10:41:19

楼主,最近在做一个红外遥控的小车,用的是Nano板,发现11号引脚不能输出PWM,是不是有冲突了?我改其它引脚就又可以了
页: [1]
查看完整版本: Arduino红外遥控系列教程2013——IRremote库进阶与调试