Relay control with a push-button

Hi I try to set up relay to be switch on and off, with push-button and it don't work as it should. Sometime it's works ok and other time it don't turn on when is button pushed other time don't switch off.
Please help me with a code

#define BUTON_PIN1 0
#define BUTON_PIN2 2
#define BUTON_PIN3 15
#define RELAY_PIN1 32
#define RELAY_PIN2 33
#define RELAY_PIN3 25

boolean oldState = HIGH;
int     mode     = 0;    

void setup(){
  pinMode(RELAY_PIN1, OUTPUT); 
  pinMode(RELAY_PIN2,OUTPUT); 
  pinMode(RELAY_PIN3,OUTPUT); 
 
  pinMode(BUTON_PIN1 ,INPUT_PULLUP); 
  pinMode(BUTON_PIN2 , INPUT_PULLUP); 
  pinMode(BUTON_PIN3 , INPUT_PULLUP); 
 
  digitalWrite(RELAY_PIN1 , LOW); 
  digitalWrite(RELAY_PIN2 , LOW); 
  digitalWrite(RELAY_PIN3 , LOW); 
} 
void loop() {{{
 
  boolean newState = digitalRead(BUTON_PIN1);

  if((newState == LOW) && (oldState == HIGH)) {
   
    delay(0);
    
    newState = digitalRead(BUTON_PIN1);
    if(newState == LOW) {      
      if(++mode > 1) mode = 0; 
      switch(mode) {           
        case 0:
         digitalWrite(RELAY_PIN1, HIGH);    
          break;
        case 1:
         digitalWrite(RELAY_PIN1, LOW);
          break;
        case 2:
         digitalWrite( RELAY_PIN1, HIGH);
          break;
      }
    }
  }

  oldState = newState;
}

  
 boolean newState = digitalRead(BUTON_PIN2);

 
  if((newState == LOW) && (oldState == HIGH)) {
    
    delay(0);
    
    newState = digitalRead(BUTON_PIN2);
    if(newState == LOW) {      
      if(++mode > 1) mode = 0; 
      switch(mode) {           
        case 0:
          digitalWrite(RELAY_PIN2, LOW);
          break;
        case 1:
          digitalWrite(RELAY_PIN2, HIGH);
          break;
        case 2:
          digitalWrite(RELAY_PIN2, LOW);
          break;
      }
    }
  }

 
  oldState = newState;
}
   
  boolean newState = digitalRead(BUTON_PIN3);

 
  if((newState == LOW) && (oldState == HIGH)) {
    
    delay(0);
    
    newState = digitalRead(BUTON_PIN3);
    if(newState == LOW) {      
      if(++mode > 0) mode = 0; 
      switch(mode) {           
        case 0:
          digitalWrite(RELAY_PIN3, LOW);
          break;
        case 1:
          digitalWrite(RELAY_PIN3, HIGH);
          break;
        case 2:
          digitalWrite(RELAY_PIN3, LOW);
          break;
      }
    }
  }

  
  oldState = newState;
}

Seems like contact bounce in your buttons.

There's some problem with the amount of { and } in your code.

Are you using ESP32?

ESP32 has the BOOT button connected to GPIO 0 and it has a pull up resistor.

It:

 pinMode(BUTON_PIN1 ,INPUT_PULLUP);

Should be:

 pinMode(BUTON_PIN1 ,INPUT);

Hello greggr81

Consider

constexpr int ButtonPins[] {A0, A1, A2};
constexpr int RelayPins[] {9, 10, 11};
enum names {One, Two, Three};
#define usl unsigned long
struct RELAYCONTROL
{
  int buttonPin;
  int relayPin;
  int stateOld;
  usl interval;
  usl stamp;
} relayControls[]
{
  {ButtonPins[One], RelayPins[One], LOW, 20, 0},
  {ButtonPins[Two], RelayPins[Two], LOW, 20, 0},
  {ButtonPins[Three], RelayPins[Three], LOW, 20, 0},
};

void setup()
{
  for (auto &relayControl : relayControls)
  {
    pinMode (relayControl.buttonPin, INPUT_PULLUP);
    pinMode (relayControl.relayPin, OUTPUT);
    digitalWrite(relayControl.relayPin,HIGH);
    delay(1000);
    digitalWrite(relayControl.relayPin,LOW);
  }
};

void loop()
{
  usl currentMillis=millis();

 for (auto &relayControl : relayControls)
  {
   if (currentMillis-relayControl.stamp >= relayControl.interval) 
   {
    relayControl.stamp=currentMillis;
    int stateNew=digitalRead(relayControl.buttonPin)?LOW:HIGH;
    if (relayControl.stateOld!=stateNew)
    {
      relayControl.stateOld=stateNew;
      if (stateNew) digitalWrite (relayControl.relayPin,digitalRead(relayControl.relayPin)?LOW:HIGH);
    }
   }
  }
}

Have a nice day and enjoy coding in C++.

1 Like

thanks it works now

Another way:

#include <Bounce2.h>

#define NUM_RELAYS 3
#define INITIAL_STATE LOW  // Initial state = HIGH to active LOW relay model.

struct INFOS
{
  const byte relayPin;
  bool relayState;
  const byte buttonPin;
};

INFOS info[NUM_RELAYS] =
{
  {2, INITIAL_STATE, 18}, // Relay 0 pin, relay 0 state, button 0 pin
  {4, INITIAL_STATE, 19},
  {5, INITIAL_STATE, 21}
};

Bounce2::Button button[NUM_RELAYS] = {Bounce2::Button()};

void printDebug(byte i)
{
  Serial.print("Button ");
  Serial.print(i);
  Serial.print(" pressed, relayState ");
  Serial.print(i);
  Serial.print(": ");
  Serial.println(info[i].relayState);
}

void setup()
{
  Serial.begin(9600);

  for (byte i = 0; i < NUM_RELAYS; i++)
  {
    button[i].attach(info[i].buttonPin, INPUT_PULLUP);
    button[i].setPressedState(LOW);
    button[i].interval(5);

    pinMode(info[i].relayPin, OUTPUT);
    digitalWrite(info[i].relayPin, info[i].relayState);
  }
}

void loop()
{
  for (byte i = 0; i < NUM_RELAYS; i++)
  {
    button[i].update();

    if (button[i].pressed())
    {
      info[i].relayState = !info[i].relayState;
      digitalWrite(info[i].relayPin, info[i].relayState);
      printDebug(i);
      break;
    }
  }
}

That might have been part of the problem.

Each pushbutton needs its own oldState

a7

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