Imagino Title
Imagino Title
 

Sample IR Receiver code

This code was developed to be substantially smaller than the various IR receiver libraries. It is intended solely for use with the two standard miniature Chinese generic remote controls. (These are the one shown in various Imagino photos and the "Car MP3 player" one).

char get_IR()
{
  char IRCodeLookup[30] = "efgd`c'5)69-8(‹zr";
  char IRNames[30] = "123456789*0#ULPRD";
  char tmp = '\0';

  if (IRResult > 0) // Result available
  {
    IRMode = 2;
    int qq = IRResult >> 16; // Check for & remove preamble
    if (qq == 0x40FF || qq == 0x20FF)
    {
      byte result = (IRResult & 0x0000FF00) >> 8;
      result = bit_reverse(result);
      result += 32;  // shift into visible characters
      char* r2 = strchr(IRCodeLookup, result);
      if (r2 != NULL)
      {
        tmp = IRNames[r2 - IRCodeLookup];
        if (key_click) tone(13, 600, 2);
      }
    }
    IRResult = 0;
    IRMode = 1;
  }
  return (tmp);
}
This routine returns a character representing the key pressed, or '\0' (NULL) if no key is currently pressed.

These two character arrays hold the codes being matched from the received IR string, and the characters that they will map on to.

IRResult is the presently active key received from the Interupt Service Routine.

The incoming code is represented as a series of 64 bits within a LONG variable type. This is manipulated to extract 8 bits that provide a distinct code for each key.

A quick character lookup returns the matching character code on the following basis:-

0 - 9, *, # - provide the name of their keys directly
U/L/R/D = Arrow keys - Up, Left, Right and Down
P = OK


void ISR_IR()
// Interrupt Service Routine for IR Remote.
{
  if (IRMode != 2)
  {
    if (IRMode == 0 && IRCount < 32)
    {
      int q = digitalRead(PIN_IR);
      long dly = micros() - micro_interval;
      micro_interval = micros();
      if (dly > 5000)
      {
        IRMode = 1;  // Result available
      }
      else if (dly > 1500)
      {
        IRBuf <<= 1;
        IRBuf += 1;
      }
      else if (dly > 500)
      {
        IRBuf <<= 1;
      }
      if (IRMode == 0)
        IRCount++;
    }
    else
    { // All done, so make result available and await next code
      IRResult = IRBuf;
      IRBuf = 0;
      IRCount = 0;
      IRMode = 0;
    }
  }
}
This is the Interrupt Service routine that needs to be attached to the incoming IR I/O pin (which is 2 in the Imagino standard).

It times the interval between pulses using the system timer functions, and compiles the short and long pulses into a 64-bit string for each incoming key press.


void setup()
...
  attachInterrupt(digitalPinToInterrupt(2), ISR_IR, FALLING);
...
Initialise the ISR in Setup (or elsewhere).


long micro_interval = micros();
unsigned long IRBuf = 0;
unsigned long IRResult = 0;
int IRMode = 0;
int IRCount = 0;
And declare these global variables.


These code examples are provided without warranty. Every care has been taken to ensure that they are fully functional, but no liability can be accepted for loss or damage incurred during their use.

© Copyright 2017 WebinaWeek ltd. trading as The Imagino Project, 14/ME10 2GE Callers by appointment only.
0800 612 8875