Multiple pushbuttons as toggles

Hello, I am going to need 11 momentary pushbutton switches to act as a toggle or flip flop circuit. I have successfully written code to toggle 2 of the buttons, but it seems really complex just to flip flop a circuit. If anyone has an easier way or I am totally doing it wrong (or right) please let me know.

int LEDState1=0;
int LEDState2=0;
int aled1=13;
int aled2=12;
int dt1=100;
int button1=7;
int button2=8;
int buttonNew1;
int buttonOld1;
int buttonNew2;
int buttonOld2;


void setup() {
  // put your setup code here, to run once:
pinMode(aled1,OUTPUT);
pinMode(aled2,OUTPUT);
pinMode(button1,INPUT_PULLUP);
pinMode(button2,INPUT_PULLUP);
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
buttonNew1=digitalRead(button1);
if(buttonOld1==0 && buttonNew1==1){
  if (LEDState1==0){
  digitalWrite(aled1, HIGH);
  LEDState1=1;
}
else{
  digitalWrite(aled1, LOW);
  LEDState1=0;
}
}
buttonOld1=buttonNew1;
delay(dt1);

buttonNew2=digitalRead(button2);
if(buttonOld2==0 && buttonNew2==1){
  if (LEDState2==0){
  digitalWrite(aled2, HIGH);
  LEDState2=1;
}
else{
  digitalWrite(aled2, LOW);
  LEDState2=0;
}
}
buttonOld2=buttonNew2;
delay(dt1);

}

Learn how to use arrays and loops to make your life easier. Whenever you see variables names like z1, x2, x3, x4, x5, etc then an array would work better (x[0], x[1], x[2], etc). Variable arrays are a standard part of C++ (most programming languages, actually), so there will be lots of tutorials out there to get you going.

I'm on my RPi at the moment not my normal laptop where my Arduino code is, so can't provide the code immediately, but I have a "master" sketch that I use to do exactly what marco_c advocates. Will post it later if you still need it.

All you need to do is put the pin numbers in one array, and sit back.

I would be very surprised though if there's not a class to do this lurking somewhere.

See For beginners: The sim****ple way to program for multiple buttons

Thank you for the responses, I will look into arrays and play with the ezbuttons. I have done the Arduino tutorials, and now studying C++ trying to connect the dots, which is still blurry. Coming from a background of ladder logic this is definitely different. Hopefully I am not forcing my thinking of ladder logic into Arduino and messing things up.

leandra_reis:
I'm on my RPi at the moment not my normal laptop where my Arduino code is, so can't provide the code immediately, but I have a "master" sketch that I use to do exactly what marco_c advocates. Will post it later if you still need it.

All you need to do is put the pin numbers in one array, and sit back.

I would be very surprised though if there's not a class to do this lurking somewhere.

*Yes, I would appreciate if you could provide me the code, that would be a huge help. *

Hello

A toggleButton class is provided with this library

Your program could be:

#include "easyRun.h"

int aled1=13;
void aled1HIGH() {digitalWrite(aled1, HIGH);}
void aled1LOW()  {digitalWrite(aled1, LOW);}
toggleButton button1(7, aled1HIGH, aled1LOW);

int aled2=12;
void aled2HIGH() {digitalWrite(aled2, HIGH);}
void aled2LOW()  {digitalWrite(aled2, LOW);}
toggleButton button2(8, aled2HIGH, aled2LOW);

void setup() {
  // put your setup code here, to run once:
pinMode(aled1,OUTPUT);
pinMode(aled2,OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
easyRun();
}

An example for doing button state change detection and debounce on a bunch of pins:

const byte ButtonCount = 3;
const byte ButtonPins[ButtonCount] = {2, 3, 4};
const unsigned long DebounceTime = 30;


boolean ButtonWasPressed[ButtonCount];  // Defaults to 'false'
boolean ButtonChangedState[ButtonCount];  // Defaults to 'false'


unsigned long ButtonStateChangeTime = 0; // Debounce timer common to all buttons


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


  pinMode(LED_BUILTIN, OUTPUT);
  
  for (byte i = 0; i < ButtonCount; i++)
  {
    pinMode (ButtonPins[i], INPUT_PULLUP);  // Button between Pin and Ground
  }
}


void loop()
{
  checkButtons();
}


void checkButtons()
{
  unsigned long currentTime = millis();


  // Update the buttons
  for (byte i = 0; i < ButtonCount; i++)
  {
    boolean buttonIsPressed = digitalRead(ButtonPins[i]) == LOW;  // Active LOW
    ButtonChangedState[i] = false;


    // Check for button state change and do debounce
    if (buttonIsPressed != ButtonWasPressed[i] &&
        currentTime  -  ButtonStateChangeTime > DebounceTime)
    {
      // Button state has changed
      ButtonStateChangeTime = currentTime;
      ButtonChangedState[i] = true;
      ButtonWasPressed[i] = buttonIsPressed;
    }
  }


  // Act on the the buttons
  for (byte i = 0; i < ButtonCount; i++)
  {
    if (ButtonChangedState[i])
    {
      if (ButtonWasPressed[i])
      {
        // Button was just pressed
/////////// ADD CODE HERE TO TOGGLE THE OUTPUT PIN
/////////// Something like:  digitalWrite(LEDPin[i], digitalRead(LEDPin[i]) == LOW);
      }
      else
      {
        // Button was just released
      }
    }
  }
}

You can use arrays. For example,

int array[10] = {4, 6, 23, 5983, 12, 9, 87, 11, 909, 8227}

The 10 indicates that there are 10 values in the array.

theultimateandy:
Y*es, I would appreciate if you could provide me the code, that would be a huge help. *

johnwasser's code in #6 is basically the same as mine: in fact his does better debouncing, so stick to his.

As for this:

bricoleau:
Hello

A toggleButton class is provided with this library

Your program could be:

#include "easyRun.h"

int aled1=13;
void aled1HIGH() {digitalWrite(aled1, HIGH);}
void aled1LOW()  {digitalWrite(aled1, LOW);}
toggleButton button1(7, aled1HIGH, aled1LOW);

int aled2=12;
void aled2HIGH() {digitalWrite(aled2, HIGH);}
void aled2LOW()  {digitalWrite(aled2, LOW);}
toggleButton button2(8, aled2HIGH, aled2LOW);

.... very tedious to have to set that up for 11 buttons.

And...

pon00009:
You can use arrays.

Well yes: that's been the point of this thread since reply #1 :wink:

leandra_reis:
.... very tedious to have to set that up for 11 buttons.

Yes but easy to understand.

Otherwise the clean way is to create a dedicated class, derived from those in the library

include "easyRun.h"

class ledButton : public togglerGen, public clickButtonGen
{
  private :
    uint8_t _pinLed;
  public :
    ledButton(uint8_t pinLed, uint8_t pinButton) : clickButtonGen(pinButton), _pinLed(pinLed) {
      pinMode(_pinLed, OUTPUT);
      switchOff();
    }
    void runClick() {//This will be called on each button click
      toggle();      //This will call alternatively switchOn() and switchOff()
    }
    void switchOn() {
      digitalWrite(_pinLed, LOW);
    }
    void switchOff() {
      digitalWrite(_pinLed, HIGH);
    }
};

ledButton led1(13, 7);
ledButton led2(12, 8);

void setup() {
}

void loop() {
easyRun();
}

Thank you for all your input, I ended up using bricoleau code from the library. I tried to use johnwasser's code, its beyond my skill level at this point in time. I was able to get the circuit working good but I did have one question. My first toggle pushbutton is a main toggle that when LOW, deactivates all the other toggle buttons, regardless of the state. When the main is off, I press the sub level buttons. They don't turn on, but I do notice a slight flash when I push the button. Is there a way to add a delay into the circuit or another way to code the master to not have the flashing?

#include <easyRun.h>

int aled1=7;
void aledmHIGH() {digitalWrite(aled1, HIGH);} //button to activate/deactivate spare setter
void aledmLOW() {digitalWrite(aled1, LOW);} //also activates 2nd ball cycle
toggleButton button1(2, aledmHIGH, aledmLOW);

int aled2=8;
void aledamHIGH() {digitalWrite(aled2, HIGH);} //button for auto/manual reset
void aledamLOW() {digitalWrite(aled2, LOW);}
toggleButton button2(3, aledamHIGH, aledamLOW);

int aled3=9;
void aled1HIGH() {digitalWrite(aled3, HIGH);} //aled1-aled10 determine which pins will be set
void aled1LOW() {digitalWrite(aled3, LOW);}
toggleButton button3(4, aled1HIGH, aled1LOW);
int aledr;

void setup() {
// put your setup code here, to run once:
pinMode(aled1,OUTPUT);
pinMode(aled2,OUTPUT);
pinMode(aled3,OUTPUT);
}

void loop() {
// put your main code here, to run repeatedly:
aledr = digitalRead(aled1);
easyRun();

if (aledr==LOW){
digitalWrite (aled2,LOW);
digitalWrite (aled3,LOW);
}

}

Presumably it's easyRun that's doing it. I would try only calling it if aledr is high.

Hello

toggleButton can't be deactivated : update is done once per loop(), within easyRun().
Your problem is probably due to a conflict with some digitalWrite remaining in loop() function

I can try to help you anyway.

Do you confirm pushButtons are wired as below?
PIN-----PB-----GND

You can also add some Serial.print in callback functions (void aledmHIGH() & co) to understand what is happening.

I know its been a bit, but I have not been able to resolve this issue. I have been studying up on how and when to use VOID, but I am not sure how to apply the VOID statement above. I have actually built the apparatus that houses the buttons and noticed a different issue. If I push the main on, the sub buttons work as intended. If I turn the master off then back on, the sub buttons require two presses to activate the led. If the main button is off, if I push a sub button once, then turn on the main, it only takes one push to activate the LED. I have a few days off so I will be able to focus on this project and to be more respondent.

'void' is not a statement, it is a data type which basically means, "a nothing".

Also I can see that you know how to use code tags from a previous post, so please go back and add them.

Oops, forgot about that. Here is the code properly inserted.

#include <easyRun.h>

int aled1=7;
void aledmHIGH() {digitalWrite(aled1, HIGH);}  //button to activate/deactivate spare setter
void aledmLOW()  {digitalWrite(aled1, LOW);}   //also activates 2nd ball cycle
toggleButton button1(2, aledmHIGH, aledmLOW);

int aled2=8;             
void aledamHIGH() {digitalWrite(aled2, HIGH);}  //button for auto/manual reset
void aledamLOW()  {digitalWrite(aled2, LOW);}
toggleButton button2(3, aledamHIGH, aledamLOW);

int aled3=9;
void aled1HIGH() {digitalWrite(aled3, HIGH);}  //aled1-aled10 determine which pins will be set
void aled1LOW()  {digitalWrite(aled3, LOW);}
toggleButton button3(4, aled1HIGH, aled1LOW);
int aledr;

void setup() {
  // put your setup code here, to run once:
pinMode(aled1,OUTPUT);
pinMode(aled2,OUTPUT);
pinMode(aled3,OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
aledr = digitalRead(aled1);  
easyRun();

if (aledr==LOW){ 
digitalWrite (aled2,LOW);
digitalWrite (aled3,LOW);
}

}

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