1

I'm new to arduinos and have not been able to find/create a working bit of code for my project. I'd like to control several different relays (standard 5v optical relays) with push buttons. I want one pushbutton1 to turn on/off relay1, pushbutton2 to turn on/off relay 2, etc.

I ran into troubles using delay statements as debouncers because I guess it locked out the remainder of the code while it ran? I then tried to use a flagging approach covered here:

https://github.com/VRomanov89/EEEnthusiast/blob/master/03.%20Arduino%20Tutorials/01.%20Advanced%20Button%20Control/ButtonSketch/ButtonSketch.ino

const int numOfInputs = 2;
const int inputPins[numOfInputs] = {2,3};
const int outputPin = 10;

int LEDState = 0;
int inputState[numOfInputs];
int lastInputState[numOfInputs] = {LOW,LOW};
bool inputFlags[numOfInputs] = {LOW,LOW};
int inputCounters[numOfInputs];

long lastDebounceTime[numOfInputs] = {0,0};
long debounceDelay = 50;

void setup() {
  for(int i = 0; i < numOfInputs; i++) {
    pinMode(inputPins[i], INPUT);
    digitalWrite(inputPins[i], HIGH); // pull-up 20k
  }
  Serial.begin(9600);
  pinMode(outputPin, OUTPUT);
}

void loop() {
  setInputFlags();
  resolveInputFlags();
  resolveOutputs();
}

void setInputFlags() {
  for(int i = 0; i < numOfInputs; i++) {
    int reading = digitalRead(inputPins[i]);
    if (reading != lastInputState[i]) {
      lastDebounceTime[i] = millis();
    }
    if ((millis() - lastDebounceTime[i]) > debounceDelay) {
      if (reading != inputState[i]) {
        inputState[i] = reading;
        if (inputState[i] == HIGH) {
          inputFlags[i] = HIGH;
        }
      }
    }
    lastInputState[i] = reading;
  }
}

void resolveInputFlags() {
  for(int i = 0; i < numOfInputs; i++) {
    if(inputFlags[i] == HIGH) {
      // Input Toggle Logic
      inputCounters[i]++;
      updateLEDState(i); 
      printString(i);
      inputFlags[i] = LOW;
    }
  }
}

void printString(int output) {
      Serial.print("Input ");
      Serial.print(output);
      Serial.print(" was pressed ");
      Serial.print(inputCounters[output]);
      Serial.println(" times.");
}

void updateLEDState(int input) {
  // input 0 = State 0 and 1
  if(input == 0) {
    if(LEDState == 0) {
      LEDState = 1;
    }else{
      LEDState = 0;
    }
  // input 1 = State 2 to 6
  }else if(input == 1) { // 2,3,4,5,6,2,3,4,5,6,2,
    if(LEDState == 0 || LEDState == 1 || LEDState > 5) {
      LEDState = 2;
    }else{
      LEDState++;
    }
  }
}

void resolveOutputs() {
  switch (LEDState) {
    case 0:
      digitalWrite(outputPin, LOW);
      break;
    case 1:
      digitalWrite(outputPin, HIGH);
      break;
    case 2:
      analogWrite(outputPin, 30);
      break;
    case 3:
      analogWrite(outputPin, 70);
      break;
    case 4:
      analogWrite(outputPin, 100);
      break;
    case 5:
      analogWrite(outputPin, 155);
      break;
    case 6:
      analogWrite(outputPin, 255);
      break;
    default: 
    break;
  }
}

But was unable to alter the code to get it to work... could someone help me write a bit of code which will allow me to do what I want it to do? I'd rather not buy a matrix-style shield to accomplish this, but I will if I have to.

What I want to do:

  • Turn on relay1 by pressing momentary pushbutton1
  • Turn off relay1 by pressing momentary pushbutton1
  • Turn on relay2 by pressing momentary pushbutton2
  • Turn off relay2 by pressing momentary pushbutton2
  • etc.
  • etc.

Thank you in advance!

3 Answers 3

0

To use this sketch, you will need the Bounce2 Library, and two N.O. switches connected between GND and the Arduino Digital Pins specified. I'm not sure if there is a limit to the number of Bounce2 objects you can create. Have a look at the Bounce2.h and Bounce2.cpp files.

#include <Bounce2.h>
byte buttonOneState = 0;
byte buttonTwoState = 0;
const byte buttonPin1 = 4;
const byte buttonPin2 = 5;
const byte debouncerInterval = 50;

// Instantiate ONE OR MORE Bounce2 object(s).
Bounce debouncer = Bounce();
Bounce debouncer2 = Bounce();

void setup(){
  Serial.begin(9600);
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  debouncer.attach(buttonPin1);
  debouncer.interval(debouncerInterval);
  debouncer2.attach(buttonPin2);
  debouncer2.interval(debouncerInterval);
}

void loop(){

  // Button 1
  if(debouncer.update()){
    if(debouncer.read() == 0){
      if(buttonOneState == 0){
        Serial.println("Turn Relay 1 ON");
        buttonOneState = 1;
      }
      else{
        Serial.println("Turn Relay 1 OFF");
        buttonOneState = 0;
      }
    }
  }

  // Button 2
  if(debouncer2.update()){
    if(debouncer2.read() == 0){
      if(buttonTwoState == 0){
        Serial.println("Turn Relay 2 ON");
        buttonTwoState = 1;
      }
      else{
        Serial.println("Turn Relay 2 OFF");
        buttonTwoState = 0;
      }
    }
  }

}
3
  • Forgive my ignorance: which line does it specify the output pin for me to connect to the relay? Thank you so much for your help - this is much more concise than my attempts!
    – Asher
    Aug 23, 2018 at 23:50
  • The sketch doesn't specify the relay pin numbers. I left that up to you to decide which ones to use. You can control the ON/OFF commands for the relays where the "Serial.println..." statements are located in the sketch. Keep in mind that some optical relay modules require a LOW signal to turn them ON, and a HIGH signal to turn them OFF. It's important to ensure you are getting the desired output first, and the print statements are an easy way to do this.
    – VE7JRO
    Aug 24, 2018 at 0:10
  • Okay beautiful, thank you very much! Good point on the relays; I'll have to check the datasheets. I'll post what I have once I have it working.
    – Asher
    Aug 24, 2018 at 0:19
0

You can use this Button library from JChristensen (in GitHub)

You only need to read the brieve (altough usefull) documentation and you can control, no only the state of many buttons, you also can read the time that the buttons are pressed.

Hope you can solve your little problem :D

TIP: Try with 50ms of delay when you instantiate the button object

0

Here is the final solution I've implemented:

/*  Thanks to VE7JRO for giving me this solution to my problem. 
 *  Thread found at https://arduino.stackexchange.com/questions/55540/push- button-control-of-multiple-relays 
 */

#include <Bounce2.h>
byte buttonOneState = 0;
byte buttonTwoState = 0;
byte buttonThreeState = 0;
byte buttonFourState = 0;
const byte buttonPin1 = 2;
const byte buttonPin2 = 3;
const byte buttonPin3 = 4;
const byte buttonPin4 = 5;
const byte relayPin1 = 9; //Relay pin 1
const byte relayPin2 = 10; //Relay pin 2
const byte relayPin3 = 11; //Relay pin 3
const byte relayPin4 = 12; //Relay pin 4
const byte debouncerInterval = 50;

// Instantiate ONE OR MORE Bounce2 object(s).
Bounce debouncer = Bounce();
Bounce debouncer2 = Bounce();
Bounce debouncer3 = Bounce();
Bounce debouncer4 = Bounce();

void setup(){
  Serial.begin(9600);
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(buttonPin4, INPUT_PULLUP);
  debouncer.attach(buttonPin1);
  debouncer.interval(debouncerInterval);
  debouncer2.attach(buttonPin2);
  debouncer2.interval(debouncerInterval);
  debouncer3.attach(buttonPin3);
  debouncer3.interval(debouncerInterval);
  debouncer4.attach(buttonPin4);
  debouncer4.interval(debouncerInterval);
  pinMode(relayPin1, OUTPUT); //Define pin as output
  pinMode(relayPin2, OUTPUT); //Define pin as output
  pinMode(relayPin3, OUTPUT); //Define pin as output
  pinMode(relayPin4, OUTPUT); //Define pin as output
}

void loop(){

  // Button 1
  if(debouncer.update()){
    if(debouncer.read() == 0){
      if(buttonOneState == 0){
        Serial.println("Turn Relay 1 ON");
        digitalWrite(relayPin1, HIGH);
        buttonOneState = 1;
      }
      else{
        Serial.println("Turn Relay 1 OFF");
        digitalWrite(relayPin1, LOW);
        buttonOneState = 0;
      }
    }
  }

  // Button 2
  if(debouncer2.update()){
    if(debouncer2.read() == 0){
      if(buttonTwoState == 0){
        Serial.println("Turn Relay 2 ON");
        digitalWrite(relayPin2, HIGH);
        buttonTwoState = 1;
      }
      else{
        Serial.println("Turn Relay 2 OFF");
        digitalWrite(relayPin2, LOW);
        buttonTwoState = 0;
      }
    }
  }

  // Button 3
  if(debouncer3.update()){
    if(debouncer3.read() == 0){
      if(buttonThreeState == 0){
        Serial.println("Turn Relay 3 ON");
        digitalWrite(relayPin3, HIGH);
        buttonThreeState = 1;
      }
      else{
        Serial.println("Turn Relay 3 OFF");
        digitalWrite(relayPin3, LOW);
        buttonThreeState = 0;
      }
    }
  }
  // Button 4
  if(debouncer4.update()){
    if(debouncer4.read() == 0){
      if(buttonFourState == 0){
        Serial.println("Turn Relay 4 ON");
        digitalWrite(relayPin4, HIGH);
        buttonFourState = 1;
      }
      else{
        Serial.println("Turn Relay 4 OFF");
        digitalWrite(relayPin4, LOW);
        buttonFourState = 0;
      }
    }
  }

}

Your Answer

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

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