1

I'm using the PunchThrough Bean and trying to build a two button project that has multiple functions. The idea is the user can press button 1 or button 2 for either short or long presses, or they can press both buttons simultaneously for a short or long press. This would give the user up to 6 different functions. Below is my code. I can get button 1 or button 2 press to work, but can't get pressing both to work. Also, I can't figure out how to have a function depending on how long a button sequence was pushed. Any help would be greatly appreciated.

const int btn0 = 2;
const int btn1 = 3;

void setup() {
  Bean.enableWakeOnConnect(true);
  Bean.enablePairingPin(true);
  BeanHid.enable();
  pinMode(btn0, INPUT_PULLUP);
  pinMode(btn1, INPUT_PULLUP);
}

void loop() {
  bool connected = Bean.getConnectionState();
  pinMode(btn0, INPUT_PULLUP);
  pinMode(btn1, INPUT_PULLUP);

  if (connected) {
    int btn0State = digitalRead(btn0);
    int btn1State = digitalRead(btn1);

    if ((btn0State == LOW) && (btn1State == HIGH)) {
      Bean.setLed(255, 0, 0);
      Serial.print("up");
      BeanHid.sendKey(KEY_UP_ARROW);
      Bean.sleep(500);
      Bean.setLed(0, 0, 0);
    }

    if ((btn1State == LOW) && (btn0State == HIGH)) {
      Bean.setLed(0, 255, 0);
      Serial.print("down");
      BeanHid.sendKey(KEY_DOWN_ARROW);
      Bean.sleep(500);
      Bean.setLed(0, 0, 0);
    }

    if ((btn1State == LOW) && (btn0State == LOW)) {
      Bean.setLed(0, 0, 255);
      Serial.print("right");
      BeanHid.sendKey(KEY_RIGHT_ARROW);
      Bean.sleep(500);
      Bean.setLed(0, 0, 0);
    }

  }
}
1
  • We need a FAQ for buttons, multi-buttons, debouncing, menu navigation ..
    – user31481
    Nov 2, 2017 at 16:48

1 Answer 1

2

Don't act immediately when a button gets pressed, instead when a button is pushed all you do is set the timestamp on that button and set a flag.

Then when it is released or the time elapsed is large enough do the appropriate thing.

void loop(){
    int btn1State = digitalRead(btn1);
    static bool button1 = false;
    static unsigned long time1 = 0;

    if (btn0State == LOW && !button1) {
        button1 = true;
        time1 = millis();
    }

    if (btn0State == LOW && button1) {
        if(millis() - time1  > SHORT){
            //do long action
            time1 = millis(); //reset timer
        }
    }

    if (btn0State == HIGH && button1) {
        button1 = false;
        //do short action
    }

}
2
  • 1
    That would cause bad user experience. When a button has both a “short press” and a “long press” action, user expectation is that the “long press” action happens as soon as the press reaches the required duration, not when the button is released. Otherwise it would be, for the user, hard to know how long is long enough. Nov 2, 2017 at 16:41
  • @EdgarBonet fixed the answer Nov 2, 2017 at 16:45

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.