Push-Button mit mehreren Funktionen

Guten Morgen,
ich habe folgendes Problem, und zwar möchte ich, dass der Arduino verschiedene Funktionen ausführt, wenn der Knopf 1,2 mal gedrückt wird.

Wenn der Knopf einmal gedrückt wird, soll er Befehl 1 ausführen. Sobald er losgelassen wird, führt er den Befehl nicht mehr aus. (Dies läuft bisher).
Wenn der Knopf nun das zweite mal gedrückt wird, soll er Befehl 2 ausführen. Nach dem loslassen wieder keinen Befehl. Beim nächsten Betätigen wieder den Befehl 1.

Ich wäre für jede Hilfe sehr dankbar!
Ein schönes Wochenende euch!

Ihr Beitrag wurde an seinen aktuellen Speicherort verschoben, da er besser geeignet ist.

Hallo
Poste deinen aktuellen Sketch, wohl formiert, mit Kommentaren und in Code Tags "</>". Diese sind oben zu finden.

@HeinzSchmale

beginne mit dem Sketch

02.Digital / State Change Detection.

Der Schaltet eine LED jedes vierte mal ein oder aus.

Probiere das mal aus.
Wenn das klappt - verwende den Zähler zum Auswählen deiner Funktionen.

Wenn der Counter überläuft, setze ihn zurück auf 0.

Abhängig vom Zähler lässt du nun die eine odere andere Funktion laufen.
also im einfachsten fall mehrere If oder ein switch

if (buttonPushCounter == 0)  doFunctionA();
if (buttonPushCounter == 1)  doFunctionB();
if (buttonPushCounter == 2)  doFunctionC();

wenn die Funktionen nur einmal durchlaufen sollen, dann gibst du diese If eben ans Ende des if(buttonState == HIGH) nachdem die Serielle Ausgabe erfolgt ist

Probier es zunächst selber.
Wenn du strauchelst, zeige deinen Code und schreibe wobei du Hilfe brauchst

Danke erstmal für deine Antwort. Die Variante mit dem Counter und anschließender Auswertung über eine IF-Bedingung mit dem Modulo-Operator habe ich schon ausprobiert. Das Problem, auf welches ich gestoßen bin ist, dass der Counter sobald ich den Button aktiviere nicht +1 hochzählt, sondern willkürlich zwischen 2-8. Hättest du dafür eine Lösung? Habe mir das durch den seriellen Monitor ausgeben lassen.
Danke! :slight_smile:
Gruß

Das ist wohl das, was im Volksmund auch "Prellen" genannt wird

Das IDE Beispiel zeigt auch das entprellen.

hier adaptiert mit Buttons gegen GND

/*
  State change detection (edge detection)

  https://forum.arduino.cc/t/push-button-mit-mehreren-funktionen/927103/6
  
  based on 
  http://www.arduino.cc/en/Tutorial/ButtonStateChange

  by noaisca
*/

// this constant won't change:
constexpr byte buttonPin = A0;    // the pin that the pushbutton is attached to
constexpr byte ledPin = 13;       // the pin that the LED is attached to
constexpr byte noOfStates = 3; 
constexpr byte ON = LOW;          // button closes to GND, ON is LOW
constexpr byte OFF = HIGH;        // 

// Variables will change:
uint8_t buttonPushCounter = 0;   // counter for the number of button presses
bool buttonState = 0;         // current state of the button
bool lastButtonState = 0;     // previous state of the button

void doFunctionA()
{
  Serial.println(F("this is Function A"));
}

void doFunctionB()
{
  Serial.println(F("this is Function B"));
}

void doFunctionC()
{
  Serial.println(F("this is Function C"));
}

void setup() {
  if (ON == HIGH)
      pinMode(buttonPin, INPUT);  // initialize the button pin as without pullup
  else
      pinMode(buttonPin, INPUT_PULLUP);  // initialize the button pin as a input with pullup
  pinMode(ledPin, OUTPUT);           // initialize the LED as an output:
  Serial.begin(115200);              // initialize serial communication:
}

