Recongising IR Codes from an IR Remote Control

Hi Guys,

I’m new to Arduino and having a blast. I got the Sainsmart UNO R3 Starter Kit. It’s a brilliant bit of kit but the documentation leaves a LOT to be desired :D, but that ends up being a good thing, as it’s mostly there and just needs some tweaks. You end up learning more.

Right now I’m trying to modify one of the projects from “Chapter 16 Infrared remote control”. It comes with a small IR Remote and I’ve hooked up a simple IR Receiver to the Arduino. When you press a button on the remote it code gets outputted to the Serial Monitor as a HEX value.

I’ve gotten it to work properly, its just that the problem I am having is trying to read what IR Code is being received and then performing an action on it.

I have two variables. 1. ir_code and 2. adrL_code. These are printed to the serial monitor window in the remote_deal() function.

They are both char variables, and I think I am making errors on dealing with hex values. But for the life of me I don’t know how to interact with them. Printing out the hex for adrL_code gives me 42 when I press the 7 button, how do I write an IF Statement to interact with it?

I’ve included the full code but it’s only the VERY TOP PART in remote_deal() that needs dealing with I believe.

Hope you can help,

Adam

#define IR_IN 8 // infrared receive
int Pulse_Width = 0;//storage pulse width
int ir_code = 0x00;// user code value
char adrL_code = 0x00;//Command code
char adrH_code = 0x00;// Command code base minus one's complement

//THIS SHOULD BE THE ONLY FUNCTION TO LOOK AT
void remote_deal(void)// Implement the decoding function
{ // data presentation
Serial.println(ir_code,HEX);//16 Into system show
Serial.println(adrL_code,HEX);//16 Into system show
//HERE IS THE MAIN PROBLEM. I HAVE TWO VARIABLES ir_code and adrL_code 
//I CANT GET THIS IF STATEMENT TO WORK
if ((adrl_code,HEX)==42) { // 42 IS OUTPUTTED IN THE SERIAL LINE WHEN THE NUMBER 7 BUTTON IS PRESSED ON THE REMOTE CONTROL
   Serial.println("Hello 42!!");
}
}

void timer1_init(void)//timer initialization function
{
TCCR1A = 0X00;
TCCR1B = 0X05;//set timer clock source
TCCR1C = 0X00;
TCNT1 = 0X00;
TIMSK1 = 0X00; // Ban timer interrupt overflow
}

char logic_value()//Judgment logic value "0" and "1" son function
{
TCNT1 = 0X00;
while(!(digitalRead(IR_IN))); //if low wait
Pulse_Width=TCNT1;
TCNT1=0;
if(Pulse_Width>=7&&Pulse_Width<=10)//low level 560us
{
while(digitalRead(IR_IN));//if high wait
Pulse_Width=TCNT1;
TCNT1=0;
if(Pulse_Width>=7&&Pulse_Width<=10)//high level 560us
return 0;
else if(Pulse_Width>=25&&Pulse_Width<=27) //high level 1.7ms
return 1;
}
return -1;
}
void pulse_deal()//Receiving address code and command code pulse function
{ 
int i;
int j;
ir_code=0x00;// clear
adrL_code=0x00;// clear
adrH_code=0x00;// clear
// Analysis of the remote control code user code value
for(i = 0 ; i < 16; i++)
{
if(logic_value() == 1) // if 1
ir_code |= (1<<i);//Save key value
}
// Analytical remote control code commands in the code
for(i = 0 ; i < 8; i++)
{
if(logic_value() == 1) // if 1
adrL_code |= (1<<i);//save key value
}
// Analysis of the remote control code user code value
for(j = 0 ; j < 8; j++)
{
if(logic_value() == 1) //if 1
adrH_code |= (1<<j);//save key value
}
}
void remote_decode(void)// Decoding function
{
TCNT1=0X00;
while(digitalRead(IR_IN))// if high wait
{
if(TCNT1>=1563) // When high level lasted for more than 100 ms, shows that at the moment no key press
{
ir_code=0x00ff;// user code value
adrL_code=0x00;// a byte value before Key code
adrH_code=0x00;// a byte value after Key code
return;
}
}
// If high level can’t last for more than 100 ms
TCNT1=0X00;
while(!(digitalRead(IR_IN))); //if low wait
Pulse_Width=TCNT1;
TCNT1=0;
if(Pulse_Width>=140&&Pulse_Width<=141)// 9ms
{
while(digitalRead(IR_IN));//if high wait
Pulse_Width=TCNT1;
TCNT1=0;
if(Pulse_Width>=68&&Pulse_Width<=72)// 4.5ms
{
pulse_deal();
return;
}
else if(Pulse_Width>=34&&Pulse_Width<=36)//2.25ms
{
while(!(digitalRead(IR_IN)));// if low wait
Pulse_Width=TCNT1;
TCNT1=0;
if(Pulse_Width>=7&&Pulse_Width<=10)// 560us
{
return;
}
}
}
}
void setup()
{
Serial.begin(9600);
pinMode(IR_IN,INPUT);// Set infrared receiving pin for input
pinMode(buzzer,OUTPUT);//set digital pin IO OUTPUT
Serial.flush();
}
void loop()
{
timer1_init();//Timer initialization
while(1)
{
remote_decode(); // decode
remote_deal(); // Executive decoding results
  
}
}

