View previous topic :: View next topic |
Author |
Message |
sarmad_101
Joined: 17 Jun 2010 Posts: 12
|
PIC RC5 Code |
Posted: Thu Jul 08, 2010 11:55 pm |
|
|
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
|
|
|
sahu77
Joined: 08 Sep 2011 Posts: 202
|
Re: PIC RC5 Code |
Posted: Sat Oct 08, 2011 1:15 pm |
|
|
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
|
|
Posted: Sun Oct 09, 2011 10:11 am |
|
|
it is not work , pl help, me . _________________ sahu |
|
|
picpgm
Joined: 28 Dec 2010 Posts: 6
|
|
Posted: Sun Oct 09, 2011 10:32 am |
|
|
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
|
|
Posted: Sun Oct 09, 2011 1:21 pm |
|
|
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
|
|
Posted: Sun Oct 09, 2011 1:35 pm |
|
|
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
|
|
Posted: Mon Oct 10, 2011 10:26 am |
|
|
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
|
|
Posted: Mon Oct 10, 2011 10:40 am |
|
|
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
|
|
Posted: Mon Oct 10, 2011 12:30 pm |
|
|
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
|
|
Posted: Fri Oct 14, 2011 12:33 pm |
|
|
pls help me _________________ sahu |
|
|
picpgm
Joined: 28 Dec 2010 Posts: 6
|
|
Posted: Sat Oct 15, 2011 1:17 am |
|
|
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
|
|
Posted: Sat Oct 15, 2011 10:23 am |
|
|
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
|
|
Posted: Sat Oct 15, 2011 2:33 pm |
|
|
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
|
|
Posted: Sun Oct 16, 2011 1:51 am |
|
|
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 |
|
|
|