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 decoder.....!!!

Status
Not open for further replies.

sandeep patel

New Member
hey !!
i m working on a IR decoder circuit with TSOP 1738 Ir decoder and ATmega16 micro-controller....i want to print the incoming bit pattern in 16x2 LCD ....please give me suggestions to code my AVR....if DSO out put of IR Deoder is required then please reply ...i'll post them here....
 
An TSOP1738 is an 38Khz infrared receiver with integrated demodulator, Nothing more.
You must know the timing and coding of the modulation signal to decode it and show it onto your display.

To get the rising and falling edges of the Output signal of the TSOP, You can use an external interrupt e.g. INT0.

To get both in one Interrupt routine you can switch the interupt sensing in the accoring interrupt.
E.g. Interrupt sensing is switched to rising edge. The rising edge of the signal appears.
The interupt will be executed, at the end of the interupt routine you switch the interupt sensing to falling edge.

To get the len of the high or low period, You can read out a free running timer ( Timer1 ) in the INT0 interrupt routine. The time between the rising edge interrupt result and the falling edge interrupt result give you the high time of the signal, for low time the opposite.

You also can use the input capture interrupt instead the INTx. The actual count of TCNT1 Register will be stored in the ICP1 Register when interupt appears. The sensing ( rising, falling ) can switched as same as the INT0.

When the whole sequence is into your controller you can compute it and put it out on your display. You must know the time between 2 sequences to use it for restarting the code sampling.

Sorry, I've no code exeample, but i've used this method to measure servo pulses ( model building ).
 
okk....!! nice information frnd....let me share few more things with you...!! may be after that u'll help me in coding that...

the in coming bit pattern have a START (high) of 4 ms , then it have LOGIC 0 and 1 with 0.4 ms and 1.6 ms.....how to procide for the code ..i want those bit pattern to be displayed in my LCD ... :?...
please reply..!! :)
 
I've done this in this example with the Input capture of Timer1.
It's "C"- Code.

First the ICP Interrupt routine:
Code:
// Timer 1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
unsigned char uc_string[10];
unsigned char uc_i;
unsigned int ui_value=0;
uc_i=TCCR1B;
if((uc_i&0b01000000)==0)                  // ICP Sensing is at falling edge
    {
    ui_timer=ICR1L;                           //ICR1 must be readed sequently
    ui_value=ICR1H;
    ui_value=ui_value<<8;
    ui_timer+=ui_value;
    ui_value=ui_timer-ui_oldtimer;
    //The actual high measurement is in the ui_value variable in micro seconds.  Here you have to set your own code
    TCCR1B|=0b01000000;        //Set ICP Sensing at falling edge
    }
else                                      // ICP Sensing is at rising edge
    {
    TCCR1B&=0b10111111;
    ui_timer=ICR1L;
    ui_value=ICR1H;
    ui_value=ui_value<<8;
    ui_timer+=ui_value;
    ui_oldtimer=ui_timer;
//The actual low measurement is in the ui_value variable in micro seconds. Here you have to set your own code   
}
}
/* In this commented Lines you must insert your own code to extract the 4ms pulse and the following bits. I would do that by putting the bits into a array. When all bits are received i would set a bit flag - bit variable to tell the main routine measurement is ready. When this flag is set the main routine read out the Array, display it on the display an reset the flag to zero for next IR frame. You should not try to put out any things onto the display in an interrupt routine - That takes to much Time an no furthen Intreupts are possible */

Here the settings in the Main Routine
Code:
void main(void)
{
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 1000,000 kHz at a Main frequency of 8Mhz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Rising Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: On
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x42;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x20;

// Global enable interrupts
#asm("sei")

while (1)
      {
      // Place your code here
      /* read out the ready flag and put it out onto display when the whole frame is received or use readin readout counters */
      };
}

Instead the working with an ready flag you can also use a Bit counter.
When the Start is received ( 4ms Pulse ) the readin Counter will be set to 0 in the interupt routine. For every further Bit it will be counted up and adresses the array.
In Main routine you can implement an readout counter. When the readout counter is lower then the readin counter a new bit has received and must be computed and displayed.
Then count up the readout counter.
When readout counter is bigger then readin counter a new IR frame was received ( readin counter was set to 0 ). Then you can clear the Display to get the new Information.
The advantage of method 2 is, the results appears faster on the display then with the method of ready flag.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top