Embedded Electronics Tutorials, Coding and lot more

TV remote decoder (NEC protocol decoder)

Today there are many remotes available in the market. They are different as per their target applications. Even though they are from different manufacturers, but they follow some standard protocols such as RC5, RC6 or NEC protocol. Here i am showing how to decode NEC protocol remote. I am using a PIC16F micrcontroller. NEC is the toughest protocol to decode, hence secure also. You can see full video demo here.

remote

NEC protocol:

  • 8 bit address and 8 bit command length
  • Address and command are transmitted twice for reliability
  • Pulse distance modulation
  • Carrier frequency of 38kHz
  • Bit time of 1.125ms or 2.25ms

The NEC protocol uses pulse distance encoding of the bits. Each pulse is a 560µs long 38kHz carrier burst (about 21 cycles). A logical “1” takes 2.25ms to transmit, while a logical “0” is only half of that, being 1.125ms. The recommended carrier duty-cycle is 1/4 or 1/3.

The picture above shows a typical pulse train of the NEC protocol. With this protocol the LSB is transmitted first.

NECMessageFrame

necmodulation

TSOP 1738 sensor:

TSOP1738 is an IR receiver which is widely used in so many electronic products for receiving and demodulating the infrared signals. The received demodulated signals can be easily decoded by a microcontroller. It supports RC5, RC6 code, Sony format (SIRCS), NEC code, Sharp code.

2685163789_d3ba85024d

I have written code in C to toggle 2 LEDs as per the even and odd buttons on the remote

Here code is explained briefly:

#define LED RC4
#define LED1 RC5
#define SWITCH RB0

//MAIN PROGRAM BEGINS

UINT8 scanvalues[16] = {0};

