IR remote control signal receiver using AVR microcontroller

IR remote control is a device you can find everywhere to find a TV, VCR, or home theatre. Why not use one of them for controlling your own devices like light, air conditioning, etc.

As we know, remote control devices use IR light. This is invisible light of about 950nm wavelength. One most significant problem in using IR light is that there many other sources of it like the sun, light bulbs, fire. To exclude other sources, the IR signal is modulated by some frequency. The receiver has to be tuned for this frequency. Mostly remote controls transmit IR signals using 36kHz frequency signals. Transmitting and coding is one part that can be done more efficiently than receiving and decoding. Decoding is usually performed by using microcontrollers. First of all, the receiver has to get rid of the 36kHz carrier frequency. This is not a simple task to demodulate the signal; this is why particular IR receiver IC’s are produced. One of them is TSOP1736:

This receiver simply removes the 36KHz carrier signal and gives clean pulses that are used for device control. I won’t go too deep into how it works – you can find this information in datasheets. This module is convenient to connect to microcontrollers like AVR or PIC because it forms TTL signal levels compatible with them.

Let’s go further. Remote controls usually use three different modulation types: biphase coding; Pulse-distance modulation, and Pulse-length code.

Pulse-distance modulations are commonly used by LG, JVC, Acorp, Hitachi, Nokia, Aiwa, Akai, AverMedia, NEC. So further, we will discuss only this modulation type.

As you have noticed, pulse-distance modulation uses fixed-length pulses while gap defines whether it is “1”(long gap) or “0”(short gap) logical value. When using Pulse-Distance modulation, first goes LSB, then MSB bits. If the remote control button is pressed for a long time, it sends one full packet, and then after some time, it continuously sends unitary pulses informing that button is still pressed. Note that different manufacturers may use different lengths of pulses.

Let’s write decoding algorithm for AVR-GCC compiler (Atmega162):

//pin connected to TSOP1736
#define K1 (1<<PINA0) 
uint8_t impulse_prev = 0;
uint8_t counter_impulse_1 = 0;
uint8_t flag_rx = 0;
uint8_t counter_impulse_0 = 0;
uint8_t impulse = 0;
uint64_t counter_ik = 0;
uint64_t code = 0;
ISR(TIMER0_OVF_vect)
{
uint8_t c;
uint8_t str[35];
uint64_t i;
//Timer0 initialization
TCNT0=0xFF;
//Invert input signal
if (K1==1) impulse=0; else impulse=1;
if ((impulse_prev==0)&&(impulse==1))
	{//rising edge detection
	//reset counter
	counter_impulse_1=0;
	if ((counter_impulse_0>3)&&(flag_rx==1)&&(counter_impulse_0<23))
		{//if receiving symbols
		if(counter_impulse_0>12)
		//logical 1 received
		code |=(1<<counter_ik);
		counter_ik++;
		};
	};
if((impulse==1)&&(counter_impulse_1<50))
	//counting positive pulses
	counter_impulse_1++;
if((impulse_prev==1)&&(impulse==0))
	{//negative front
	counter_impulse_0=0;
	if(counter_impulse_1>30)
		{//one long synchro pulse
		code=0;
		counter_ik=0;
		flag_rx=1;
		}
	};
if((impulse==0)&&(flag_rx==1)&(counter_impulse_1<150))
//counting negative pulses
counter_impulse_0++;
if((counter_impulse_0>50)&&(flag_rx==1)&&(impulse==0))
	{//end of receive
	flag_rx=0;
	counter_impulse_0=0;
	counter_impulse_1=0;
	counter_ik=0;
	code=0;
	};
impulse_prev=impulse;
}

Interrupt service routine ISR(TIMER0_OVF_vect) is called with the frequency of 10.8kHz. This frequency is more than enough compared with a pulse frequency of receiving the code. At the beginning of the procedure, the signal is inverted. The current signal level from the photo-sensor is defined by variable impulse. Signal reference is the signal front (variable impulse_prev). Duration of positive and negative impulses are defined by variables counter_impulse_0 and counter_impulse_1. They show how much time has passed since the signal front was registered.

flag_rx variable indicates the beginning of the signal transfer.

Received code is stored in 64-byte variable code. Variable counter_ik indicates a bit number in the received code.

The algorithm can receive one code. Using this ISR, you can program any control from your fantasy 🙂

The further example demonstrates how this can be used to control a remote light switch:

Download hex code for this circuit here: remote_light_switch.zip

The remote control button code is stored in EEPROM. It can be programmed by pressing the remote control button 20 times. After this code is saved to EEPROM, if you missed the button, then start again from 0 to 20.

RS232 interface is optional if you want to expand the functionality of the remote switch by connecting it to another embedded platform or PC. Circuit sends code in ASCII format at kB/s speed.

LED D1 indicates that MCU works OK; LED D2 – indicates about receiving a signal; LED D3 – indicates that the Light switch is ON/OFF.

Of course, it is easy to construct an algorithm to another AVR MCU and for different purposes. This article only gives an idea of using a remote control with embedded platforms.

15 Comments:

  1. it is a great information for beginners

  2. Hi,
    Line 26 seems to be broken,
    as code |=(1 Can you perhaps put the source code into a .txt file / zip it and send to me?

    Thanks

  3. Can you sand the full source code to me at pratheepmail@gmail.com

  4. Unfortunately only hex and decoding code fragment is available for this circuit.

  5. Manoj Jaiswal

    will you put full source code is txt format. i unable to understandhow it differtiate key of remote controller

  6. i wont to use atmega8,will you put full source code

  7. It’s grate. thanks!

  8. hi guy’s……..
    i am asking for your help guy’s….i have this project…the doctor asked me for a project to write alphabetic’s on lcd using avr and bascom programing lang….the idea is not that hard..but i can’t figure how to recognize different buttons on remote control using the avr…i mean this is how i imagine it…button 1 on remote is assembled by 5 0/1 digital signal’s …button2 by 6 and …etc.
    plzzzzzzz help me with the hole concept…and how can i read a single 0/1 using avr …

  9. hey
    can anyone mail me the full code of this project,
    i m unable to understand it clearly

  10. hey
    can anyone mail mw the whole code
    at
    er_vikram190@hotmail.com

  11. Sigh, what’s up with all these people asking for source. It’s right there!

  12. Can somebody send me full C code, because i see that there are some lack code.
    xcentras@gmail.com Thanx.

  13. I am looking for am explanation about IR tran/recieve .

    i am a beginner.
    where can i get tutorial about that in c language.

  14. I have assembled a IR Remote controller kit from Embedded For You magazine it works fine.
    http://www.embedded4u.com/kits4u.asp?pno=1&sel=1&cat=

Leave a Reply