void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);
  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == ON) {
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter++;
      if (buttonPushCounter >= noOfStates) buttonPushCounter = 0; // rollover
      Serial.println(F("on"));
      Serial.print(F("number of button pushes: "));
      Serial.println(buttonPushCounter);
      switch (buttonPushCounter)
      {
        case 0: doFunctionA(); break;
        case 1: doFunctionB(); break;
        case 2: doFunctionC(); break;
      }
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println(F("off"));
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

  // turns on the LED every n button pushes by checking the modulo 
  if (buttonPushCounter % noOfStates == 0) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
}

warum man zum Forum-How To lesen mehr als eine Stunde braucht verstehe ich zwar nicht, aber seis drumm.

Zuerst mal entprellen und dann auf Flanken triggern nicht auf HIGH zustand.

Entprellen. Am einfachsten ein delay(20) nach dem Lesen des Tasters einfügen.
Flanken triggern: siehe #4 "02.Digital / State Change Detection" Beispiel der IDE.

Grüße Uwe

Hallo
Ich habe in meiner Sketchkiste einen Sketch, für eine ähnliche Aufgabenstellung, gefunden, den ich ein bißchen angepasst habe. Im wesentlichen enthält der Sketch zwei Objekte, eins für den Button und eins für die Befehle und eine entsprechende Methode für die Datenverarbeitung.

/* BLOCK COMMENT
  ATTENTION: This Sketch contains elements of C++.
  https://www.learncpp.com/cpp-tutorial/
  https://forum.arduino.cc/t/push-button-mit-mehreren-funktionen/927103
*/
#define ProjectName "Push-Button mit mehreren Funktionen"
//======================================================================================
// USER FUNCTIONS
void keinBefehl() {
  Serial.println(__func__);
}
void befehl1() {
  Serial.println(__func__);
}
void befehl2() {
  Serial.println(__func__);
}
void befehl3() {
  Serial.println(__func__);
}
//======================================================================================
// HARDWARE SETTINGS
// YOU MAY NEED TO CHANGE THESE CONSTANTS TO YOUR HARDWARE AND NEEDS
constexpr byte ButtonPin {A0};      // portPin o---|button|---GND
// CONSTANT DEFINITION
enum {Button_};
constexpr byte Input_[] {ButtonPin};
// FORWARD DECLARATION USING FUNCTION PROTOTYPE
void keinBefehl();
void befehl1();
void befehl2();
void befehl3();
// VARIABLE DECLARATION AND DEFINITION
unsigned long currentTime;
struct BUTTON {
  byte pin;
  bool statusQuo;
  int counter;
  int call;
  unsigned long stamp;
  unsigned long duration;
} button_ {Input_[Button_], false, 0, 0, 0, 20};

struct TASK {
  void (*exec)();
} tasks[] {
  {keinBefehl},
  {befehl1},
  {befehl2},
  {befehl3},
};
// -------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  Serial.println(F("."));
  Serial.print(F("File   : ")), Serial.println(__FILE__);
  Serial.print(F("Date   : ")), Serial.println(__DATE__);
  Serial.print(F("Project: ")), Serial.println(ProjectName);
  pinMode (LED_BUILTIN, OUTPUT);  // used as heartbeat indicator
  //  https://www.learncpp.com/cpp-tutorial/for-each-loops/
  for (auto Input : Input_) pinMode(Input, INPUT_PULLUP);
}
void loop () {
  currentTime = millis();
  digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);
  // button debouncing
  if (currentTime - button_.stamp >= button_.duration) {
    button_.stamp=currentTime;
    bool stateNew = !digitalRead(button_.pin);
    // state change detection
    if (button_.statusQuo != stateNew) {
      button_.statusQuo = stateNew;
      enum {Released, Pressed};
      enum {Idle, Tasks};
      // action on new button state
      switch (stateNew) {
        case Released:
          button_.call = Idle;
          break;
        case Pressed:
          button_.call = Tasks + button_.counter;
          ++button_.counter %= (sizeof(tasks) / sizeof(tasks[0]) - Tasks);
          break;
      }
    }
  }
  // execute selected task 
  tasks[button_.call].exec();
  // for test purposes only
  delay (250); 
}

Viel Spass damit beim Spielen.
Ich wünsche ein geschmeidges Wochenende und viel Spass beim Programmieren in C++.

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