int main(void)
{
unsigned char array[17] = {0};
int Count = 0;
UINT16_VAL Inputs;
OSCCONbits.IRCF = 0b111;
while (!OSCCONbits.HTS);
ANSEL = 0x00;
ANSELH = 0x00;
TRISA = 0x00;
TRISB = 0x01;
TRISC = 0x00;
TRISD = 0x00;
TRISBbits.TRISB0 = 1;
PORTBbits.RB0 = 0;
UINT8 time = 0;
T1CON = 0b00000001;
T1CONbits.T1CKPS = 0b01;
BOOL start_bit = 0;
UINT16 command = 0;
LED1 = 0;
UINT8 index = 0;
MainSystemInitialize();
LCDClear();
LCDWriteString(” ** Welcome ** “);
__delay_ms(1500);
LCDClear();
LCDWriteString(“NEC Protocol”);
LCDRow2();
LCDWriteString(“Remote Decoder”);
__delay_ms(1500);
LED = 0;
LCDClear();
LCDWriteString(“Ready to decode”);
__delay_ms(50);

while (1)
{
TMR1 = 0X00;
Count = 0;
while (SWITCH);
Count = TMR1;

if ((Count > 4450) && (Count < 4550))
{
start_bit = 1; // set flag
command = 0; // reset old command value
//LED = 1;
index = 0;
}

else if (start_bit)
{
if (index > 15)
{
if ((Count >= 1400) && (Count <= 1800))
{
command |= 1;
if (index > 16)
command <<= 1;
}
else if ((Count >= 450) && (Count <= 700))
{
if (index > 16)
command <<= 1;
}
}
}

index++;

while (!SWITCH); // wait until sensor flips

if (index == 32) // a full 8 bit command received
{
LCDClear();
Inputs.Val = command;
scanvalues[0] = (0xf & (command >> 12)) + 48;
scanvalues[1] = (0xf & (command >> 8)) + 48;
scanvalues[2] = (0xf & (command >> 4)) + 48;
scanvalues[3] = (0xf & (command)) + 49;

if(scanvalues[0] > ‘9’)
{
scanvalues[0] = scanvalues[0] + 7;
}

if(scanvalues[1] > ‘9’)
{
scanvalues[1] = scanvalues[1] + 7;
}

if(scanvalues[2] > ‘9’)
{
scanvalues[2] = scanvalues[2] + 7;
}

if(scanvalues[3] > ‘9’)
{
scanvalues[3] = scanvalues[3] + 7;
}

if(strncmp(scanvalues,”48B7″, 4) == 0)
{
LCDWriteString(“Power”);
LED = 1;
LED1 = 0;
}
if(strncmp(scanvalues,”58A7″, 4) == 0)
{
LCDWriteString(“Mode”);
LED = 0;
LED1 = 1;
}

if(strncmp(scanvalues,”7887″, 4) == 0)
{
LCDWriteString(“Mute”);
LED = 1;
LED1 = 0;
}
if(strncmp(scanvalues,”807F”, 4) == 0)
{
LCDWriteString(“Play/Stop”);
LED = 0;
LED1 = 1;
}
if(strncmp(scanvalues,”40BF”, 4) == 0)
{
LCDWriteString(“Previous”);
LED = 1;
LED1 = 0;
}
if(strncmp(scanvalues,”C03F”, 4) == 0)
{
LCDWriteString(“Next”);
LED = 0;
LED1 = 1;
}
if(strncmp(scanvalues,”20DF”, 4) == 0)
{
LCDWriteString(“EQ”);
LED = 1;
LED1 = 0;
}
if(strncmp(scanvalues,”A05F”, 4) == 0)
{
LCDWriteString(“VOL-“);
LED = 0;
LED1 = 1;
}
if(strncmp(scanvalues,”609F”, 4) == 0)
{
LCDWriteString(“VOL+”);
LED = 1;
LED1 = 0;
}
if(strncmp(scanvalues,”E01F”, 4) == 0)
{
LCDWriteString(“”0″”);
LED = 0;
LED1 = 1;
}
if(strncmp(scanvalues,”10EF”, 4) == 0)
{
LCDWriteString(“Repeat”);
LED = 1;
LED1 = 0;
}
if(strncmp(scanvalues,”906F”, 4) == 0)
{
LCDWriteString(“U/SD”);
LED = 0;
LED1 = 1;
}
if(strncmp(scanvalues,”50AF”, 4) == 0)
{
LCDWriteString(“”1″”);
LED = 1;
LED1 = 0;
}
if(strncmp(scanvalues,”D827″, 4) == 0)
{
LCDWriteString(“”2″”);
LED = 0;
LED1 = 1;
}
if(strncmp(scanvalues,”F807″, 4) == 0)
{
LCDWriteString(“”3″”);
LED = 1;
LED1 = 0;
}
if(strncmp(scanvalues,”30CF”, 4) == 0)
{
LCDWriteString(“”4″”);
LED = 0;
LED1 = 1;
}
if(strncmp(scanvalues,”B04F”, 4) == 0)
{
LCDWriteString(“”5″”);
LED = 1;
LED1 = 0;
}
if(strncmp(scanvalues,”708F”, 4) == 0)
{
LCDWriteString(“”6″”);
LED = 0;
LED1 = 1;
}
if(strncmp(scanvalues,”00FF”, 4) == 0)
{
LCDWriteString(“”7″”);
LED = 1;
LED1 = 0;
}
if(strncmp(scanvalues,”F00F”, 4) == 0)
{
LCDWriteString(“”8″”);
LED = 0;
LED1 = 1;
}
if(strncmp(scanvalues,”9867″, 4) == 0)
{
LCDWriteString(“”9″”);
LED = 1;
LED1 = 0;
}
LCDWriteString(” Button”);
__delay_ms(10);

index = 0;

start_bit = 0; // reset values for another round
}
}
return 0;
}

I designed a PCB and got it fabricated. You can see the final design below:

NEC decoder PIC micrcontroller

Sharing is caring

1 Comment

  1. Sandheep

    Its a great job.
    I couldn’t work out with this can you provide the complete main file.

Leave a Reply

Your email address will not be published. Required fields are marked *

© 2023 EMBEDDED TWEAKS

Theme by Anders NorenUp ↑

Follow Me

Get the latest posts right delivered in you mailbox

%d bloggers like this: