Turning led on and off remotelly

I downloaded the ir library and i’m having problems with controlling pin13 led by long holding certain button. I know how to make led to turn on by pressing one button, and to turn off by pressing another button, but I don’t know how to program arduino to hold the led turned on while i’m holding down a button, and to turn it off when i move my finger off that button.

When a button is pressed shortly, serial monitor displays some code. When i hold button down, serial monitor prints FFFFFFFF repeatedly.

This is the example program i wan’t to modify. So, i wan’t to make led on pin13 on when i’m holding down a button on my remote, and to turn it off when i’m not. Thanks for assistance, i’m beginner in programming.

#include <IRremote.h>

int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
  }
}

You can try something like this :

#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(13,OUTPUT); //pin for driving the led
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);

    if(results.value == value_for_the_key_you_want) //test what key is pressed
        digitalWrite(13,HIGH);  //turn on led if the key is pressed
    else digitalWrite(13,LOW); //turn off led if the key is not pressed

    irrecv.resume(); // Receive the next value
  }
}

i just went through the same thing and am looking for the same answer. dont forget to replace the HEX with 0xXX. as in.....

if(results.value == 0xA90     or    0xF in your case....) 
        digitalWrite(13,HIGH);  //turn on led if the key is pressed
    else digitalWrite(13,LOW); //turn off led if the key is not pressed

good luck!

Have a look at this thread http://arduino.cc/forum/index.php/topic,123009.msg931823.html#msg931823 where someone else was asking the same sort of question about repeating remote code (0xFFFFFFFF)

bricofoy:
You can try something like this :

#include <IRremote.h>

int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
 Serial.begin(9600);
 irrecv.enableIRIn(); // Start the receiver
 pinMode(13,OUTPUT); //pin for driving the led
}

void loop() {
 if (irrecv.decode(&results)) {
   Serial.println(results.value, HEX);

if(results.value == value_for_the_key_you_want) //test what key is pressed
       digitalWrite(13,HIGH);  //turn on led if the key is pressed
   else digitalWrite(13,LOW); //turn off led if the key is not pressed

irrecv.resume(); // Receive the next value
 }
}

Thanks but that is not what i want. You wrote a code that will turn the led on when i press button, not while i’m holding the button down. The code for short press and for holding down button are not the same, and the codes for holding down any button are the same (FFFFFFFFF), just first code differents. Let’s say if i press power button, monitor prints 123456 (this code is just example) in hex, but when I hold that button for a bit longer time, monitor prints 123456 and than FFFFFFFF one bellow another. When i press another button, it displays it’s code (example 123321), but when i hold that button down, it prints FFFFFFFF again. Each button has it’s own code, but when the button is held down, remote sends button unique code once and FFFFFFFF as long as i’m holding the button.

Is that "F"code HEX? Does arduino recognize it when called on?

if(results.value == 0xF) { // or FFFFF...ect 

      digitalWrite(ledpin,HIGH);
      delay(1000);
      digitalWrite(ledpin,LOW); 
    }

as long as "F" is received that will keep the light on but with a blink between. increase delay to decrease blink.

itsthedanyole:
Is that "F"code HEX?
Does arduino recognize it when called on?

if(results.value == 0xF) { // or FFFFF...ect 

digitalWrite(ledpin,HIGH);
     delay(1000);
     digitalWrite(ledpin,LOW);
   }





as long as "F" is received that will keep the light on but with a blink between.
increase delay to decrease blink.

results.value returns an unsigned long so the 0xF should be 0xFFFFFFFF

archangel:
Thanks but that is not what i want. You wrote a code that will turn the led on when i press button, not while i’m holding the button down. The code for short press and for holding down button are not the same, and the codes for holding down any button are the same (FFFFFFFFF), just first code differents. Let’s say if i press power button, monitor prints 123456 (this code is just example) in hex, but when I hold that button for a bit longer time, monitor prints 123456 and than FFFFFFFF one bellow another. When i press another button, it displays it’s code (example 123321), but when i hold that button down, it prints FFFFFFFF again. Each button has it’s own code, but when the button is held down, remote sends button unique code once and FFFFFFFF as long as i’m holding the button.

Ok I missed a part of your needs

try this :

#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

unsigned long value1;
unsigned long value2;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(13,OUTPUT); //pin for driving the led
}

void loop() {
  if (irrecv.decode(&results)) {
      value1=results.value;
      irrecv.resume(); // Receive the next value
      value2=results.value;
      irrecv.resume(); // Receive the next value
      Serial.println(value1, HEX);
      Serial.println(value2, HEX);
   }

   if(value1 == value_for_the_key_you_want) //test what key is pressed
        if(value2 == 0xFFFFFFFF)
           digitalWrite(13,HIGH);  //turn on led if the key is pressed for a long time
        else digitalWrite(13,LOW); //turn off led if the key is released


   }
}

