Requiring input from two buttons at the same time

hey guys,

I’m trying to increment int screenState when I press button one and two simultaneously. However I cant seem to get them to work together. how can I capture pressing both at once with the way I am setting my inputFlags? setInputFlags() and resolveInputFlags() are both called withing the main loop();

void setInputFlags() {
  for(int i = 0; i < numInputs; 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 < numInputs; i++) {
    if(inputFlags[i] == HIGH) {
      // Input Toggle Logic // all invoked upon bttn press
      inputCounter[i]++;
      updateScreenState(i); 
      printString(i);
      inputFlags[i] = LOW;
    }
  }
}

mzaccaro89:
hey guys,

I’m trying to increment int screenState when I press button one and two simultaneously. However I cant seem to get them to work together. how can I capture pressing both at once with the way I am setting my inputFlags? setInputFlags() and resolveInputFlags() are both called withing the main loop();

void setInputFlags() {

for(int i = 0; i < numInputs; 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 < numInputs; i++) {
    if(inputFlags[i] == HIGH) {
      // Input Toggle Logic // all invoked upon bttn press
      inputCounter[i]++;
      updateScreenState(i);
      printString(i);
      inputFlags[i] = LOW;
    }
  }
}

Let’s be a little reasonable. You cannot and will never be able to press two button switches at the same time. Also, you cannot program an Arduino to even determine if you pressed two button switches at the same time.

So, what is your real time frame for pressing the switches? 1/2 second? 1/10 second? 1/100 second? What?

Paul

I think a little more context is needed, what's going wrong with the code as it is now? Are the input flags not getting set properly or are you not resolving them properly? The way you're handling button inputs with the debouncing and what-not makes me think you might benefit from some interrupts instead

The way you're handling button inputs with the debouncing and what-not makes me think you might benefit from some interrupts instead

Nonsense. Interrupts are NOT the solution.

What is needed is to read the state of the two switches and THEN determine what to do, based on whether both switches are CURRENTLY pressed. What OP is currently doing is reading one switch after another, and making decisions based on one switch's state.

void setInputFlags() {
   int pincapture
   for(int i = 0; i < numInputs; i++) {
       pincapture[i] = digitalRead(inputPins[i]);
   }
 \\ Now you can process pincapture[] solely to determine which actual buttons were on at the same moment.  
\\ Add your existing code starting with your for loop to process everything else with debound outputs.
}

something like if (digitalread(pinX1) ==1) and (digitalread(pinX2) == 1) might work.

Idahowalker:
something like if (digitalread(pinX1) ==1) and (digitalread(pinX2) == 1) might work.

It might, IF you put the parentheses in the right places.

Slumpert:

void setInputFlags() {

int pincapture
  for(int i = 0; i < numInputs; i++) {
      pincapture[i] = digitalRead(inputPins[i]);
  }
\ Now you can process pincapture solely to determine which actual buttons were on at the same moment. 
\ Add your existing code starting with your for loop to process everything else with debound outputs.
}

and how would i be able to use this in an if statement to do something like change a lcd screen, which is my ultimate goal. Press both buttons at once to advance to the next screen,

mzaccaro89:
and how would i be able to use this in an if statement to do something like change a lcd screen, which is my ultimate goal. Press both buttons at once to advance to the next screen,

The usual method is by applying logical operators in various user-defined combinations to one or more variables within the parentheses. The bottom line being, does the stuff in the parentheses evaluate to true (a non-zero value) or false (value of zero).

To construct a correct set of conditions you need to account for operator precedence, also discussed on the linked page.

dougp:
The usual method is by applying logical operators in various user-defined combinations to one or more variables within the parentheses. The bottom line being, does the stuff in the parentheses evaluate to true (a non-zero value) or false (value of zero).

To construct a correct set of conditions you need to account for operator precedence, also discussed on the linked page.

dougp:
The usual method is by applying logical operators in various user-defined combinations to one or more variables within the parentheses. The bottom line being, does the stuff in the parentheses evaluate to true (a non-zero value) or false (value of zero).

To construct a correct set of conditions you need to account for operator precedence, also discussed on the linked page.

I’m familiar with the logical operators, but how does the suggested “pincapture” allow me to compare when both buttons are pressed at the same time

bool setInputFlags()
{
  // First, we debounce everything
  unsigned long lastStateChangeTime = 0;
  if (millis() - lastStateChangeTime < debounceDelay)
    return;

  // Now we look for state changes
  bool stateChanged = false;
  for (int i = 0; i < numInputs; i++)
  {
    bool inputState[i] = digitalRead(inputPins[i]);

    if (inputState[i] != lastInputState[i])
    {
      stateChanged = true;
      lastInputState[i] = inputState[i];
      inputFlags[i] = inputState[i];
    }
  }

  // If anything changed, restart the debounce timer
  if (stateChanged)
    lastStateChangeTime = millis()
  }

  return stateChanged;
}

Then you can use this to trigger something if 1 and 2 are now both HIGH and weren’t before:

  static bool lastExtendedState = false;
  if (inputFlags[1] && inputFlags[2] && !lastExtendedState)
  {
    lastExtendedState = true;
    // Both 1 and 2 are now down and weren't before
  }

johnwasser:

bool setInputFlags()

{
  // First, we debounce everything
  unsigned long lastStateChangeTime = 0;
  if (millis() - lastStateChangeTime < debounceDelay)
    return;

// Now we look for state changes
  bool stateChanged = false;
  for (int i = 0; i < numInputs; i++)
  {
    bool inputState[i] = digitalRead(inputPins[i]);

if (inputState[i] != lastInputState[i])
    {
      stateChanged = true;
      lastInputState[i] = inputState[i];
      inputFlags[i] = inputState[i];
    }
  }

// If anything changed, restart the debounce timer
  if (stateChanged)
    lastStateChangeTime = millis()
  }

return stateChanged;
}




Then you can use this to trigger something if 1 and 2 are now both HIGH and weren't before:


static bool lastExtendedState = false;
  if (inputFlags[1] && inputFlags[2] && !lastExtendedState)
  {
    lastExtendedState = true;
    // Both 1 and 2 are now down and weren’t before
  }

johnwasser:

bool setInputFlags()

{
  // First, we debounce everything
  unsigned long lastStateChangeTime = 0;
  if (millis() - lastStateChangeTime < debounceDelay)
    return;

// Now we look for state changes
  bool stateChanged = false;
  for (int i = 0; i < numInputs; i++)
  {
    bool inputState[i] = digitalRead(inputPins[i]);

if (inputState[i] != lastInputState[i])
    {
      stateChanged = true;
      lastInputState[i] = inputState[i];
      inputFlags[i] = inputState[i];
    }
  }

// If anything changed, restart the debounce timer
  if (stateChanged)
    lastStateChangeTime = millis()
  }

return stateChanged;
}




Then you can use this to trigger something if 1 and 2 are now both HIGH and weren't before:


static bool lastExtendedState = false;
  if (inputFlags[1] && inputFlags[2] && !lastExtendedState)
  {
    lastExtendedState = true;
    // Both 1 and 2 are now down and weren’t before
  }

so I can replace my code with this for a two button press? or add it in addition to what I have already? Also, I’m assuming when handling a single button press i can do this?

if(inputFlags[1] && !lastExtendedState)
{
 //button one now down
 lastExtendedState== true;
}

johnwasser:

bool setInputFlags()

{
  // First, we debounce everything
  unsigned long lastStateChangeTime = 0;
  ....

[/quote]

better make that variable static if you want to make it work

[code]
static unsigned long lastStateChangeTime = 0;
...