IR remote controlled christmas tree, pt. 2/2

IR remote controlled christmas tree, pt. 2/2

Just in time for Christmas eve! At least I finished the tree by then, the post here is a bit late.

So I needed something to demonstrate a simple IR receiver circuit. What could be simpler than making LEDs blink? Well, it would be simple, had I just spent a bit more time on the IR signal encoding so it would be easier to eliminate surrounding IR noise. Because many lights sources emits a certain amount of infrared light, it is not always sufficient to trust the receiver module to filter out all disturbance, some of it will always come trough. This is very true for my bright RGB LEDs that sits on the Christmas tree and screws up and causes external interrupts as soon as they turn on! If you’re reading the output from a module like mine on a oscilloscope, try switching a fluorescent desktop lamp on and off and you will see the scope trigger every time you flip the light switch. This disturbance must be taken care of by software.

But on to the Christmas tree itself. You might have already seen the remote control, where I was wise enough to use a stripboard (a very pretty one, with silver colored strips, maybe they’re pre-tinned). But for the tree I decided to have no visible wiring on the front, so I chose a prototyping board with only these “dots” of copper around each hole. It was a total mess to work with, and I will most probably never do it again. Using those boards are almost similar to wiring components leg-to-leg in free air! Anyways, the tree has three modes which is
1) Christmas star
2) Rotating leds in the middle
3) RGB leds color shifting on the edges
and is controlled by four buttons, where three buttons will individually control one mode, and several modes can run at the same time. The fourth button will turn off all modes at once, like an “off” button.

When the active low output from the IR receiver module pulls INT0 pin low, an interrupt occurs. When this interrupt occurs, it will delay for a period as long as half the pulse width that the data is transferred with.

_delay_ms(2);
if (!(PIND & (1< 

This is to ensure we read the pulse at the most steady state (on the middle). After the parity bit, we start reading once every full length of the pulse width.

_delay_ms(2);
if (!(PIND & (1< 	ir = ir << 1;

_delay_ms(4);
if (!(PIND & (1< 	ir = ir << 1;

_delay_ms(4);
if (!(PIND & (1< 	ir = ir << 1;

_delay_ms(4);
if (!(PIND & (1< 

For every readout, the read bit (low level equals 1, high level equals 0) is shifted to the left and a new one is read. This repeats itself four times to capture all 4 bits of my digital signal transmitted by the remote. So the first bit to be read, the parity bit, will be the most significant bit, MSB. The last read bit will be the LSB. The result is stored in the “ir” variable.


This is really my the whole deal of receiving IR signals. I hope someone will come by and tell me how it’s really done, because you can see many limitations in my design.

Because of the slight problem with the RGB leds triggering the IR receiver module, I decided to only run the RGB show for one cycle while turning of the external interrupts. Its a sad solution, but maybe next year, or sooner, I will upgrade my design with a RF Rx/Tx module or just try to send more complex IR signals, so it’s easier to ignore noise. Here is the rest of the code:

#include <avr/io.h>
#define F_CPU 8000000UL
#include <util/delay.h>
#include <avr/interrupt.h>
#define RED OCR0A
#define GREEN OCR0B
#define BLUE OCR2B

char ir = 0;
char condition = 0;
volatile char rgb = 0;
volatile char blink = 0;
int i;


ISR(INT0_vect)
{
	cli();//disable interrupts
	
	_delay_ms(2);
	if (!(PIND & (1<<PIN2))) ir |= 1;
	ir = ir << 1;

	_delay_ms(4);
	if (!(PIND & (1<<PIN2))) ir |= 1;
	ir = ir << 1;

	_delay_ms(4);
	if (!(PIND & (1<<PIN2))) ir |= 1;
	ir = ir << 1;

	_delay_ms(4);
	if (!(PIND & (1<<PIN2))) ir |= 1;

	
	switch(ir)
	{
		case 12: rgb = ~rgb;  break;
		case 10: blink = ~blink; break;
		case 14: PORTC ^= (1<<PIN3); break;
		case 9:  rgb = 0;
				 blink = 0;
				 TCCR0A &= ~(1<<COM0A1) & ~(1<<COM0B1);
				 TCCR2A &= ~(1<<COM2A1) & ~(1<<COM2B1);
				 PORTC=0;
				 break;
		default: break;
	}

	//if(rgb) PORTD |= 1;
	//else PORTD &= ~1;
	ir = 0;

	_delay_ms(400);

	sei(); //enable interrupts
	
} 


int main(void)
{
	//TC0 init
	TCCR0A |= (1<<WGM00) | (1<<WGM01);
	TCCR0B |= (1<<CS00);
	DDRD |= (1<<PIN3) | (1<<PIN5) | (1<<PIN6) | (1<<PIN0);
	

	//TC2 init
	TCCR2A |= (1<<WGM20) | (1<<WGM21);
	TCCR2B |= (1<<CS20);
	OCR2A = 0;
	OCR2B = 200;

	//External interrupt int0 init
	EICRA |= (1<<ISC11); //Falling edge
	EIMSK |= (1<<INT0); //int0 enable
	

	DDRC = 0xFF;

	sei();

	while(1)
	{
		//PORTC = blink;
		

		if(rgb)
		{
			cli();

			TCCR0A |= (1<<COM0A1) | (1<<COM0B1);
			TCCR2A |= (1<<COM2A1) | (1<<COM2B1);
			//loop(B100-0, R0-100)
			for(i=0 ; i<150 ; i++)
			{
				BLUE = 150-i;
				RED = i;
				if(blink) {PORTC |= 1; PORTC &= ~2 & ~4;}
				else PORTC &= ~1 & ~2 & ~4;
				_delay_ms(5);
			}
			//loop(R100-0, G0-100)
			for(i=0 ; i<150 ; i++)
			{
				RED = 150-i;
				GREEN = i;
				if(blink) {PORTC |= 2; PORTC &= ~4 & ~1;}
				else PORTC &= ~1 & ~2 & ~4;
				_delay_ms(5);
			}

			
			//loop(G100-0, B0-100)
			for(i=0 ; i<150 ; i++)
			{
				GREEN = 150-i;
				BLUE = i;
				if(blink) {PORTC |= 4; PORTC &= ~2 & ~1;}
				else PORTC &= ~1 & ~2 & ~4;
				_delay_ms(5);
			}

			rgb=0;
			TCCR0A &= ~(1<<COM0A1) & ~(1<<COM0B1);
			TCCR2A &= ~(1<<COM2A1) & ~(1<<COM2B1);
			sei();
		}

		while(blink && !rgb)
		{
			PORTC |= 1;
			_delay_ms(150);
			PORTC &= ~1 & ~2 & ~4;
			if(!blink) {PORTC &= ~1 & ~2 & ~4; break;}
			PORTC |= 2;
			_delay_ms(150);
			PORTC &= ~1 & ~2 & ~4;
			if(!blink) {PORTC &= ~1 & ~2 & ~4; break;}
			PORTC |= 4;
			_delay_ms(150);
			PORTC &= ~1 & ~2 & ~4;
		}
	}
}

And to finish it off, here is a short video of the Christmas tree

This article has 7 comments

  1. Very nice thing! I will build this, but do you have the circuit schematic of the christmas tree? I can’t find it ont this page, as you say in part 1.

    • Henrik Sandaker Palm
      Friday 28 October 2011, 11:10 pm

      I can see now that the code posted here is all screwed up. I will fix this. The schematic is also missing. It really is just the IR receiver connected to INT0 pin of the microcontroller, and lot’s of LEDs on all other pins! It shouldn’t be to hard figuring out which LED is on which pin, when I get the schematic back up.

      • will you please send me the corrected code… i m not able to find out the bugs in the code….
        theirs still 3 bugs remaining

        ../IR_Rc.c:20: error: lvalue required as left operand of assignment
        ../IR_Rc.c:20: error: expected ‘)’ before ‘;’ token
        ../IR_Rc.c:124: error: expected declaration or statement at end of input
        make: *** [IR_Rc.o] Error 1

        here’s the simulation output…please help

        • Henrik Sandaker Palm
          Saturday 21 April 2012, 1:48 am

          Sorry, the code is messed up here, I don’t know what have happened. You will not be able to trace this code back to working condition.

  2. sir please send me the correct receiver code its urgent in my yhesis work

  3. Hello, you’re not covering the mesh circuit

Leave a Reply