Have you considered the IRremote library?. It works well for me. http://github.com/shirriff/Arduino-IRremote

Libraries are good. If you roll-your-own, you can use something like:

  int key = getIRKey();   //Fetch the key
  
  if(key != 0)            //Ignore keys that are zero
  {
    switch(key)
    {
      case 128: Serial.print("1"); break;
      case 129: Serial.print("2"); break;
      case 130: Serial.print("3"); break;
      case 131: Serial.print("4"); break;
      case 132: Serial.print("5"); break;
      case 133: Serial.print("6"); break;
      case 134: Serial.print("7"); break;
      case 135: Serial.print("8"); break;
      case 136: Serial.print("9"); break;
      case 137: Serial.print("0"); break;
      
      case 144: Serial.print("A"); break;  // CH Up
      case 145: Serial.print("B"); break;  // CH Down
      case 146: Serial.print("C"); break;  // VOL Right
      case 147: Serial.print("D"); break;  // VOL Left
      case 148: Serial.print("E"); break;  // Mute
      case 165: Serial.print("F"); break;  // AV/TV
      case 149: Serial.print("P");         // Power == MENU ACTIVE
        //This toggles the statLED every time power button is hit
        if(digitalRead(statLED) != 1)
          digitalWrite(statLED, HIGH);
        else
          digitalWrite(statLED, LOW);
        break;

      //default: Serial.println(key); // for inspection of keycode
    }

128... 129... 130 is the decimal value of the HEX. You can also simply use the HEX directly.

This may be a little help in understanding the Arduino C++ data types: https://gist.github.com/texhex/3954113

There are good articles out on the Net about "Arduino Data Types", just Google.

Ray

Ahh that is perfect!

As soon as you pass the variable to an int I can interact with it. I'll jump on to that link you included and work out why.

Thanks for the help!

Adam

Hiya, am also having a blast - n00bie with HTML "programming" experience. Was wondering how this part actually works;

TCCR1A = 0X00;
TCCR1B = 0X05;//set timer clock source
TCCR1C = 0X00;
TCNT1 = 0X00;
TIMSK1 = 0X00; // Ban timer interrupt overflow

the only variable actually used in the sketch is TCNT1 where are the others being used ?

Thanks, and hoping to be quite active here. :)

They're internal registers in the micro controller. Have a look at the data sheet for exact details.

They’re used as timers further down. I’m not certain but I think they are used to create a timer difference in the info sent.

I’ve included their pdf here. Hope you enjoy, they offer a fantastic package for its price.

UNO R3 Starter Kit Tutoral.pdf (2.44 MB)

AWOL: They're internal registers in the micro controller.

oh yeah, duhh.... they can't be variables because they weren't declared in the sketch ! so they are actually like 'keywords' then ?

AWOL: Have a look at the data sheet for exact details.

and this would be the datasheet for the (eg.) Arduino Uno itself, right ? probably a bit beyond my understanding but will have to start understanding what sorts of things goes on between the Arduino IDE and the actual chip.

Thanks.

so they are actually like 'keywords' then ?

No, they're defined in header files automatically included by the build process.

and this would be the datasheet for the (eg.) Arduino Uno itself, right

Wrong, it would be the datasheet for the Atmel AVR 328 processor

naescent: I've included their pdf here. Hope you enjoy, they offer a fantastic package for its price.

wow, thanks !! i'm working off the Earthshine Starter Kit Manual. and your PDF has a few extra different stuff to try. Cheers!

AWOL:

so they are actually like 'keywords' then ?

No, they're defined in header files automatically included by the build process.

and this would be the datasheet for the (eg.) Arduino Uno itself, right

Wrong, it would be the datasheet for the Atmel AVR 328 processor

ahh, further down the rabbit-hole then. okay - thanks for painting the correct picture.

As per an earlier post....use the IRremote library to start with = much easier

retronet_RIMBA1ZO: wow, thanks !! i'm working off the Earthshine Starter Kit Manual. and your PDF has a few extra different stuff to try. Cheers!

Ahh I might give that a go myself. Thanks

Is the IR Library simple enough to implement?

Adam

the IRremote (or IRlib) libraries are by far the easiest way to use IR remotes with Arduino.

All you need is an IR receiver to receive IR signals and an IR LED to send IR signals (plus an Arduino etc)

see http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html the latest library is on github.

Start off using the examples included with the library.

There are many posts on this forum for reference also.