InduinoX User Guide - Working with NEC Remotes

The Simple Labs InduinoX Arduino Learners' Kit comes with a small remote, the kind of remote you would find with a MP3 Player / Audio Players. Owing to their size these remotes have spread fast and hence this tutorial on how to decode these manually without using the library. If you want to use the library, check out our previous post on this

These small remotes use the NEC protocol which is a 32-bit protocol and much different from the SIRC Protocol we saw earlier. Here's the signal train of the NEC protocol

The Start Bit is a 9 ms long pulse followed by 4.5 ms space. This is  followed by a burst of 32-bit data. The 32-bit data consists of 8-bits of command and 8-bits of address which are transmitted twice for reliability. The first transmission of 8 bits is inverted when it is being transmitted the next time for increased reliability.


Heres the Pulse Modulation of the NEC Protocol

The Logical '1' is represented by a 560us long 38khz pulse (MARK) followed by a 1690us long LOW signal (SPACE). The Total Duration for the Logical '1' is 2.25us.

The Logical '0' is represented by a 560us long 38khz pulse (MARK) followed by a 560us long LOW signal (SPACE). The Total Duration for the Logical '1' is 1.12us.

So How do we read this?

For our purpose, we can read this as a 16-bit data (8-bit address & 8-bit command)


To read this signal here are the things we need to do
  • Wait till be get the start bit
  • Read the time duration for the subsequent 32bits
  • Sort through the time duration in 4 parts of 8-bits each
  • Calculate 2 values, one from the bits 0-7 and 16-23 and one from bits 8-15 & 24-31
  • Check if these values are equal. If so take the value as valid. if not ignore the value.
Here's the code for a function to read NEC remotes. This function works for the InduinoX board.


int remote()
{
  int val1=0,val2=0, dur[32], i=0, j=0;
  if(pulseIn(15,LOW)>8000)
  {
    for(i=0; i<32;i++)
    {
      dur[i]=pulseIn(15,HIGH);
    }
    
//Value Calculation

    for(i=0,j=0;i<24;i++,j++)
    {
      if(i==8)
         i=16;
      if(dur[i]>1000)
          val1 = val1+ (1<<j);
           
    }
    for(i=8,j=0;i<32;i++,j++)
    {
      if(i==16)
        i=24;
      if(dur[i]<1000)
        val2 = val2+ (1<<j);    
     }
     Serial.println(val1);
     Serial.println(val2);
     if(val1==val2)
       return val1;
     else
       return 0;
  }
  
  return 0;
}