Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

IR Receiver with ATMEGA16

Status
Not open for further replies.

Mortalo

New Member
Hi !!
I talked before about this.
Im trying to do a Dimmer controled by IR with a SONY controller
and SONY S protocol.

I configured INT1 by falling edge and INT2 by rising edge and joined them and send the output of the IR sensor to this two pins joined together.
then i configured TMR0 as fast pwm with a period of 2ms and the
TOP = OCR0 to 99d. so the timer its going to give me an interrupt every 0.1ms and in the ISR of the TIMER0 compare i increment a variable "cont".

Every falling edge i begin the timer by setting the prescaler and every rising edge i deactive the prescaler to stop the timer and compare how many counts my variable "cont" have (6 for 0.6ms, 12 for 1.2ms and 24 for 2.4ms).

Doing this, im having trouble reading the data that i send to PORTC. It starts sending wrong data to the PORTC and i dont know what i am doing wrong.
Can somebody help me ?

this is my code.

Code:
#include <mega16.h>
unsigned char start = 0;
unsigned char data = 0;
unsigned char i=0;   
unsigned char num=0;
unsigned char cont=0;
int E = 0;
unsigned char LUMOS []= {1, 32, 47, 62, 77, 92, 107, 122, 137, 152, 167, 182, 197, 212, 227, 242};

// External Interrupt 1 service routine
interrupt [EXT_INT1] void falling(void)
{
 TCCR0|=0x02;               			// Start TMR0
 
}

interrupt [EXT_INT2] void rising(void)
{
 TCCR0 &= 0xf8;                             // TMR0 stopped
 if(start==0)
 	{
 	 if(cont>=25 && cont<=27)		// range for 2.4ms
 		{
 		 start=1;                           // flag  1
 		 cont=0;                            // reset contador
 		 data=0;                            // reset data
 		}
 	}
 else
 	{
 	 	
 	 	 if(cont<8 && cont>4)		// range   0.6ms
 	 		{
 	 	 	 num=0x00;                      
 	 	 	 data = (data<<1);         // for positioning
 	 	 	 data |= num;
 	 	 	 i++;                           // increment puntero
 	 	 	 cont=0;                        // Star  contador
 	 		}
 	 	 if(cont<14 && cont>10 )            // range  1.2ms
 	 	 	{
 	 	 	 num=0x01;                      
 	 	 	 data = (data<<1);              // for positioning 
 	 	 	 data |= num;
 	 	 	 i++;                           // increment puntero
 	 	 	 cont=0;                        // Start contador
 	 	    }
 	}	
}               
interrupt [EXT_INT0] void Zero_cross(void)
{
 TCCR1B |= 0x04;				// activate prescaler 
 OCR1A = LUMOS[E];                 		// Pwm value         		
}

interrupt [TIM1_COMPA] void stop_timer1(void)
{
 TCCR1B &= 0xF8;					// desactivate prescaler 
}


// Timer 0 overflow interrupt service routine
interrupt [TIM0_COMP] void T_BASE(void)
{
 cont++;									
 PORTA.0=~PORTA.0;
}                                    

// Declare your global variables here
void main(void)
{                
PORTA=0x00;									
DDRA=0xFF;                                  // porta OUT

// Port C initialization
PORTC=0x00;									
DDRC=0xFF;                                  // portc OUT 
// Port B initialization
PORTB=0x00;
DDRB=0x00;                                  // portb IN

// Port D initialization
PORTD=0x00;                                 // portd IN
DDRD=0xF0;

// Timer/Counter 0 initialization
TCCR0=0b00001000;			// CTC TMR0, timer stop
OCR0=99;           							
// TIMER 1 INITIALIZATION
TCCR1A = 0b10000010;			// no inverter, fast PWM
TCCR1B = 0b00011100;			// fast PWM, Prescaler 256
ICR1 = 255;								


// External Interrupt(s) initialization
GICR |= 0xE0;				  // INT0, INT1, INT2  On
MCUCR=0x0B;				// INT0 MODE RISING INT1 Mode: Falling Edge
MCUCSR=0x40;				// INT2 Mode: Rising Edge
SREG |=0x80;    			//GLOBAL INT ENABLE

TIMSK=0x12;				// TMR0 COMPARE MATCH INT, TMR1 COMPARE INT

ACSR=0x80;				// Analog Comparator: Off
SFIOR=0x00;

while (1)
      {
       	while(start==0);		// WAIT FLAG TO START       	
       	while(i<7);
       	data &= 0x7F;
       	PORTC = data;                   // TO SEE DATA ON PORTC
       	i=0;                            
       	start = 0;						 
       	data=0;							 
       	if(data==0x10)
				FOR PWM
       		{
       		 if(LUMOS[E]==242)		
     			 	E=E;            
     			 else
     			 	E++;            	
            }
        if(data==0x11)
        	{
        	 if(LUMOS[E]==1)			
     			 	E=E; 	
     			 else
     			 	E--;                
        	}
      };
}
 
Last edited:
I'm not totally sure where you were heading with that, but a good place to start is with the code wrap tag :eek:


Having never worked with Sony S Protocol, I googled it, and found this;

http://www.armory.com/~spcecdt/remote/control-S.html

The Control-S
command word is 12 bits long, and consists of a 5-bit device ID
code followed by a 7-bit button code. The control-S data packet
is preceded by a 2.4 millisecond TTL logic-1 pulse (start bit)
followed by 0.6 ms of logic-0. Each 1 bit in the control word is
represented by a 1.2 ms logic-1 level followed by a 0.6 ms logic-
0 level
, and each 0 bit is 0.6 ms high, 0.6 ms low. The end of
the control packet is always a TTL logic-0 level
, and the total
length of each packet is fixed at 45 ms in length.

So you know the timings, perhaps there is an easier method here.. I'd go for a sequence driven capture, eg, wait for the first signal.. wait for a certain amount of time - then the next frame will be the "window" where if the signal changes from one state to another - then its a high, but if remained the same for the whole duration then its a low... Rinse and repeat until all 12 bits are received then see if it meant anything


And of course you could always just use a PWM output from one PIC and a Logic Output IR Receiver connected to another PIC, then make your own mini protocol :eek:
 
need code tag

@Mortalo

Please edit your message, and add CODE tags before and after your example code. This will increase the number of members who are willing to read it.

regards,
Mike
 
Are you sure you want interrupts enabled while you read and write data?
Code:
while (1)
      {
           while(start==0);        // WAIT FLAG TO START           
           while(i<7);
           data &= 0x7F;
           PORTC = data;                   // TO SEE DATA ON PORTC
           i=0;                            
           start = 0;                         
           data=0;                             
           if(data==0x10)

....etc
 
heyy... i know this discussion is old....but please reply its importatnt for me....i m using TSOP 1738 with Onida TV remote....its giving PWM signals....please tell me in which pin (INT0 , INT1 , INT2 ) i have to put the output of IR decoder(TSOP1738)...
please reply its urgent..!!
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top