Pushbutton and Toggle Switch Relay Control Issue

Hello everybody,
I am trying to control a relay using an On-Off toggle switch and a momentary pushbutton. My program does what I want essentially, but it does not work as it should. Basically, I want both the toggle switch and the button to control the state of the relay. The basic operation would be turning the toggle switch on turns the relay on, and in a remote location, press the button to turn the relay off and press the button again to turn the relay back on. No matter the state of the switch, the button should be able to toggle the relay. Ultimately, if the switch is in the on position, and I press the button to toggle the relay off, when I go to return the switch to the off position, the relay should not toggle back on and vice versa. If I toggled the relay on with the button and the switch in the off position, when I go to turn the switch on, the relay should not toggle off.

My program accomplishes this only partially. The switch toggles the relay flawlessly. When the switch is in the off position, the pushbutton also toggles the relay flawlessly, as the arduino recognizes every actuation of the button immediately and responds appropriately. However, when the switch is in the on position, the pushbutton has trouble toggling the relay. I have been chasing down this issue for hours and cannot find a solution. The arduino will not respond to every actuation of the button when the switch is on. I sometimes have to push the button 15 times to get it to toggle the relay. Good news is that the button does toggle the relay on and off, but it is very important that when the switch is on, the pushbutton also works on the first push every time.

There is no physical pullup resistor connected to the switch, but I am using a physical 1k ohm pullup resistor connected to the button as any other arrangement did not work for me.

I am using the ezButton library as it seemed easier to create a pushbutton toggle in this use case. However, if there is another way that is better, I am open to it.

I also have not done a big arduino project in a while, so I am sorry for my programming if it is hard to follow. I also am not the most experienced with Eagle, so I am also sorry for my schematic if it is hard to follow.

Any help is greatly appreciated!

#include <ezButton.h>

int buttonPin = 7;  //Momentary pushbutton
int switchPin = 8;  //SPST On-Off switch
int relayPin = 12;  //Pin to enable 3V relay
int i = 0;  //Loop control variable
int relayState = false;  //Variable to turn relay On and Off

ezButton button(buttonPin);

void setup() 
{
  pinMode(buttonPin, INPUT);  //I did not use INPUT_PULLUP as I am using a pullup resistor
  pinMode(switchPin, INPUT_PULLUP);  //No pullup resistor wired in with the switch
  pinMode(relayPin, OUTPUT);

  button.setDebounceTime(50);
}

void loop() 
{
  button.loop();

  if(button.isPressed())  //Momentary pushbutton toggle when the switch is in the off position. 
                          //With switch off, the button toggle works flawlessly, and fast, with every push. It recognizes every actuation
  {
    relayState = !relayState;
    digitalWrite(relayPin, relayState);
  }
  
  if(digitalRead(switchPin) == LOW)  //ON
  {
    relayState = !relayState;
    if(button.isPressed())  //Same pushbutton toggle code as above, but with the switch on. When the switch is on, the pushbutton toggles the state of the relay but with issues.
                            //This must be where my problem is. When using the button to toggle the relay, it randomly recognizes the button being pushed. I would like it to
                            //toggle with every push.
    {
      relayState = !relayState;
      digitalWrite(relayPin, relayState);
    }
    while(i == 0)  //While statement to set relay on one time. This is so the program does not stop once the relay is turned on
    {
      digitalWrite(relayPin, HIGH);
      i = 1;
    }
  }
  else  //OFF
  {
    while(i == 1)  //while statement to turn relay off one time. This is so the program does not stop once the relay is turned off
    {
      digitalWrite(relayPin, LOW);
      i = 0;
    }
  }
    
}

You want to detect when your toggle switch changes state, not detect what state is currently is in. Look at the StateChangeDetection example in the IDE (File->examples->02.Digital->StateChangeDetection)

Hopefully, you schematic is not correct. Pin 7 is not equal to D7 within the IDE. Pin 7 of an '328 is analog 0

ricmal:
There is no physical pullup resistor connected to the switch, but I am using a physical 1k ohm pullup resistor connected to the button as any other arrangement did not work for me.

I am using the ezButton library as it seemed easier to create a pushbutton toggle in this use case. However, if there is another way that is better, I am open to it.

ezButton library has used the internal pull-up resistor. you do not need to use any external pull-up/pull down resistor

IoT_hobbyist is right, just use the internal pull up and be alright. Although if that "remote location" is >1m a lower value external pull up might be desired. Also, just connect both the switch and the button to GND.

Simplified program:

#include <ezButton.h>

const byte ButtonPin = 7;  //Momentary pushbutton
const byte SwitchPin = 8;  //SPST On-Off switch
const byte RelayPin = 12;  //Pin to enable 3V relay

ezButton button(ButtonPin);
ezButton theSwitch)SwitchPin

void setup()
{
  pinMode(ButtonPin, INPUT_PULLUP);
  pinMode(SwitchPin, INPUT_PULLUP);
  pinMode(RelayPin, OUTPUT);
}

void loop()
{
  button.loop();
  theSwitch.loop()
  
  if(button.isPressed()){
    digitalToggle(RelayPin);
  }
  
  if(theSwitch.isPressed()){
    digitalWrite(RelayPin, HIGH);
  }
  
  if(theSwitch.isReleased()){
    digitalWrite(RelayPin, LOW);
  }
}

bool digitalToggle(const byte Pin){
  const bool NewState = !digitalRead(Pin);
  digitalWrite(Pin, NewState);
  return NewState;
}

Although I have to say I totally hate the names of the functions isPressed() and isReleased() as it suggest a steady state instead of an event. becamePressed() and becameReleased() would have been way better names.

Thank you so much! My relay is toggling as intended now. I was starting to go crazy

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.