@bricofoy:

The new code is not working, the led neither turns on or off. But the monitor prints commands arduino is receiving.

Here is the article that explains NEC type protocol.

http://wiki.altium.com/display/ADOH/NEC+Infrared+Transmission+Protocol

can you paste here what you got in the serial monitor ?

Here's what i get when long pressed button:

8B7926D 8B7926D FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

then long press another button: 8B710EF 8B710EF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

and another:

8B7D02F 8B7D02F FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

You need to remember the last value received, when the value is not FFFFFFFF. Then, when you receive FFFFFFFF, do whatever the last non-FFFFFFFF said to do.

Since you may not notice exactly when the repeat value stops appearing, there may be a lag between when it stops and when you do something about it not appearing anymore.

here is something that should do the trick. Maybe some corrections to do in conditions, but you have the idea to make a “memory” of the key.

#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

unsigned long value;


void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(13,OUTPUT); //pin for driving the led
}

void loop() {
  static boolean key_pressed;

  if (irrecv.decode(&results)) {
      value=results.value;
      irrecv.resume(); // Receive the next value

      if (value == the_key_you_want)
          key_pressed = true;
      else if ((value != the_key_you_want)&&(value != 0xFFFFFFFF))
          key_pressed = false;

      if (value == 0xFFFFFFFF)&&key_pressed)
          digitalWrite(13,HIGH);
      else digitalWrite(13,LOW);
      Serial.println(value, HEX);
   }
}

@bricofoy: not working…i think that problem might be in speed…processor is driving program very fast, faster than remote sends commands. So, in the gap of two 0xF commands, arduino will pass through loop many times, resulting in led13 shutdown. There should be some kind of delay i think, maybe…

@paulS

Good idea, i’ll try that.

Edit: whatever i try to do except turn on by one button, and turn off by another, is not working. I really don’t understand this, programming is my weak point :frowning:

not a problem of speed, I think, because as I understand it, it's the role of the first if to filter the moments when there is no answer from the IR system.

you may add some serial.print all over my code to see where is something wrong. As I said, I wrote it quickly and with no possibilities to test it. But I'm convinced the overall idea is good, just need some tune to get it working.

paulS spoke of "memory of the last key before FFFFFFF, this is somewhat what my code should do. More exactly, the memory does not store the last key code, but the fact the last key code was the good one.

May be you could make it simpler with storing really the last key code.

This is best I can make. The led turns on and off in intervals, only the on interval is much longer then off. I’m quite sure that the problem is speed, because state in between two consecutive 0xF is the same as the state when button is released. I think it could be solved with some timers included and to tell the arduino that it should turn led off only if it has passed enough time from last command, and to reset that timer when program receives 0xF again. But i don’t know how to include timers in whole story.

Here is the program i’ve build so far using all your recommendations. Thanks for solutions so far :grin:

#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

unsigned long value;


void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(13,OUTPUT); //pin for driving the led
}

void loop() {
  static boolean key_pressed;
  int k;
  results.value = 0;
  if (irrecv.decode(&results)) {
     Serial.println(results.value, HEX);
   
     if (results.value == 0x8B712ED) {
        key_pressed = true; 
     }
     if ((results.value == 0xFFFFFFFF) && key_pressed) {
      digitalWrite (13, HIGH);
     delay(400); 
      k = 1;
    }
    if (results.value != 0x8B712ED && results.value != 0xFFFFFFFF) {
     key_pressed = false; 
    }
   irrecv.resume();  
   }
   if (k == 1 && results.value == 0) {
   digitalWrite (13, LOW);
   k = 0;
   }
   }

static boolean key_pressed;

This is a local variable. Unless you provide an initial value, the value is whatever garbage happened to be in the memory location that was assigned to that variable. How is that garbage remotely useful to you?

Local variables MUST be initialized.

archangel -> I think your "k" variable should be declared as "static", otherway it will be reset each time you enter in the loop fonction.

Static allow the variable to be conserved between several function calls.

PaulS -> what is the behaviour when you declare something like static int k = 0; ? k is initialised to 0 only on the first function call ? Or each time you call the function ? (so "static" will be quite useless...) In the arduino reference manual, in the exemple use for "static" variable is not initialized.

what is the behaviour when you declare something like static int k = 0; ? k is initialised to 0 only on the first function call ?

The variable is declared and given an initial value ONCE. After that, it keeps whatever value it is given between function calls.

In the arduino reference manual, in the exemple use for "static" variable is not initialized.

That doesn't make it right.

Good to know. Thank you very much. I think this must be added to the static reference documentation page.