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.

Need help in implementing IR bit encoding ?

Status
Not open for further replies.

sanddune008

New Member
Hi All,

Problem statement:
I am struck writing code to encode bit 0 and 1. Using PWM and Timer0

It is as follows:
encoding of bit 1
I have to retain pulses(38Khz) exact for duration = 13*(1/38Khz)
and keep no pulses for duration = 82*(1/38khz)

similarly the encoding for bit 0
I have to retain pulses(38Khz) exact for duration = 13*(1/38Khz)
and keep no pulses for duration = 120*(1/38khz)

similarly there is a different encoding for lead out burst and lead in burst.

My Approach:

1. set up the PWM with duty cycle...etc for generating 38Khz pulses..
2. Parallel run the Timer0 with time duration equivalent of 13*(1/38Khz)
3. Inside the Timer0 ISR, I will make the corresponding associated CCP1 OFF and simultaneously set the Timer0 with new time duration of 82*(1/38khz) for which the CCP1 pin has to be low

Here i am struck how to proceed with timing a very important parameter.
can any one give a better approach to improve the timings?I am sending the command at 38 Khz carrier frequency


This is where I am facing problem ,

1. The IR code scheme or protocol whatever contains multiple encode formats, OFF duration (No PWM pulses) varies based on the command (ex mycase: 0xAE). Bit 1, bit 0, extra burst pairs lead out , lead in,frame endseq all of them have same ON duration but differ in their OFF duration. In my case I have to sent all of them bit0, bit1, Lead out burst ,Lead in burst seq and frame end seq in a sequence for controlling a device.

2. Now, I have check for whether it is bit 0 or bit 1 or lead out or lead in or seqence end in the Timer0 ISR and based on this Timer0 has to be loaded. With the OFF duration. won't that affect my timing ? .Remember all the bit sequence(in a command) has to be at one go with no gap in between the command bits

Thanks to all in advance
 
hi,

Look thru Nigel's tutorials. Tutorial #5
 
Last edited:
Now, I have check for whether it is bit 0 or bit 1 or lead out or lead in or seqence end in the Timer0 ISR and based on this Timer0 has to be loaded. With the OFF duration. won't that affect my timing ? .Remember all the bit sequence(in a command) has to be at one go with no gap in between the command bits

So you want to do all that using interrupt driven code. Nice.

You don't "check" when you are inside the ISR but you should build a state machine before you even start the transmission. Every state of the state machine contains the duration and whether the 38KHz should be ON/OFF. During each Timer0 interrupt, you just advance the state machine and read the next state accordingly. Then you turns On/Off the 38KHz carrier and reload Timer0 with new value. Or you can advance the state machine before exiting the ISR so you don't have to do that in next ISR.

This will tie up two of your three timers. One for 38KHz carrier generation and one for the ON/OFF duration.
 
hi,

Look thru Nigel's tutorials. Tutorial #5

Thanks for your time................

I am through with the coding scheme....I am using pronto codes....

What i need to know is there an optional implementation method....with the current code i am not able to achieve prefect timings......needed for the IR

Following is the code i implemented

Code:
Sendcommand()
{
//check for bits in command
//send the command thrice. Command : 0xA6
if (check for bits in command)
SendBit0();
or
SendBit1();

//finally sent the seq end
seqend();
}

void SendBit0(void)
{
   //printf("\r\nInsSndBit0\n\r");
   //38khz Pulses
   SetPWM();
   //delay_us(342);
   //modification after MPLAB simulation
   delay_us(322);
   //No pulses for 82*(1/38Khz)
   output_low(PIN_B3);
   delay_us(3130);//No pulses are sent     
}

//similarly bit1
SendBit0()
{
switch on duration :13*(1/38Khz)
switch off duration : 120*(1/38Khz)

}


void SetPWM(void)
{
   set_tris_B(0x01);
   //App_init();
   setup_ccp1(CCP_PWM);   // Configure CCP1 as a PWM
   setup_timer_2(T2_DIV_BY_1,25,1);
   //Generating 38khz PWM with 50% duty cycle
   set_pwm1_duty(13);
}


Basically a bit encoding..............Will this be an efficient mechanism?...
considering strict timing constraints. Following timing accuracy was tested using MPLAB Simulator.

Is there a way of achieving the same using only timers and PWM. If so how?:confused:

Thanks
 
Last edited:
hi,
Sorry cant help, with 'C' I use assembler.:)

I'm sure others will come forward.
 
So you want to do all that using interrupt driven code. Nice.

You don't "check" when you are inside the ISR but you should build a state machine before you even start the transmission. Every state of the state machine contains the duration and whether the 38KHz should be ON/OFF. During each Timer0 interrupt, you just advance the state machine and read the next state accordingly. Then you turns On/Off the 38KHz carrier and reload Timer0 with new value. Or you can advance the state machine before exiting the ISR so you don't have to do that in next ISR.

This will tie up two of your three timers. One for 38KHz carrier generation and one for the ON/OFF duration.

Thanks for your time......will this be efficient on timings....

A hint on implementation will help....
 
Here's some C code that outputs Sony codes on a 18F1320. It does pretty much what you describe.

Code:
#include <p18f1320.h> 
#include "delays.h"

#pragma config WDT = OFF, LVP = OFF, OSC = INTIO2

void sendbyte(char Num,char bits){
char i;
    for(i=0;i<bits;i++){
        CCPR1L = 0x1A;                  // 0
        CCP1CON = 0x1C;                 // 50%
        if(Num&1==1)
            Delay100TCYx(24);           //1.2mS
        else
            Delay100TCYx(12);           //0.6mS
        Num=Num>>1;
        CCPR1L = 0x00; 	                //Space
        CCP1CON = 0x0C ;                // 0%
        Delay100TCYx(12);               //0.6mS
    }
}

void main(void) {    
    OSCCON=0x72;                        //speed up the clock to 8MHz
    ADCON1 = 0; 
    TRISBbits.TRISB3 = 0;
    TRISBbits.TRISB6=1;
    PR2 = 0b00110100 ;
    T2CON = 0b00000100 ;
    CCPR1L = 0b00011010 ;
    CCP1CON = 0b00011100 ;

    while(1) {
        CCPR1L = 0x1A;                  // 0
        CCP1CON = 0x1C ;                // 50%
        Delay100TCYx(48);               //2.4mS pulse
        CCPR1L = 0x00;                  //Space
        CCP1CON = 0x0C ;                // 0%
        Delay100TCYx(12);               //0.6mS
        sendbyte(18,7);                 //device 18
        sendbyte(1,5);                  //command 1
        Delay1KTCYx(100);
     }    
}

Sorry about the lack of comments. If there's any bits that are confusing, just ask. I can't even remember why I wrote this but it does work on a Junebug.

Mike.
 
Last edited:
Thanks Mike........

Only idea of using timers and PWM for the implementation was to avoid EXT interrupt form interfering with the execution of the code......cause the above code which i implemented may effect the timings when a external interrupt occur.

How do i proceed with the idea proposed by chang as above using state machine?

Thanks
 
How do i proceed with the idea proposed by chang as above using state machine?

State machine is just an array(s), on which you store the values to load into Timer0 and the On/Off status of the carrier. The index to the array form the state machine states.
You can use two separate arrays, one for duration and one for carrier On/Off. Or you can cheat by use value zero to mean "fixed length Timer0 load value and carrier ON" and non-zero values to mean various durations and carrier OFF. In this way only a single dimension array is needed.

The index to this array(s) is your state machine corresponding states. On each ISR you read the value from the array and load the Timer0 accordingly. Then you increase the index by one until you reach the end of array.

Of course you have to fix up the array with correct data before starting the transmission.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top