One button to on/off

I’m using a remote control to turn the light on, but my problem is that I have one button to turn on and another to turn down, I really want just one to do both but I don’t know how.
Like if I press and the light is off it would turn on and when press again the same button it would turn off, maybe is something really stupid but I’m new on arduino.
the code I’m using:

#include <IRremote.h>

#define on 0xFFA25D

#define off 0xFF629D


int RECV_PIN = 12;
int rl = 7;

IRrecv irrecv(RECV_PIN);

decode_results results;


void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
   pinMode(rl, OUTPUT); 
   digitalWrite(rl, LOW);
 }

void loop() {
   
   if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
    
     if(results.value ==off){
       digitalWrite(rl, LOW); //turn off
       
    }
     if(results.value ==on){
    digitalWrite(rl, HIGH); //turn on
   
}
}
}

Do you know if the light is on or off?

When you turn it on set a boolean variable to true.
when the 'on' button is pressed AND the boolean is true, turn the light off and set the boolean to false.

Basically you need to track the current status (on/off) of the light and modify your action accordingly.

Even better if you have a direct feedback of whether the light is on or off. Then you just use the feedback from the digital on/off indicator without needing to track anything.

You can actually read back the pin status. The below will toggle an output pin with an interval of 500ms

void loop()
{
  digitalWrite(yourPin, !digitalRead(yourPin));
  delay(500);
}

You can actually read back the pin status

Yep, forgot about that one!

marco_c:
Do you know if the light is on or off?

When you turn it on set a boolean variable to true.
when the 'on' button is pressed AND the boolean is true, turn the light off and set the boolean to false.

Basically you need to track the current status (on/off) of the light and modify your action accordingly.

Even better if you have a direct feedback of whether the light is on or off. Then you just use the feedback from the digital on/off indicator without needing to track anything.

I can track the status of the relay and I have tried to do something like this but it failed because i'm using a remote control, I'm not sure how to explain why it didn't work

In what I understand would be like, if I press the button and lights is off light will turn on, if the light is on will turn off. But when I click the button it sends a IR signal and the light turn on, however the signal ''still in the arduino'' until another signal is send so it's like i'm still pressing the button and when delay is over the light will turn off. (not sure if I really understand, begginer here c:)

sterretje:
You can actually read back the pin status. The below will toggle an output pin with an interval of 500ms

void loop()

{
  digitalWrite(yourPin, !digitalRead(yourPin));
  delay(500);
}

sorry didn't really understand this :(, I never used digitalRead and the "!", but thanks!

Than look it up...

digitalRead() is just kind of the opposite of digitalWrite()...

Second is a bit more tricky but it's the not operator. Still easy to find in the Arduino reference.

septillion:
Than look it up…

digitalRead() is just kind of the opposite of digitalWrite()…

Second is a bit more tricky but it’s the not operator. Still easy to find in the Arduino reference.

Hey thanks a lot! It did really work :smiley:

#include <IRremote.h>
#define on 0xFFA25D
#define off 0xFF629D

int RECV_PIN = 12;
int rl = 7;

IRrecv irrecv(RECV_PIN);
decode_results results;


void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
   pinMode(rl, OUTPUT); 
   digitalWrite(rl, LOW);
 }

void loop() {
  
   if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
    
     if(results.value ==on){
   digitalWrite(rl, !digitalRead(rl));
  delay(500);
   }
  }
}

Final suggestion(s), use proper variable names. I mean “rl” tells nothing.

Also, stick with the same naming scheme throughout.

And drop defines for stuff like this. Use a const. A const unsigned long int his case.

And watch you indentation, it’s all over. Press ctrl+T and let the Arduino IDE format it for you again.

It does not effect the outcome of the program but it makes it more readable and easier to remember. Which is very important if you start making bigger programs.

So after a little edit

#include <IRremote.h>

const byte IRPin = 12;
const byte OutputPin = 7;

const unsigned long TriggerValue = 0xFFA25D;
//const unsigned long OffValue = 0xFF629D; //don't use it anymore

IRrecv irReceiver(IRpin);

void setup(){
  Serial.begin(9600);
  irReceiver.enableIRIn(); // Start the receiver
  pinMode(OutputPin, OUTPUT);
  //digitalWrite(OutputPin, LOW); //no need for this
 }

void loop() {
  decode_results results;
  
  if (irReceiver.decode(&results)) {
    Serial.println(results.value, HEX);
    irReceiver.resume(); // Receive the next value
    
    if(results.value == TriggerValue){
      digitalToggle(OutputPin);
      delay(500);
    }
  }
}

//Function I like to add to make it easier to reuse :)
inline void digitalToggle(byte pin){
  digitalWrite(pin, !digitalRead(pin));
}

Although the delay() does work, it makes expanding the code a bit hard.

septillion:
Final suggestion(s), use proper variable names. I mean “rl” tells nothing.

Also, stick with the same naming scheme throughout.

And drop defines for stuff like this. Use a const. A const unsigned long int his case.

And watch you indentation, it’s all over. Press ctrl+T and let the Arduino IDE format it for you again.

It does not effect the outcome of the program but it makes it more readable and easier to remember. Which is very important if you start making bigger programs.

So after a little edit

#include <IRremote.h>

const byte IRPin = 12;
const byte OutputPin = 7;

const unsigned long TriggerValue = 0xFFA25D;
//const unsigned long OffValue = 0xFF629D; //don’t use it anymore

IRrecv irReceiver(IRpin);

void setup(){
  Serial.begin(9600);
  irReceiver.enableIRIn(); // Start the receiver
  pinMode(OutputPin, OUTPUT);
  //digitalWrite(OutputPin, LOW); //no need for this
}

void loop() {
  decode_results results;
 
  if (irReceiver.decode(&results)) {
    Serial.println(results.value, HEX);
    irReceiver.resume(); // Receive the next value
   
    if(results.value == TriggerValue){
      digitalToggle(OutputPin);
      delay(500);
    }
  }
}

//Function I like to add to make it easier to reuse :slight_smile:
inline void digitalToggle(byte pin){
  digitalWrite(pin, !digitalRead(pin));
}




Although the delay() does work, it makes expanding the code a bit hard.

Alright!, thanks for the suggestions, it really helped! The code was kinda hard to understand for a begginer like me, I didn’t know all the expressions you used (specially the ''unsigned long" and “inline void”) but with some search I think I got it. Thank you again, really appreciate c:.

My pleasure :slight_smile:

Next up, use the reply button instead of the quote :wink:

Aauehaue, sure, newbie here... :smiley: