4

What I have:

  • 1 x 8 channel relay
  • 1 x IR receiver
  • 1x Arduino Uno
  • 1x momentary switch
  • 1x breadboard
  • 1x 10K resister

I think the wiring is all ok as for the most part things are working as they should..ish.

Just a few bugs I need to fix.

The goal was to toggle just 2 relays (at the moment) on/off with the hardwired switch and individually toggle the a relay using an IR remote control.

Like I said this sort of works....

If I press the momentary button it does indeed toggle both relays...yeah! then as long as the 2 relays are toggled to the on position by the momentary switch I can toggle each relay using buttons on a remote.

However if I turn the relays off with the momentary button I can't turn them on with the remote. Also if I turn off one of the relays with the remote and then press momentary switch it alternates the toggle between the 2 relays rather than just turning the other one off.

I have been using various example sketches to achieve all this and just trying to stitch them together as best I can but something is telling me that the approach is all wrong and that I should maybe be looking into Boolean's perhaps?

Hope you can shed some light on this for me.

#include <IRremote.h>
#define irPin 8
IRrecv irrecv(irPin);
decode_results results;
const int buttonPin = 2;
const int relay1 = 13;
const int relay2 = 12;
int relay1State;
int relay2State;
int buttonState;
int lastButtonState;
long lastDebounceTime = 0;
long debounceDelay = 50;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
  pinMode(buttonPin, INPUT);
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  digitalWrite(relay1, relay1State);
  digitalWrite(relay2, relay2State);
}

void loop() {
  if (irrecv.decode(&results)) {
    switch (results.value) {
      case 0xFF30CF:
        Serial.println("Button 1 Pressed");
        relay1State = ~relay1State;
        digitalWrite(relay1, relay1State);
        delay(250);
        break;
      case 0xFF18E7:
        Serial.println("button 2 pressed");
        relay2State = ~relay2State;
        digitalWrite(relay2, relay2State);
        delay(250);
        break;
    }
    irrecv.resume();
  }

  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {

    if (reading != buttonState) {
      buttonState = reading;

      if (buttonState == HIGH) {
        relay1State = !relay1State;
        relay2State = !relay2State;
      }
    }
  }

  digitalWrite(relay1, relay1State);
  digitalWrite(relay2, relay2State);
  lastButtonState = reading;
}
4
  • Welcome Michael. First, just a suggestion, in line 30 and 36 change the ~ to !. Now just clarify us one thing. Suppose you start arduino and press the the buttonPin once. You make both relays ON. Now with remote you make relay 1 OFF. So current state is relay1 OFF and relay2 ON. Now you press the buttonPin again. What do you want the new relay states to be? (not what is happening right now, what you intend to be)
    – brtiberio
    Commented Nov 22, 2015 at 22:34
  • 1
    Thank you! That changes has solved one issue of being able to turn on the relays from the remote while first being in the off state with the button. To answer your question: I was hoping to turn both relays off or on using the button (like an all on all off switch/override) which works when both are on or off but if one is on and the other is off they toggle opposite to each other, so I guess it is doing what the code is telling it to do, just not the way I want it. I want the one that is left on to turn off with the button then when i press the button again both will turn on. Thank you! Commented Nov 22, 2015 at 22:51
  • That's because you're telling it "relay1State = !relay1State;". IE invert the relays' state when you press the button. If you want them both to go off and on together, you need an extra variable, to store whether the next time you press the button, you want on or off. So have the button flip that variable, then whatever value that variable is, send that to the relays. Also at the top, "int relay1State;" should be "int relay1State=0;" because in your setup, you send that state to relay1 without defining it first. By luck, it works anyway.
    – Greenaum
    Commented Sep 19, 2019 at 5:30
  • Also I should add, having the button do on AND off is a bit confusing! If one is on, other is off, then which state do you want them both to go to when you press it? I suppose if you only have one button you're a bit constrained by that. A better design would involve buying another button! Then you'd have one ON and one OFF. And the user would know which one to expect, where if currently you have one relay in each state, should the button switch them on or off? Maybe an LED or something could inform the user of that, but an extra button would be better I think.
    – Greenaum
    Commented Sep 19, 2019 at 5:36

1 Answer 1

3

So according to your comments this should be the code if no mistake was made

#include <IRremote.h>
#define irPin 8
IRrecv irrecv(irPin);
decode_results results;
const int buttonPin = 2;
const int relay1 = 13;
const int relay2 = 12;
int relay1State = 0;
int relay2State = 0;
int masterState = 0;
int buttonState;
int lastButtonState;
long lastDebounceTime = 0;
long debounceDelay = 50;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
  pinMode(buttonPin, INPUT);
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  digitalWrite(relay1, relay1State);
  digitalWrite(relay2, relay2State);
}

void loop() {
  if (irrecv.decode(&results)) {
    switch (results.value) {
      case 0xFF30CF:
        Serial.println("Button 1 Pressed");
        relay1State = !relay1State;
        digitalWrite(relay1, relay1State);
        delay(250);
        break;
      case 0xFF18E7:
        Serial.println("button 2 pressed");
        relay2State = !relay2State;
        digitalWrite(relay2, relay2State);
        delay(250);
        break;
    }
    irrecv.resume();
  }

  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {

    if (reading != buttonState) {
      buttonState = reading;

      if (buttonState == HIGH) {
        masterState = !masterState;
        relay1State = masterState;
        relay2State = masterState;
      }
    }
  }

  digitalWrite(relay1, relay1State);
  digitalWrite(relay2, relay2State);
  lastButtonState = reading;
}

what I've done is create a masterState that only changes whenever you press the buttonPin and by pressing it will also change both relays to the value of new masterState independently of their actual state.

Another advice: is a bad practice to not initialize variables before use, because when you declare it is not granted that they are automatically equal to zero.

2
  • You sir are a big help! That's solved my problems! I'm not sure I totally understand how my program works just yet but it's slowly sinking in. But I can say I have learned much more and quicker by just getting stuck in and attempting small projects, rather than just reading book after book or watching tutorial after tutorial. Program to learn, not learn to program I think they say :) Thanks again for your help. That was a real head scratch-er for me! Think I might fire a photo-resister into the mix now..why not eh? This is fun! :D Commented Nov 22, 2015 at 23:38
  • Go on Michael. Keep testing things. To help you undertstand your original code, what you did was invert the current state of the relays when you pushed the buttonPin. The ! gives you the logical not of a variable. So if a var is 1, true, using ! will give the negation of that var. This is why you needed a master state to do what you wanted. Go on and keep practicing! Happy coding
    – brtiberio
    Commented Nov 23, 2015 at 16:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.