CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PIC RC5 Code
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
sarmad_101



Joined: 17 Jun 2010
Posts: 12

View user's profile Send private message

PIC RC5 Code
PostPosted: Thu Jul 08, 2010 11:55 pm     Reply with quote

Can anyone share C code for decoding RC5 signals using PIC microcontoller? I've googled for days and all the code that I found used delays to sample the signal..which causes problem when RC5 signal timings are slightly different than standard. None of them actually uses manchester decoding.

I am looking for a code like the BASCOM 8051/AVR compilers internal library has. Till date its the best RC5 decoding code I have found...it works for any damn RC5 remote...irrespective of timing variations.

Now I am looking for similar code for PIC. Anyone please?
picpgm



Joined: 28 Dec 2010
Posts: 6

View user's profile Send private message

PIC RC5 Code
PostPosted: Wed Jul 27, 2011 3:01 pm     Reply with quote

Hi,
I have written a RC5 decoder driver which can be compiled with the CCS C compiler.
You can download it here:
http://members.aon.at/electronics/pic/projects/rc5_decoder/index.html
sahu77



Joined: 08 Sep 2011
Posts: 202

View user's profile Send private message

Re: PIC RC5 Code
PostPosted: Sat Oct 08, 2011 1:15 pm     Reply with quote

picpgm wrote:
Hi,
I have written a RC5 decoder driver which can be compiled with the CCS C compiler.
You can download it here:
http://members.aon.at/electronics/pic/projects/rc5_decoder/index.html

i m use it like this ....
Code:
 ******************************************************************************/
#include <RC5 IR Remote.h>
#include "types.h"

/* --- RC5 driver configuration --- */
#define RC5_DATA_PIN          PIN_A4        /* IR sensor (SFH5110-36) connected to RB1 */
#define RC5_TICKS_PER_MS      (1000/26)     /* timer increments every 25.6us, */
                                            /* i.e. around 39 ticks per millisecond */
#define RC5_GetTimer()        get_timer0()  /* timer0 shall be used for RC5 decoding */
                         

/* --- macros to switch on/off LED --- */
#define Led_On()        output_high(PIN_A0)
#define Led_Off()       output_low(PIN_A0)
 
/* RC5 driver include */
#include <RC5_driver.h>

/*******************
//PORT C Register = 0x07
//PORT A Register = 0x05
*********************/
#BIT RL1 = 0x07.0
#BIT RL2 = 0x07.1
#BIT RL3 = 0x07.2
#BIT RL4 = 0x07.3
#BIT RL5 = 0x07.4
#BIT RL6 = 0x07.5
#BIT RL7 = 0x05.1
#BIT RL8 = 0x05.2

/******************************************************************************
 Key Codes
 *****************************************************************************/
#define RC5_NUMERIC_KEY_0 0x00 /* NUMERIC KEY 0 */
#define RC5_NUMERIC_KEY_1 0x01 /* NUMERIC KEY 1 */
#define RC5_NUMERIC_KEY_2 0x02 /* NUMERIC KEY 2 */
#define RC5_NUMERIC_KEY_3 0x03 /* NUMERIC KEY 3 */
#define RC5_NUMERIC_KEY_4 0x04 /* NUMERIC KEY 4 */
#define RC5_NUMERIC_KEY_5 0x05 /* NUMERIC KEY 5 */
#define RC5_NUMERIC_KEY_6 0x06 /* NUMERIC KEY 6 */
#define RC5_NUMERIC_KEY_7 0x07 /* NUMERIC KEY 7 */
#define RC5_NUMERIC_KEY_8 0x08 /* NUMERIC KEY 8 */
#define RC5_NUMERIC_KEY_9 0x09 /* NUMERIC KEY 9 */

/*****************************************************************************/
/* Interrupt_RA                                                              */
/*                                                                           */
/* Port A change interrupt service routine.                                  */
/* Used to decode RC5 IR signal.                                             */
/*****************************************************************************/
/* Function Commented Out
#INT_RA
void Interrupt_RA(void)
{
   Led_On();
   RC5_InterruptHandler();
   Led_Off();
   
   set_timer0(230);
   clear_interrupt(INT_RA4);
}

** End Function Commented Out */


/*****************************************************************************/
/* Interrupt_TIMER0                                                          */
/*                                                                           */
/* Timer0 Needs to be executed every 26 us                                   */
/* Used to decode RC5 IR signal.                                             */
/*****************************************************************************/
#INT_TIMER0
void Interrupt_Timer0(void)
{
   //Reset Timer to execute next 26 us
   set_timer0(230);
   clear_interrupt(INT_TIMER0);
}


/*****************************************************************************/
/* main                                                                      */
/*                                                                           */
/* Configures timer0 as time base for RC5 decoding and enables port A        */
/* interrupt on change.                                                      */
/* Main loop checks if a RC5 code has been received and processes the code   */
/* in the switch-case statement                                              */
/*****************************************************************************/
/* NOTE: Currently it only works if PIC is reset after programming? */
 void main()
{
   unsigned int16 rc5code;
   unsigned int rc5cmd;

   setup_comparator(NC_NC);      // All Ports Digital

    /* FOSC/4 is timer source */
   
    /* Original Configuration:
    /* FOSC = 20MHz => 5MHz, i.e. timer increment every t = 1/(FOSC/4) = 200ns */
    /* with prescaler of 128 timer will increment every 25.6us */
   
    // 16F676 Running at Internal 4 Mhz Configuration:
    // Timer0 Registers:
   // Prescaler=1:1; TMR0 Preset=230; Freq=38,461.53846Hz; Period=26.00 µs
    setup_timer_0(RTCC_INTERNAL);
    set_timer0(230);
   
   
    // TRIS Ports set by #use fixed_io in RC5 IR Remote.h
    /* read port A to clear mismatch condition */
    input_a();                     
   
    /* configure port A interrupt on change */
    clear_interrupt(INT_RA4);        /* clear port A interrupt flag */
    enable_interrupts(INT_RA4);     /* enable RA4 interrupt on change */
   
    // Setup Timer0 Interrupt
    clear_interrupt(INT_TIMER0);
    enable_interrupts(INT_TIMER0);
   
   
    /* global interrupt enable */
    enable_interrupts(GLOBAL);
   
    // Main Loop
    while (1)
    {
      /* check if new data is available */
        if (RC5_CodeReady())
        {
            /* get code */
            rc5code = RC5_GetCode();
           
            // Extract command from RC5 code
            rc5cmd = RC5_GetCmd(rc5code);
           
           switch (rc5cmd)
           {
               case RC5_NUMERIC_KEY_0:
                    RL1 = ~RL1;
                    break;
                 
                 case RC5_NUMERIC_KEY_1:
                    RL2 = ~RL2;
                    break;
                 
                 case RC5_NUMERIC_KEY_2:
                    RL3 = ~RL3;
                    break;
                 
                 case RC5_NUMERIC_KEY_3:
                    RL4 = ~RL4;
                    break;
                 
                 case RC5_NUMERIC_KEY_4:
                    RL5 = ~RL5;
                    break;
                   
                 case RC5_NUMERIC_KEY_5:
                    RL6 = ~RL6;
                    break;
                   
                 case RC5_NUMERIC_KEY_6:
                    RL7 = ~RL7;
                    break;
                   
                 case RC5_NUMERIC_KEY_7:
                    RL8 = ~RL8;
                    break;
                   
                 case RC5_NUMERIC_KEY_8:
                    RL1 = 1;
                    RL2 = 1;
                    RL3 = 1;
                    RL4 = 1;
                    RL5 = 1;
                    RL6 = 1;
                    RL7 = 1;
                    RL8 = 1;
                    break;
                     
                 case RC5_NUMERIC_KEY_9:
                    RL1 = 0;
                    RL2 = 0;
                    RL3 = 0;
                    RL4 = 0;
                    RL5 = 0;
                    RL6 = 0;
                    RL7 = 0;
                    RL8 = 0;
                    break;
                   
         }   
        }
       
        /* this function increments the RC5 timeout timer */
        /* NOTE: Decoding will also work without calling this function, but */
        /*       it could happen that RC5 codes are sometimes not getting */
        /*       recognized because of decoding state machine stucks due */
        /*       to erroneous RC5 signal. */
        RC5_TimeoutIncrement();   
   }
   
}


I'm doing right ?
_________________
sahu
sahu77



Joined: 08 Sep 2011
Posts: 202

View user's profile Send private message

PostPosted: Sun Oct 09, 2011 10:11 am     Reply with quote

it is not work , pl help, me .
_________________
sahu
picpgm



Joined: 28 Dec 2010
Posts: 6

View user's profile Send private message

PostPosted: Sun Oct 09, 2011 10:32 am     Reply with quote

Hi,
is the Port-Change interrupt working properly? I.e. is the LED toggling if you press a button on your IR remote control?
Does your remote control send RC5 code?
sahu77



Joined: 08 Sep 2011
Posts: 202

View user's profile Send private message

PostPosted: Sun Oct 09, 2011 1:21 pm     Reply with quote

picpgm wrote:
Hi,
is the Port-Change interrupt working properly? I.e. is the LED toggling if you press a button on your IR remote control?
Does your remote control send RC5 code?


yes my remote control send RC5 code (device address = 00 \ command = as numeric button press)
& Port-Change interrupt working properly.
_________________
sahu
picpgm



Joined: 28 Dec 2010
Posts: 6

View user's profile Send private message

PostPosted: Sun Oct 09, 2011 1:35 pm     Reply with quote

Your problem is that you restart the timer to get an interrupt every 26us. But the algorithm needs a free running timer! I.e. it needs to start with 0 and overflow after reaching 0xFF.
This is because the algorithm uses the hardware timer value to calculate the time difference between RC5 input pin changes, hence it must be a free running timer.

So if your PIC is running at 4MHz, you will have an timer increment every 1us and hence will overflow every 256us which is too fast. We need a timer which runs longer than a RC5 bit time. So I would suggest to have at least 2 times the RC5 bit time as timer range. If you e.g. use a prescaler of 32 you will get a timer range of 32us * 256 = 8.192ms.

To solve the problem, remove your timer interrupt service routine and disable the timer interrupt.
Further, configure a prescaler of 32 for timer 0.

Code:
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32);


Finally, to inform the RC5 driver about the timer resolution, update the following define accordingly:

Code:
#define RC5_TICKS_PER_MS      (1000/32)     /* timer increments every 32us, i.e. around 31 ticks per millisecond  */


This should solve the problem.
sahu77



Joined: 08 Sep 2011
Posts: 202

View user's profile Send private message

PostPosted: Mon Oct 10, 2011 10:26 am     Reply with quote

picpgm wrote:
Your problem is that you restart the timer to get an interrupt every 26us. But the algorithm needs a free running timer! I.e. it needs to start with 0 and overflow after reaching 0xFF.
This is because the algorithm uses the hardware timer value to calculate the time difference between RC5 input pin changes, hence it must be a free running timer.

So if your PIC is running at 4MHz, you will have an timer increment every 1us and hence will overflow every 256us which is too fast. We need a timer which runs longer than a RC5 bit time. So I would suggest to have at least 2 times the RC5 bit time as timer range. If you e.g. use a prescaler of 32 you will get a timer range of 32us * 256 = 8.192ms.

To solve the problem, remove your timer interrupt service routine and disable the timer interrupt.
Further, configure a prescaler of 32 for timer 0.

Code:
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32);


Finally, to inform the RC5 driver about the timer resolution, update the following define accordingly:

Code:
#define RC5_TICKS_PER_MS      (1000/32)     /* timer increments every 32us, i.e. around 31 ticks per millisecond  */


This should solve the problem.


no profit problem is same .
_________________
sahu
picpgm



Joined: 28 Dec 2010
Posts: 6

View user's profile Send private message

PostPosted: Mon Oct 10, 2011 10:40 am     Reply with quote

Have you also removed the following code pieces?

Code:
/*****************************************************************************/
/* Interrupt_TIMER0                                                          */
/*                                                                           */
/* Timer0 Needs to be executed every 26 us                                   */
/* Used to decode RC5 IR signal.                                             */
/*****************************************************************************/
#INT_TIMER0
void Interrupt_Timer0(void)
{
   //Reset Timer to execute next 26 us
   set_timer0(230);
   clear_interrupt(INT_TIMER0);
}


and

Code:
    // Setup Timer0 Interrupt
    clear_interrupt(INT_TIMER0);
    enable_interrupts(INT_TIMER0);


What is the crystal speed of your PIC, 4MHz?

Please post your modified code again. Thanks.
sahu77



Joined: 08 Sep 2011
Posts: 202

View user's profile Send private message

PostPosted: Mon Oct 10, 2011 12:30 pm     Reply with quote

picpgm wrote:
Have you also removed the following code pieces?

Code:
/*****************************************************************************/
/* Interrupt_TIMER0                                                          */
/*                                                                           */
/* Timer0 Needs to be executed every 26 us                                   */
/* Used to decode RC5 IR signal.                                             */
/*****************************************************************************/
#INT_TIMER0
void Interrupt_Timer0(void)
{
   //Reset Timer to execute next 26 us
   set_timer0(230);
   clear_interrupt(INT_TIMER0);
}


and

Code:
    // Setup Timer0 Interrupt
    clear_interrupt(INT_TIMER0);
    enable_interrupts(INT_TIMER0);


What is the crystal speed of your PIC, 4MHz?

Please post your modified code again. Thanks.


now
Code:
/*** HISTORY OF CHANGE *********************************************************
 *
 *   07.10.2011 Initial Version
 *
 *
 *
 *
 ******************************************************************************/
#include <RC5 IR Remote.h>
#include "types.h"

/* --- RC5 driver configuration --- */
#define RC5_DATA_PIN          PIN_A4        /* IR sensor (SFH5110-36) connected to RB1 */
#define RC5_TICKS_PER_MS      (1000/32)      /* timer increments every 31.25 us */
                                            /* i.e. around 1000 ticks per millisecond */
#define RC5_GetTimer()        get_timer0()  /* timer0 shall be used for RC5 decoding */
                         

/* --- macros to switch on/off LED --- */
#define Led_On()        output_high(PIN_A0)
#define Led_Off()       output_low(PIN_A0)
 
/* RC5 driver include */
#include <RC5_driver.h>

/*******************
//PORT C Register = 0x07
//PORT A Register = 0x05
*********************/
#BIT RL1 = 0x07.0
#BIT RL2 = 0x07.1
#BIT RL3 = 0x07.2
#BIT RL4 = 0x07.3
#BIT RL5 = 0x07.4
#BIT RL6 = 0x07.5
#BIT RL7 = 0x05.1
#BIT RL8 = 0x05.2

/******************************************************************************
 Key Codes
 *****************************************************************************/
#define RC5_NUMERIC_KEY_0 0x00 /* NUMERIC KEY 0 */
#define RC5_NUMERIC_KEY_1 0x01 /* NUMERIC KEY 1 */
#define RC5_NUMERIC_KEY_2 0x02 /* NUMERIC KEY 2 */
#define RC5_NUMERIC_KEY_3 0x03 /* NUMERIC KEY 3 */
#define RC5_NUMERIC_KEY_4 0x04 /* NUMERIC KEY 4 */
#define RC5_NUMERIC_KEY_5 0x05 /* NUMERIC KEY 5 */
#define RC5_NUMERIC_KEY_6 0x06 /* NUMERIC KEY 6 */
#define RC5_NUMERIC_KEY_7 0x07 /* NUMERIC KEY 7 */
#define RC5_NUMERIC_KEY_8 0x08 /* NUMERIC KEY 8 */
#define RC5_NUMERIC_KEY_9 0x09 /* NUMERIC KEY 9 */

/*****************************************************************************/
/* Interrupt_RA                                                              */
/*                                                                           */
/* Port A change interrupt service routine.                                  */
/* Used to decode RC5 IR signal.                                             */
/*****************************************************************************/
#INT_RA
void Interrupt_RA(void)
{
   Led_On();
   RC5_InterruptHandler();
   Led_Off();
   
   clear_interrupt(INT_RA4);
}

/*****************************************************************************/
/* main                                                                      */
/*                                                                           */
/* Configures timer0 as time base for RC5 decoding and enables port A        */
/* interrupt on change.                                                      */
/* Main loop checks if a RC5 code has been received and processes the code   */
/* in the switch-case statement                                              */
/*****************************************************************************/
/* NOTE: Currently it only works if PIC is reset after programming? */
 void main()
{
   unsigned int16 rc5code;
   unsigned int rc5cmd;

   setup_comparator(NC_NC);      // All Ports Digital

    /* FOSC/4 is timer source */
   
    /* Original Configuration:
    /* FOSC = 20MHz => 5MHz, i.e. timer increment every t = 1/(FOSC/4) = 200ns */
    /* with prescaler of 128 timer will increment every 25.6us */
   
    // 16F676 Running at Internal 4 Mhz Configuration:
    // Timer0 increments every 1 us (4 Mhz/4 = 1 Mhz)
    setup_timer_0(RTCC_INTERNAL | RTCC_DIV_32);
   
   
    // TRIS Ports set by #use fixed_io in RC5 IR Remote.h
    /* read port A to clear mismatch condition */
    input_a();                     
   
    /* configure port A interrupt on change */
    clear_interrupt(INT_RA);        /* clear port A interrupt flag */
    enable_interrupts(INT_RA);     /* enable RA4 interrupt on change */
     
    /* global interrupt enable */
    enable_interrupts(GLOBAL);
   
    // Main Loop
    while (1)
    {
      /* check if new data is available */
        if (RC5_CodeReady())
        {
            /* get code */
            rc5code = RC5_GetCode();
           
            // Extract command from RC5 code
            rc5cmd = RC5_GetCmd(rc5code);
           
           switch (rc5cmd)
           {
               case RC5_NUMERIC_KEY_0:
                    RL1 = ~RL1;
                    break;
                 
                 case RC5_NUMERIC_KEY_1:
                    RL2 = ~RL2;
                    break;
                 
                 case RC5_NUMERIC_KEY_2:
                    RL3 = ~RL3;
                    break;
                 
                 case RC5_NUMERIC_KEY_3:
                    RL4 = ~RL4;
                    break;
                 
                 case RC5_NUMERIC_KEY_4:
                    RL5 = ~RL5;
                    break;
                   
                 case RC5_NUMERIC_KEY_5:
                    RL6 = ~RL6;
                    break;
                   
                 case RC5_NUMERIC_KEY_6:
                    RL7 = ~RL7;
                    break;
                   
                 case RC5_NUMERIC_KEY_7:
                    RL8 = ~RL8;
                    break;
                   
                 case RC5_NUMERIC_KEY_8:
                    RL1 = 1;
                    RL2 = 1;
                    RL3 = 1;
                    RL4 = 1;
                    RL5 = 1;
                    RL6 = 1;
                    RL7 = 1;
                    RL8 = 1;
                    break;
                     
                 case RC5_NUMERIC_KEY_9:
                    RL1 = 0;
                    RL2 = 0;
                    RL3 = 0;
                    RL4 = 0;
                    RL5 = 0;
                    RL6 = 0;
                    RL7 = 0;
                    RL8 = 0;
                    break;
                   
         }   
        }
       
        /* this function increments the RC5 timeout timer */
        /* NOTE: Decoding will also work without calling this function, but */
        /*       it could happen that RC5 codes are sometimes not getting */
        /*       recognized because of decoding state machine stucks due */
        /*       to erroneous RC5 signal. */
        RC5_TimeoutIncrement();   
   }
   
}


it is OK ?
Code:
#include <16F676.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOBROWNOUT               //No brownout reset

#use delay(int=4000000)


#use fixed_IO(A_outputs = PIN_A0,PIN_A1,PIN_A2,PIN_A5)
#use fixed_IO(C_outputs = PIN_C0,PIN_C1,PIN_C2,PIN_C3,PIN_C4,PIN_C5)

not use xtal , use internal osc use 4mh
_________________
sahu
sahu77



Joined: 08 Sep 2011
Posts: 202

View user's profile Send private message

PostPosted: Fri Oct 14, 2011 12:33 pm     Reply with quote

pls help me
_________________
sahu
picpgm



Joined: 28 Dec 2010
Posts: 6

View user's profile Send private message

PostPosted: Sat Oct 15, 2011 1:17 am     Reply with quote

From code point of view it looks ok. Could you post a schematic of your hardware?

You can also try to increase the range of a valid bit time. To do that, update the following lines in the driver code:

Code:
#define RC5_HALF_BIT_TIME_MIN   (((RC5_TICKS_PER_MS) * 500) / 1000)
#define RC5_HALF_BIT_TIME_MAX   (((RC5_TICKS_PER_MS) * 1600) / 1000)
sahu77



Joined: 08 Sep 2011
Posts: 202

View user's profile Send private message

PostPosted: Sat Oct 15, 2011 10:23 am     Reply with quote

picpgm wrote:
From code point of view it looks ok. Could you post a schematic of your hardware?

You can also try to increase the range of a valid bit time. To do that, update the following lines in the driver code:

Code:
#define RC5_HALF_BIT_TIME_MIN   (((RC5_TICKS_PER_MS) * 500) / 1000)
#define RC5_HALF_BIT_TIME_MAX   (((RC5_TICKS_PER_MS) * 1600) / 1000)


Hope can post here schematic of my hardware ? not fond option here.
Pls help me.
_________________
sahu
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sat Oct 15, 2011 2:33 pm     Reply with quote

To post a schematic here you first have to upload the picture to a specialized picture website like imageshack.us Then on this forum you post the picture using the IMG button with a link to the picture at imageshack.
sahu77



Joined: 08 Sep 2011
Posts: 202

View user's profile Send private message

PostPosted: Sun Oct 16, 2011 1:51 am     Reply with quote

picpgm wrote:
From code point of view it looks ok. Could you post a schematic of your hardware?
You can also try to increase the range of a valid bit time. To do that, update the following lines in the driver code:

schematic of my hardware
http://imageshack.us/photo/my-images/812/rxcm.png/
_________________
sahu
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group