Friday, January 23, 2015

Philips RC5 & LG TV Remote Control Decoder

Control your PIC microcontroller from Philips RC5 remote control or LG TV remote control
Remote control decoder using PIC16F877A
This topic talks about how to decode remote controls based on Philips RC5 protocol and some LG tvs protocol.
about the rc5 protocol: Wikipedia
The protocol used by lg tv remote controls is similar to the Philips RC5  protocol except the length of the bits. The carrier of both RC5 and our lg protocol has a frequency of 36KHz, and the length of each transmitted bit is 1778us for RC5 protocol and about 1620 us for the protocol used by LG in some televisions.
The tow  protocols can be divided into 4 parts:
1-start bit,
2-Toggle bit,
3-Address (5 bits),
4-Command (6 bits).
RC5 and LG TV remote controls decoder circuit:
The circuit of our system is shown below:

rc5 lgtv remote control decoder pic16f877a mikroc code

This system is designed to decode the Philips RC5 protocol and a protocol similar to the RC5 which is used in many equipments specially televisions like LG.
As we see in the circuit schematic diagram there is a switch, this switch allows us chose between the tow protocols. Note that you will have a wrong result if you want to decode  a RC5 protocol using LG TV decoder and vise versa.
RC5 and LG TV remote controls decoder mikroC code:
The code of this project is written using mikroc pro for pic compiler. The crystal used is 12MHz.
The software interrupts the microcontroller when there is an ir signal received. After receiving the signal the software detects if the received signal is an RC5 or similar protocol.
To set and clear individual bits in mikroC I used the following statements:

 A|= (1 << ( A));   //Set bit (B) of A
 A&=~(1 << (B));}  //Clear bit (B) of A

If the received signal is an RC5 protocol, the software starts reading the bits (toggle bit, address, and command) and then display the result on a 16X2 LCD.
The total MikroC code is as the following:

//PIC16F877A RC5 & LG Remote control decoder MikroC code
//Written by: BENCHEROUDA Okba
//electronnote@gmail.com
//Used crystal: 12MHz
//The switch connected to RB1 is for toggle between
//       the rc5 protocol and lg protocol
//Use at your own risk


 // LCD module connections
sbit LCD_RS at RD5_bit;
sbit LCD_EN at RD4_bit;
sbit LCD_D4 at RD3_bit;
sbit LCD_D5 at RD2_bit;
sbit LCD_D6 at RD1_bit;
sbit LCD_D7 at RD0_bit;
sbit LCD_RS_Direction at TRISD5_bit;
sbit LCD_EN_Direction at TRISD4_bit;
sbit LCD_D4_Direction at TRISD3_bit;
sbit LCD_D5_Direction at TRISD2_bit;
sbit LCD_D6_Direction at TRISD1_bit;
sbit LCD_D7_Direction at TRISD0_bit;
// End LCD module connections

unsigned short ir_read, ir_sw,j, toggle, address=0, command=0;
unsigned char  *text, mytext[4];
 void Interrupt(){               //External interrupt occured
 //Check if the received signal is RC5 protocol
  delay_us(500);
  if(PORTB.F0==0){
  delay_us(900);
  if(PORTB.F0==1){
  delay_us(900);
  if(PORTB.F0==0){
  delay_us(1778); ir_read = 1;
  INTCON  = 0;                //Disabe the external interrupt
 }}}
 INTF_bit = 0;                //Clear Interrupt flag
}
   //Display the results in 1602 LCD
  void display (){
   Lcd_Cmd(_LCD_CLEAR);            //Clear LCD
   if(ir_sw.F0 == 0)  text = " RC5 :" ;
   else               text = "LG TV:" ;
   Lcd_Out(1, 1, text);
   text = "Tgl:" ;
   Lcd_Out(1, 9, text);
   text = "Ads:" ;
   Lcd_Out(2, 3, text);
   text = "Cmd:" ;
   Lcd_Out(2, 10, text);
   ByteToStr(toggle, mytext);   Lcd_Out(1, 13, Ltrim(mytext));
   ByteToStr(address, mytext);  Lcd_Out(2, 7, Ltrim(mytext));
   ByteToStr(command, mytext);  Lcd_Out(2, 14, Ltrim(mytext));
  }
 void main() {
 OPTION_REG = 0;
 TRISB = 3;
 Lcd_Init();
 Lcd_Cmd(_LCD_CURSOR_OFF);        // cursor off
 Lcd_Cmd(_LCD_CLEAR);             // clear LCD
 text = "RC5 LGTV Remote" ;
 Lcd_Out(1, 1, text);
 text = "control decoder" ;
 Lcd_Out(2, 1, text);
 delay_ms(1000);
 INTCON         = 0x90;   //External Interrupt enabled

while(1){
while(!ir_read){         //Wait until IR RC5 protocl received
if(Button(&PORTB, 1, 100, 0)){Lcd_Cmd(_LCD_CLEAR);
 ir_sw.F0 = ~ ir_sw.F0;
 display();
  }}
 
ir_read = 0;
for(j = 0; j < 12; j++){
if(j == 0){
if (PORTB.F0 == 0) toggle = 1;
else toggle = 0;}
else {
if(j < 6){                               //Read address bits
if (PORTB.F0 == 0) address|= (1<<( 5 - j)); //Set bit (5-j)
if (PORTB.F0 == 1) address&=~(1<<(5 - j));} //Clear bit (5-j)
else {                                   //Read command bits
if (PORTB.F0 == 0) command|= (1<<( 11 - j));//Set bit (11-j)
else               command&=~(1<<(11 - j)); //Clear bit (11-j)
                                       }}
if(ir_sw.F0==0)                           //RC5 protocol
  delay_us(1778);
else                                          //LG protocol
  delay_us(1620);}
display();
INTCON  = 0x90;                 //External Interrupt enabled
 }
}

RC5 and LG TV remote controls decoder video:
The following video shows the project in a hardware circuit: