Turning led on and off remotelly

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.

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.

Insert Quote
Quote
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.

No, it is given the value zero (in this case, representing "false"), exactly the same as if you had declared it with global scope without an explicit initialiser.

ok so to be really clear, something like

static int abcd;

is ok ? no need to explicitly set abcd to 0 ?

and if we write

static int abcd=0;

will this work, or will abcd be reset to 0 on each function call ?

I really think the documentation need to be clearer on this point.

Explicitly setting the initial value is allowed, and highly recommended. It happens ONCE.

If you give it any value explicitly, it will be set to that value before "setup" is run (before "init" or "main" even).
If you don't give it a value, it will be given the value zero, more or less at the same time as if you had given it a value.
This is only done once per reset.

This is standard C/C++ behaviour.

ok, thanks to you two for the explanations :slight_smile: