Practical library series : Infrared ray transmitter and receiver

Languages

日本語版はこちら : http://mbed.org/users/shintamainjp/notebook/remote_ir_ja/

Overview

The most easiest way to get a user input is using push button switches.

However, Many pins on mbed have a peripheral and we can't use their pin if we use the peripherals.

It's OK to add a few switches. But over 10 switches ... It's not good way to get a user inputs. It's not beautiful way for it.

So I created IR remote transmitter and receiver class library.

You can get a user inputs with only a pin if you use this class library.

Now we can control many machines that have a IR port.

Features

The following function is provied on this library.

  • Support NEC, AEHA, SONY protocol.
  • Support transmit and receive.
  • Interrupt based transmitting and receiving.
  • This library don't touch the data. So It can be support many protocols. Maybe I think. :)

Library

Structure of the class

The library consist are 2 classes.

You can transmit and receive IR signal if you known these 2 classes.

  • TransmitterIR class is for transmitting.
  • ReceiverIR class is for receiving.

Projects

The projects are RemoteIRandRemoteIR_TestProgram.

The library project is RemoteIR. This project have not mbed library for general library use.

You can check the functions with RemoteIR_TestProgram.

How to use the library

ReceiverIR class

Create ReceiverIR instance in your program. The instance need a pin name for IR receiver.

#include "ReceiverIR.h"

ReceiverIR ir_rx(p15);

And check the state with getState(), if the state indicate ReceiverIR::Received than you can get a data.

RemoteIR::Format format;
uint8_t buf[32];
int bitcount;
if (ir_rx.getState() == ReceiverIR::Received) {
    bitcount = ir_rx.getData(&format, buf, sizeof(buf) * 8);
}

'format' have a received format type. The last argument of getData is maximum bit length for the buffer.

'bitcount' is received bit count.

You know this library interfaces is very simple.

The example circuit

TransmitterIR class

Create TransmitterIR instance in your program. The instance need a pin name for IR transmitter.

#include "TransmitterIR.h"

TransmitterIR ir_tx(p21);

And check the state with getState(), if the state indicate TransmitterIR::Idle than you can write a data for transmit.

RemoteIR::Format format = RemoteIR::SONY;
uint8_t buf[] = { 0x80, 0x00 };
int bitcount = 12;
if (ir_tx.getState() == TransmitterIR::Idle) {
    bitcount = ir_tx.setData(format, buf, bitcount);
}

'format' is for a transmit protocol type. The last argument of setData is bit length of the data.

This is very simple way to transmit IR signal.

 

The example circuit

 

Others

There is a example application.

RemoteIR_TestProgram

Research and verification

There are many protocols in IR remote world. In this section, check some protocols with theis signals.

The output signals polarity is negative. The data is LSB first.

NEC

  • T=562u[sec]
  • Leader: 16T+8T (With data), 16T+4T (Without data => Repeat)
  • Data: 32bits fixed length (With data), None (Without data => Repeat)
  • Stop bit: Yes
  • Data bit: 1T+1T (bit0), 1T+3T (bit1)

The data is ...

Check my library output.

AEHA

  • T=425u[sec]
  • Leader: 8T+4T (With data), 8T+8T (Without data => Repeat)
  • Data: Variable length (With data), None (Without data => Repeat)
  • Stop bit: Yes
  • Data bit: 1T+1T (bit0), 1T+3T (bit1)

The data is ...

Check my library output.

SONY

  • T=600u[sec]
  • Leader :4T
  • Data: Variable length
  • Stop bit: No
  • Data bit: 1T+1T (bit0), 1T+2T (bit1)

12bits length

The data is ...

Check my library output.

15bits length

The data is ...

Check my library output.

References

Update history

Version Date Description
1.0.0 2010/08/21 First version.
1.0.1 2010/10/18 Added schematics of the transmitter and the receiver circuits.
- - -
- -
-
- - -
- - -
- - -
- - -
- -
-

Special Thanks to...

Special Thanks to Mr.Johan Philippe-san.


5 comments

06 Aug 2012

thanks for such a great work! Library really works well.

I would like to ask something about hardware of transmitting IR signal. In the example cicuit, why did you use 5 IR Leds?

I guess it is just for increase the IR transmitting power. I would like to carry the IR signal with cable and there will be one IR LED at the end of the cable. I am going to use

5V circuit, same as your example. So, do you have any idea or suggestion about the long distance(about 30m) transmitting.

 

thanks in advance,

25 Jul 2014 . Edited: 25 Jul 2014

Thank for the code and explanation. I've tested with LPC1769 (lpcxpresso) and it works perfectly. But it does not work with Nucleo F401 board. I think the isr_wdt function is not responsding.

 

void ReceiverIR::isr_wdt(void) {
    LOCK();
    static int cnt = 0;
    if ((Idle != work.state) || ((0 <= work.c1) || (0 <= work.c2) || (0 <= work.c3) || (0 <= work.d1) || (0 <= work.d2))) {
        cnt++;
        if (cnt > 50) {
#if 1
            printf("# WDT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n",
                   work.c1,
                   work.c2,
                   work.c3,
                   work.d1,
                   work.d2,
                   work.state,
                   data.format,
                   data.bitcount);
#endif
            init_state();
            cnt = 0;
        }
    } else {
        cnt = 0;
    }
    UNLOCK();
}

Regards,

Aung

29 Oct 2014
Found the solution In case you want to make this library work on F401RE, you should declare "ReceiverIR ir_rx(pin);" inside main() function, not outside, otherwise timer/ticker would not work.
12 Oct 2015
Hello Great libs! I am using it on a Nucelo L476RG. However Iam trying to send more than 32 bit at the same time (using AHEA) protocol for example. With 32 bit of code to send it works great. With more than 32 bit (40 for example) the sender crash while copy the data to the buffer for (int i = 0; i < n; i++) { data.buffer[i] = buf[i]; } Any idea why is this?
08 Apr 2018
Great Libs, But can I use it with nRF52 ?

You need to log in to post a comment