Mehrfachbelegung von 4 Buttons

Hallo Community, bei der Programmierung habe ich folgende ungelöste Aufgabenstellung.
Ich möchte mit vier Taster zehn Funktionen schalten. Das Problem beginnt dann, wenn eine Tastenkombination von zwei Tasten eine Funktion auslösen soll bei welcher die Einzeltasten bereits mit einer Funktion verknüpft bzw. belegt ist.

Aus beigefügter Tabelle ist ersichtlich, dass Button 2 bei zwei von vier Funktionen beteiligt ist.
Versuche ich Ereignis no.6 zu aktivieren, wird z.B. gleichzeitig auch Ereignis no.2 aktiviert.
Dabei werden die Ereignisse nicht oder wechselweise ausgeführt. Gibt es überhaupt eine Möglichkeit, diese Aufgabe via Programm zu lösen?
Vielleicht hat ja jemand einen Lösungsvorschlag. Vielen Dank vorab!

Wie soll Dir jemand ohne Schaltung und ohne Sketch helfen können?
Setze Deinen Sketch bitte in Codetags. Wie das geht, steht hier.

Gruß Tommy

Ja, natürlich. Das wäre jetzt nicht das erste System, das mit mit Mehrfachtastendrücken umgehen muss.

Tipps:

  • Tastendrücke bearbeite ich am liebsten durch Erkennung der Flankenwechsel "nicht aktiv" nach "aktiv" und zurück (PRESSED und RELEASED Events).
  • Bei Mehrfachtasten muss man sich darauf einstellen, dass kein Benutzer die exakt gleichzeitig drückt.
  • Die Aktion, die auf die Taste hin ausgeführt werden soll, lege ich meist auf den RELEASED-Event - das hilft auch beim Behandeln von langen Tastendrücken.

So - und jetzt kommst Du mit dem was Du schon hast!

Wofür ist diese Aufgabenstellung im echten Leben?

Du musst dir die Zeit des ersten Erkennens merken, und dann x ms prüfen, on ein weiterer Taster kommt. Er wenn die Wartezeit ohne Änderung abgelaufen ist, die Aktion auslösen.

// Forensketch
// https://forum.arduino.cc/

#include <Streaming.h>     // https://github.com/janelia-arduino/Streaming

//#define DEBUG              // Wenn aktiviert, werden Zwischenwerte ausgegeben

#ifdef DEBUG
  #define DBG_PRINTLN(...) Serial << __VA_ARGS__ << endl
#else
  #define DBG_PRINTLN(...)
#endif

constexpr byte buttons {4};

constexpr bool pressed {LOW};
constexpr uint32_t debounceTime {50};
byte step;

struct BUTTON
{
  const byte pin;
  uint32_t pressTime;
  bool state;
};

BUTTON button[buttons]
{{2, 0, !pressed}, {3, 0, !pressed}, {4, 0, !pressed}, {5, 0, !pressed}};

void setup()
{
  Serial.begin(115200);
#if (defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2650)) // https://github.com/arduino/Arduino/issues/10764
  delay(300);
#endif
  Serial << (F("\r\nStart...\r\n")) << endl;
  DBG_PRINTLN(__FILE__);
  DBG_PRINTLN( __TIMESTAMP__);
  for (byte b = 0; b < buttons; b++)
  {
    pinMode(button[b].pin, INPUT_PULLUP);
  }
}

void  loop()
{
  readButtons();
  checkButtons();
}

void checkButtons()
{
  switch (step)
  {
    case 0:
      if (button[0].state == pressed && button[1].state == !pressed && button[2].state == !pressed && button[3].state == !pressed)
      {
        Serial << F("Taste 1 gedrückt") << endl;
        step++;
      }
      break;
    case 1:
      if (button[0].state == !pressed && button[1].state == pressed && button[2].state == !pressed && button[3].state == !pressed)
      {
        Serial << F("Taste 2 gedrückt") << endl;
        step++;
      }
      break;
    case 2:
      if (button[0].state == !pressed && button[1].state == !pressed && button[2].state == pressed && button[3].state == !pressed)
      {
        Serial << F("Taste 3 gedrückt") << endl;
        step++;
      }
      break;
    case 3:
      if (button[0].state == !pressed && button[1].state == !pressed && button[2].state == !pressed && button[3].state == pressed)
      {
        Serial << F("Taste 4 gedrückt") << endl;
        step++;
      }
      break;
    case 4:
      if (button[0].state == pressed && button[1].state == pressed && button[2].state == !pressed && button[3].state == !pressed)
      {
        Serial << F("Taste 1 & 2 gedrückt") << endl;
        step++;
      }
      break;
    case 5:
      if (button[0].state == pressed && button[1].state == !pressed && button[2].state == pressed && button[3].state == !pressed)
      {
        Serial << F("Taste 1 & 3 gedrückt") << endl;
        step++;
      }
      break;
    case 6:
      if (button[0].state == pressed && button[1].state == !pressed && button[2].state == !pressed && button[3].state == pressed)
      {
        Serial << F("Taste 1 & 4 gedrückt") << endl;
        step++;
      }
      break;
    case 7:
      if (button[0].state == !pressed && button[1].state == pressed && button[2].state == pressed && button[3].state == !pressed)
      {
        Serial << F("Taste 2 & 3 gedrückt") << endl;
        step++;
      }
      break;
    case 8:
      if (button[0].state == !pressed && button[1].state == pressed && button[2].state == !pressed && button[3].state == pressed)
      {
        Serial << F("Taste 2 & 4 gedrückt") << endl;
        step++;
      }
      break;
    case 9:
      if (button[0].state == !pressed && button[1].state == !pressed && button[2].state == pressed && button[3].state == pressed)
      {
        Serial << F("Taste 3 & 4 gedrückt") << endl;
        step++;
      }
      break;
    default:
      step = 0;
      break;
  }
}

void readButtons()
{
  for (byte b = 0; b < buttons; b++)
  {
    if (!digitalRead(button[b].pin))
    {
      button[b].pressTime = millis();
      button[b].state = pressed;
    }
    else if (millis() - button[b].pressTime > debounceTime)
    {
      button[b].state = !pressed;
    }
  }
}

zweite Variante:

// Forensketch
// https://forum.arduino.cc/

#include <Streaming.h>     // https://github.com/janelia-arduino/Streaming

//#define DEBUG              // Wenn aktiviert, werden Zwischenwerte ausgegeben

#ifdef DEBUG
  #define DBG_PRINTLN(...) Serial << __VA_ARGS__ << endl
#else
  #define DBG_PRINTLN(...)
#endif

constexpr byte buttons {4};

constexpr bool pressed {LOW};
constexpr uint32_t debounceTime {50};
byte step;
byte buttonState;

struct BUTTON
{
  const byte pin;
  uint32_t pressTime;
};

BUTTON button[buttons]
{{2, 0}, {3, 0}, {4, 0}, {5, 0}};

void setup()
{
  Serial.begin(115200);
#if (defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2650)) // https://github.com/arduino/Arduino/issues/10764
  delay(300);
#endif
  Serial << (F("\r\nStart...\r\n")) << endl;
  DBG_PRINTLN(__FILE__);
  DBG_PRINTLN( __TIMESTAMP__);
  for (byte b = 0; b < buttons; b++)
  {
    pinMode(button[b].pin, INPUT_PULLUP);
  }
}

void  loop()
{
  readButtons();
  checkButtons();
}

void checkButtons()
{
  switch (step)
  {
    case 0:
      if (buttonState == B00000001)
      {
        Serial << F("Taste 1 gedrückt") << endl;
        step++;
      }
      break;
    case 1:
      if (buttonState == B00000010)
      {
        Serial << F("Taste 2 gedrückt") << endl;
        step++;
      }
      break;
    case 2:
      if (buttonState == B00000100)
      {
        Serial << F("Taste 3 gedrückt") << endl;
        step++;
      }
      break;
    case 3:
      if (buttonState == B00001000)
      {
        Serial << F("Taste 4 gedrückt") << endl;
        step++;
      }
      break;
    case 4:
      if (buttonState == B00000011)
      {
        Serial << F("Taste 1 & 2 gedrückt") << endl;
        step++;
      }
      break;
    case 5:
      if (buttonState == B00000101)
      {
        Serial << F("Taste 1 & 3 gedrückt") << endl;
        step++;
      }
      break;
    case 6:
      if (buttonState == B00001001)
      {
        Serial << F("Taste 1 & 4 gedrückt") << endl;
        step++;
      }
      break;
    case 7:
      if (buttonState == B00000110)
      {
        Serial << F("Taste 2 & 3 gedrückt") << endl;
        step++;
      }
      break;
    case 8:
      if (buttonState == B00001010)
      {
        Serial << F("Taste 2 & 4 gedrückt") << endl;
        step++;
      }
      break;
    case 9:
      if (buttonState == B00001100)
      {
        Serial << F("Taste 3 & 4 gedrückt") << endl;
        step++;
      }
      break;
    default:
      step = 0;
      break;
  }
}

void readButtons()
{
  for (byte b = 0; b < buttons; b++)
  {
    if (!digitalRead(button[b].pin))
    {
      button[b].pressTime = millis();
      bitSet(buttonState, b);
    }
    else if (millis() - button[b].pressTime > debounceTime)
    {
      bitClear(buttonState, b);
    }
  }
}

edit: noch ne Variante:

// Forensketch
// https://forum.arduino.cc/

#include <Streaming.h>     // https://github.com/janelia-arduino/Streaming

//#define DEBUG              // Wenn aktiviert, werden Zwischenwerte ausgegeben

#ifdef DEBUG
  #define DBG_PRINTLN(...) Serial << __VA_ARGS__ << endl
#else
  #define DBG_PRINTLN(...)
#endif

constexpr byte buttons {4};

constexpr bool pressed {LOW};
constexpr uint32_t debounceTime {50};
byte step;
byte buttonState;
byte lastState;

struct BUTTON
{
  const byte pin;
  uint32_t pressTime;
};

BUTTON button[buttons]
{{2, 0}, {3, 0}, {4, 0}, {5, 0}};

void setup()
{
  Serial.begin(115200);
#if (defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2650)) // https://github.com/arduino/Arduino/issues/10764
  delay(300);
#endif
  Serial << (F("\r\nStart...\r\n")) << endl;
  DBG_PRINTLN(__FILE__);
  DBG_PRINTLN( __TIMESTAMP__);
  for (byte b = 0; b < buttons; b++)
  {
    pinMode(button[b].pin, INPUT_PULLUP);
  }
}

void  loop()
{
  readButtons();
  checkButtons();
}

void checkButtons()
{
  if (buttonState != lastState)
  {
    Serial << F("Taste ");
    switch (buttonState)
    {
      case B00000001:
        Serial << "1";
        break;
      case B00000010:
        Serial << "2";
        break;
      case B00000100:
        Serial << "3";
        break;
      case B00001000:
        Serial << "4";
        break;
      case B00000011:
        Serial << "1 & 2";
        break;
      case B00000101:
        Serial << "1 & 3";
        break;
      case B00001001:
        Serial << "1 & 4";
        break;
      case B00000110:
        Serial << "2 & 3";
        break;
      case B00001010:
        Serial << "2 & 4";
        break;
      case B00001100:
        Serial << "3 & 4";
        break;
    }
    Serial << " gedrückt" << endl;
    lastState = buttonState;
  }
}

void readButtons()
{
  for (byte b = 0; b < buttons; b++)
  {
    if (!digitalRead(button[b].pin))
    {
      button[b].pressTime = millis();
      bitSet(buttonState, b);
    }
    else if (millis() - button[b].pressTime > debounceTime)
    {
      bitClear(buttonState, b);
    }
  }
}

Danke, wno158,
es wird seine Zeit dauern, Deinen Kommentar und Hinweise zu sichten und verarbeiten.
Gruß
Gerhard

Hallo Tommy56,
momentan ist das für mich ein abgegrenztes Problem für die Steuerung von Relais.
In der Tabelle ist das simple, aber hardwaremäßig doch ein Problem für mich.
Gruß
Gerhard

Für die Steuerung von Relais.
Gruß
Gerhard

Hallo wwerner,
das wird für mich eine abendfüllende Herausforderung.
Danke für diesen Hinweis.
Gruß
Gerhard

Danke, my_xy_projekt,
deine Beispiele werden mich geraume Zeit beschäftigen und viel Schweiß fließen lassen....Danke für die Beispiele! :sweat_smile:
Gruß
Gerhard

Tja.. hättest Du zur Verfügung gestellt, was Du hast, hätte man daraus was entwickeln können.
Jetzt musst Du vermutlich erstmal neu lernen :laughing:

Es ist wie beim Führerschein, ich fahre einen PKW und habe theoretisch das Recht auch 7,5t zu fahren. Ich brauch einfach Zeit, mich mit der Programmiersprache und den einzelnen Bedeutungen sowie Auswirkungen auseinanderzusetzen. Ich will das auch nachvollziehen können. Habt bitte Geduld mit mir. Danke! :slightly_smiling_face:
Gruß
Gerhard

Der Lerneffekt ist aber größer, wenn auf das aufgebaut wird, was vorhanden ist.
Vielleicht hilft Dir ja ein wenig Bettlektüre.
Nur bis zur Hälfte. Danach gehts schon ans eingemachte.
Und Du musst es nicht auswendig lernen. Nur wissen, was drin steht.

Vielen, vielen Dank, my_xy_projekt für diese Bettlektüre! Habe das Skript kurz überflogen und habe einen guten Eindruck von dieser Zusammenfassung. Also, es gibt nun sehr viel zu tun.... :relieved:
Gruß
Gerhard

Moin, my_xy_projekt,
habe die letzte deiner Varianten etwas intensiver betrachtet und mir etwas Hardware (je 4x Taster und Leds) aufgebaut. Danach habe ich den Code für die Ausgabe an den Leds aktuallisiert.

// Forensketch
// https://forum.arduino.cc/

#include <Streaming.h>     // https://github.com/janelia-arduino/Streaming

//#define DEBUG              // Wenn aktiviert, werden Zwischenwerte ausgegeben

#ifdef DEBUG
  #define DBG_PRINTLN(...) Serial << __VA_ARGS__ << endl
#else
  #define DBG_PRINTLN(...)
#endif

constexpr byte buttons {4};

constexpr bool pressed {LOW};
constexpr uint32_t debounceTime {50};
byte step;
byte buttonState;
byte lastState;

struct BUTTON
{
  const byte pin;
  uint32_t pressTime;
};

BUTTON button[buttons]
{{2, 0}, {3, 0}, {4, 0}, {5, 0}};

const int ledPin1 = 8;  // the number of the LED pin
const int ledPin2 = 9;  // the number of the LED pin
const int ledPin5 = 10;  // the number of the LED pin
int ledState1 = LOW;  // ledState used to set the LED
int ledState2 = LOW;  // ledState used to set the LED
int ledState5 = LOW;  // ledState used to set the LED

void setup()
{
  Serial.begin(115200);
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin5, OUTPUT);
#if (defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2650)) // https://github.com/arduino/Arduino/issues/10764
  delay(300);
#endif
  Serial << (F("\r\nStart...\r\n")) << endl;
  DBG_PRINTLN(__FILE__);
  DBG_PRINTLN( __TIMESTAMP__);
  for (byte b = 0; b < buttons; b++)
  {
    pinMode(button[b].pin, INPUT_PULLUP);
  }

}

void  loop()
{
  readButtons();
  checkButtons();
}

void checkButtons()
{
  if (buttonState != lastState)
  {
    Serial << F("Taste ");
    switch (buttonState)
    {
      case B00000001:
        Serial << "1";
        ledState1 = HIGH;  // ledState used to set the LED
        digitalWrite(ledPin1, ledState1);
        delay(50);
        ledState1 = LOW;  // ledState used to set the LED
        digitalWrite(ledPin1, ledState1);
        break;
      case B00000010:
        Serial << "2";
        ledState2 = HIGH;  // ledState used to set the LED
        digitalWrite(ledPin2, ledState2);
        delay(50);
        ledState2 = LOW;  // ledState used to set the LED
        digitalWrite(ledPin2, ledState2);
        break;
      case B00000100:
        Serial << "3";
        break;
      case B00001000:
        Serial << "4";
        break;
      case B00000011:
        Serial << "1 & 2";
        ledState5 = HIGH;  // ledState used to set the LED
        digitalWrite(ledPin5, ledState5);
        delay(50);
        ledState5 = LOW;  // ledState used to set the LED
        digitalWrite(ledPin5, ledState5);
        break;
      case B00000101:
        Serial << "1 & 3";
        break;
      case B00001001:
        Serial << "1 & 4";
        break;
      case B00000110:
        Serial << "2 & 3";
        break;
      case B00001010:
        Serial << "2 & 4";
        break;
      case B00001100:
        Serial << "3 & 4";
        break;
    }
    Serial << " gedrückt" << endl;
    lastState = buttonState;
  }
}

void readButtons()
{
  for (byte b = 0; b < buttons; b++)
  {
    if (!digitalRead(button[b].pin))
    {
      button[b].pressTime = millis();
      bitSet(buttonState, b);
    }
    else if (millis() - button[b].pressTime > debounceTime)
    {
      bitClear(buttonState, b);
    }
  }
}

Hier wird meine Aufgabenstellung deutlich!
Wenn "Taste 1" & " Taste 2" gedrückt wird, können die Leds "1", "2" und "5" aufleuchten.
Es soll in diesem Fall nur Led "5" aufleuchten.
Led "1" und "2" dürfen nicht angesprochen werden.
Für diese Aufgabenstellung suche ich eine Lösung!
Gruß
Gerhard

wer oder was drückt denn auf die Tasten?

Wenn die Tasten manuell gedrückt werden, dann wirst du vor einer gemeinsamen Auswertung eine Wartezeit abwarten müssten um sicherzustellen dass die Usereingabe abgeschlossen ist.

Ein Mensch wird es nicht in der gleichen Millisekunde schaffen zwei Taster zu drücken.
(Also das was @wwerner ähnlich vor 3 Tagen schon geschrieben hat.).

Hallo @noiasca,
also, die Tasten werden aktuell mechanisch betätigt. Wenn die "Tasten" elektrisch betätigt werden, dann erfolgt dies ja auch sequentiell, oder täusche ich mich da! Es geht dann nur schneller. Momentan überlege ich, ob man die nicht aktiven, einzelnen Ports nicht geplant auf "INPUT" oder "OUTPUT" zieht.

du siehst ja schön das beim drücken zweier Tasten verschiedene Events ausgelöst werden.

1+3 manuell:

13:37:37.393 -> Taste 3 gedrückt
13:37:37.393 -> Taste 1 & 3 gedrückt

1+3 "gleichzeitig" losgelassen::

13:37:38.329 -> Taste 1 gedrückt
13:37:38.329 -> Taste  gedrückt

verstehst du jetzt das Problem?
So erreichst du keine Prüfung auf zwei Tasten.

edit: das wäre eine Variante die auf die Kombination von weiteren Tastendrücke wartet:

/*
  Mehrfachbelegung von 4 Buttons
  https://forum.arduino.cc/t/mehrfachbelegung-von-4-buttons/1353643/18
  2025-02-16 by noiasca
*/


#include <Streaming.h>                                        // https://github.com/janelia-arduino/Streaming
#include "button.h"                                           
Button button[] {A0, A1, A2, A3};                             // create 4 active LOW buttons

constexpr uint32_t syncDelay {200};                           // time waited to get several button presses
byte buttonState;                                             // current result of button presses
uint32_t lastPress;                                           // when was the last press of any button

constexpr byte buttons {sizeof(button) / sizeof(button[0])};  // get the number of buttons

void setup() {
  Serial.begin(115200);
#if (defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2650)) // https://github.com/arduino/Arduino/issues/10764
  delay(300);
#endif
  Serial << (F("\r\nStart...\r\n")) << endl;
  for (auto &b : button) {
    b.begin();
  }
}

void  loop() {
  readButtons();
  checkButtons();
}

void checkButtons() {
  if (buttonState && millis() - lastPress > syncDelay) {
    Serial << F("Taste(n) ") << _BIN(buttonState) << " gedrückt" << endl;
    switch (buttonState) {
      case 0b00000001: // "1"
        break;
      case 0b0000010:  // "2";
        break;
      case 0b0000100:  // "3";
        break;
      case 0b00001000: // "4";
        break;
      case 0b00000011: // "1 & 2";
        break;
      case B00000101:  // "1 & 3";
        break;
      case B00001001:  // "1 & 4";
        break;
      case B00000110:  // "2 & 3";
        break;
      case B00001010:  // "2 & 4";
        break;
      case B00001100:  // "3 & 4";
        break;
    }
    buttonState = 0;
  }
}

void readButtons() {
  for (size_t b = 0; b < buttons; b++) {
    if (button[b].wasPressed()) {
      //Serial <<F("SinglePress") << b << endl;
      lastPress = millis();
      bitSet(buttonState, b);
    }
  }
}
//

und die button.h in einem weiteren Tab:

/*
  a class to debounce a button
  the program is based on "state change detection" and converted to OOP to make it reusable
  2024-11-09 by noiasca
*/

class Button {                                // a simple class for buttons based on the "Debounce" example
    const uint8_t buttonPin;                  // the GPIO / pin for the button
    static constexpr byte debounceDelay = 30; // the debounce time; Static because we only need one value for all buttons
    const bool active;                        // is the pin active HIGH or active LOW (will also activate the pullups!)
    bool lastButtonState = HIGH;              // the previous reading from the input pin
    uint32_t lastDebounceTime = 0;            // the last time the output pin was toggled

  public:
    /**
       \brief constructor for a button

       The constructor takes the GPIO as parameter.
       If you omit the second parameter, the class will activate the internal pullup resistor
       and the button should connect to GND.
       If you set the second parameter to HIGH, the button is active HIGH.
       The button should connect to VCC.
       The internal pullups will not be used but you will need an external pulldown resistor.

       \param buttonPin the GPIO for the button
       \param active LOW (default) - if button connects to GND, HIGH if button connects to VCC
    */
    Button(uint8_t buttonPin, bool active = LOW) : buttonPin(buttonPin), active(active) {}

    /**
       \brief set the pin to the proper state

       Call this function in your setup().
       The pinMode will be set according to your constructor.
    */
    void begin() {
      if (active == LOW)
        pinMode(buttonPin, INPUT_PULLUP);
      else
        pinMode(buttonPin, INPUT);
    }

    /**
        \brief indicate if button was pressed since last call

        @return HIGH if button was pressed since last call - debounce
    */
    bool wasPressed() {
      bool buttonState = LOW;                                        // for the current reading from the input pin
      byte reading = LOW;                                            // "translated" state of button LOW = released, HIGH = pressed, despite the electrical state of the input pint
      if (digitalRead(buttonPin) == active) reading = HIGH;          // overwrite the current button state (independent from active LOW or active HIGH)
      if ((millis()  - lastDebounceTime) > debounceDelay) {          // If the switch changed, AFTER any pressing or noise
        if (reading != lastButtonState && lastButtonState == LOW) {  // If there was a change and and last state was LOW (= released)
          buttonState = HIGH;
        }
        lastDebounceTime = millis();
        lastButtonState = reading;
      }
      return buttonState;
    }
};
//

Ich habe es ähnlich gelöst. Alle Sekunde wird ausgewertet, welche Tastenkombination gedrückt wurde:

#include <Button_SL.hpp>

using ulong = unsigned long;

class Interval {
public:
  bool operator()(const ulong duration) {
    if (false == isStarted) { return start(false); }
    return (millis() - timeStamp >= duration) ? start(true) : false;
  }
  void stop() { isStarted = false; }

private:
  bool start(bool state = false) {
    isStarted = !state;   // Set the value to true on the first call
    timeStamp = millis();
    return state;
  }

  bool isStarted {false};   // Flag = true if the first Operator() call has been made.
  ulong timeStamp {0};
};

//////////////////////////////////////////////////
// Global constants and variables
//////////////////////////////////////////////////

namespace gc {
constexpr ulong delay {1000};   // in ms
}

Interval interval;
Btn::Button buttons[] {{2}, {3}, {4}, {5}};

//////////////////////////////////////////////////
// Functions
//////////////////////////////////////////////////
template <size_t N> uint8_t checkButtons(Btn::Button (&btns)[N]) {
  uint8_t btnMask {0};
  for (size_t i {0}; i < N; ++i) {
    (btns[i].tick() == true) ? bitWrite(btnMask, i, 1) : bitWrite(btnMask, i, 0);
  }
  return btnMask;
}

void evaluate(uint8_t value) {
  switch (value) {
    case 0b00001000: Serial.println("Button 1 gedrückt"); break;
    case 0b00000100: Serial.println("Button 2 gedrückt"); break;
    case 0b00000010: Serial.println("Button 3 gedrückt"); break;
    case 0b00000001: Serial.println("Button 4 gedrückt"); break;
    case 0b00001100: Serial.println("Button 1 und 2 gedrückt"); break;
    case 0b00000101: Serial.println("Button 2 und 4 gedrückt"); break;
    case 0b00001010: Serial.println("Button 1 und 3 gedrückt"); break;
  }
}

//////////////////////////////////////////////////
// Main
//////////////////////////////////////////////////

void setup() {
  Serial.begin(115200);
  Serial.println("Start");
  // Initialize Buttons
  for (auto& btn : buttons) {
    btn.begin();
  }
}

void loop() {
  uint8_t buttonMask = checkButtons(buttons);
  if (interval(gc::delay)) { evaluate(buttonMask); }
}

Zum Ausprobieren:

1 Like