Panasonic TV IR decoder

Two versions of the IR decoder are implemented and described here:
1. A dedicated IR decoder for the antenna switching circuit project.
2. The stand alone IR decoder with a display to read the IR codes.

1. Panasonic TV infrared decoder for the antenna switching.
For the antenna switching circuit , I needed a piece of electronics to decode specific IR codes from Panasonic TV remotes:

To measure the output of the remotes, an infrared receiver is needed. I used a Sharp GP1UX511QS 38 KHz infrared receiver, but any 38 KHz infrared receiver should do the job.
With an oscilloscope I got the following screens for the remote buttons: “TV”, “EXIT”, “eHelp” and “lastView”

The transmitted bit pattern has a syncronization part, a 16 bit address and a 32 bit of data to identify the button being pressed.
For each button two identical bit patterns are transmitted, and 3 times for the red “Power” button.
The syncronization part is the long “LOW” followed by “HIGH”:

The following 48 bits ( 16 bit address + 32 bit data ) is encoded like this:
0 : A short “LOW” followed by a short “HIGH”
1 : A short “LOW” followed by a long “HIGH”
By looking through the bit patterns for the “TV”, “EXIT” and “eHelp” buttons, I got the following data values in hexadecimal:
“TV” button: Address : 4004 data: 01400C4D
“EXIT” button: Address : 4004 data: 0100CBCA
“eHelp” button: Address : 4004 data: 01003534
“Last view” button: Address : 4004 data: 0100ECED
I decided to use an 8 pin Attiny25 microcontroller to do the decoding of the specific bit patterns. The schematic is clipped from the antenna switch project.

The free Atmel Studio 7 from was used for
compiling the C code. An AVR-ISP MKII programmer was used to flash the Attiny25.
The Attiny25 uses the internal clock generator at 1 MHz with the DIV8 fuse enabled.
The program to decode the bit patterns uses port interrupt at PB2 on negative going edges (INT0). Timer 0 is set to be free running with a divide by 64 prescaler, providing timer intervals of 64 usec.:
TCCR0A = 0;
TCCR0B = 3<<CS00; // Prescaler /64 , 64 usec. timer
MCUCR |= (1<<ISC01); // Interrupt on falling edge
GIMSK |= _BV(INT0); // Enable external interrupt INT0
sei(); // enable global interrupts
Three global 16 bit variables hold address, dataHigh and DataLow.
volatile unsigned int RecdAddress;
volatile unsigned long RecdDataH;
volatile unsigned long RecdDataL;
The newFrame has a value of 1 when new address and data are
volatile uint8_t newFrame;
The INTO interrupt routine simply measures the elapsed time
( provided by Timer 0 ) from last INT0 interrupt. In case of timer
overflow, the interrupt starts looking for the next syncronization
pattern. When a new frame with address and data is received, the
newFrame variable is set to 1.
ISR(INT0_vect) {
int BitTime = TCNT0;
int Overflow = TIFR & 1<<TOV0;
if (NextBit == 48) // looking for the Panasonic header period
{ // in between 4700 and 5700 usec.
if ((BitTime >= 73) && (BitTime <= 89) && (Overflow == 0))
RecdAddress = 0;
RecdDataH = 0;
RecdDataL = 0;
NextBit = 0;
} // got header, now ready to receive 48 bit data
} else
f ((BitTime > 30) || (Overflow != 0))
NextBit = 48; // max bit period exceeded, restart
f (BitTime > 15) // if bit time > “0”-time, e.g. add “1” into the bit
f (NextBit <= 15) RecdAddress = RecdAddress | ((unsigned int)
f ((NextBit <= 31) && (NextBit > 15)) RecdDataH = RecdDataH |
((unsigned int) 1<<(15-(NextBit-16)));
else RecdDataL = RecdDataL | ((unsigned int) 1<<(15-(NextBit-
if (NextBit == 48) newFrame = 1; // signal to main() to retrieve
}} TCNT0 =
0; // Clear counter
TIFR |= 1<<TOV0; // Clear overflow
GIFR |= 1<<INTF0; // Clear INT0 flag
The complete Attiny25 program is found here: main.c

2. Stand alone Panasonic TV infrared decoder with LCD display
As a spin off from the Attiny25 based IR decoder, I wanted a display to show the Panasonic IR code values instead of reading and translate the code timing from an oscilloscope. The LCD display shows Panasonic TV IR codes for the address (16 bit) and data (2 * 16 bit). The hardware is the Arduino Nano v.3 and a 16*2 character LCD display with the PCF8574 port expander to provide an I2C (TWI) interface. These parts are less than 2 Euro each from

The Sharp GP1UX511QS 38 KHz infrared receiver is connected to the Atmega328P interrupt input, INT0 (PORTD2). To monitor the 9V battery voltage a 1:1 voltage divider with 2 x 4K7 resistors are added to provide 0..4.5V to the A0 ADC input.

The Atmel Studio software for this solution includes I2C and LCD libraries.
The free Atmel Studio 7 from was used to compile the C code.

An AVR-ISP MKII programmer was used to flash the ATmega328P. The ATmega328P clock generator uses the external 16 MHz x-tal on the Arduino Nano board. The program to decode the bit patterns uses port interrupt at PD2 on negative going edges (INT0). Timer 0 is set to be free running with a divide by 1024 prescaler, providing timer intervals of 64 usec.

The complete source code is available here: PanaIR_I2C_LCD


Leave a Reply