Button Kurz/Lang Drücken

Aloa,

Was habe ich vor?
Ich möchte einen Button kurz antippen damit eine LED 3 Sek leuchtet.
Ebenfalls möchte ich bei langem drücken das die LED an bleibt aber ohne 3 Sekunden nachzuleuchten. Sprich sobald ich den Knopf los lasse soll die Lampe ausgehen.

Problem:
Die LED leuchtet 3 Sekunden nach und das soll sie nicht sondern nur bei kurzem Drücken.

Sketch:

#include <OneButton.h>

const int buttonPin = 7;     
const int ledPin =  6;      

int buttonState = 0;         
OneButton button(7, true);  

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  

  button.attachClick(singleclick);
  button.attachLongPressStop(longclick);
}

void loop() {

    button.tick();
  delay(10);  
}

void singleclick(){  
  while( digitalRead(7) == 1 )
  {
    digitalWrite(6,HIGH);
    delay(3000);
    digitalWrite(6,LOW);
  }
}

void longclick(){  
  if (buttonState == HIGH) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
}

Wo habe ich den Wurm drin?

Danke schonmal vorab.

Deine Logik ist falsch und Du darfst kein delay() verwenden.

Taster gedrückt? --> led an; millis() in start abspeichern; status = 2 Taster noch gedrückt & millis() > start + lange -> status = 1 Taster losgelassen & status == 1 ? -> led aus status == 2 & millis() > start + 3000? -> led aus; status = 0

Grüße Uwe

Ein großes Problem ist dass du versucht den buttonPin zu interpretieren, obwohl das eigentlich von der Library gemacht wird.

Du verwendest mit
OneButton button(buttonPin, true);

den PIN mit active True

daher - wenn du den pin auch selber auslesen willst, starte den pinMode auch mit den internen Pullup:

pinMode(buttonPin, INPUT_PULLUP);

vor dieser Änderung spielte der Sketch verrückt.

außerdem:

Du hast sauber Konstanten für die Pins definiert - dann nutze diese auch und nicht magic Numbers!
Du fragtest in deinem Code auf buttonState ab, hast aber nie buttonState ausgelesen.
Nutze die Methoden die dir die OneButton bietet, dann brauchst du den buttonPin nicht separat auslesen.
Generell: Serielle Ausgaben helfen dir während der Programmentwicklung, was der Arduino gerade macht. Wenn alles klappt kannst du sie ja wieder entfernen
Im speziellen:
Für den 10ms delay im loop sehe ich keinen Grund.
Der 3000 ms Delay ist stark verbesserungswürdig und das sollte dein nächster Schritt sein, davon wegzukommen.

// http://forum.arduino.cc/index.php?topic=565118.msg3850115#new


#include <OneButton.h>

const int buttonPin = 7;
const int ledPin =  6;
//int buttonState = 0;
OneButton button(buttonPin, true);

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);               // du verwendest den OneButton mit true = aktiveLow ... das setzt einen internen Pullup
  button.attachClick(singleclick);
  button.attachDuringLongPress(duringLongPress);
  button.attachLongPressStop(longPressStop);
}

void loop() {
  Serial.println(digitalRead(buttonPin));
  button.tick();
  // delay(10);                // dieser delay blockiert
}

void singleclick() {
  Serial.print(F("singleClick"));
  digitalWrite(ledPin, HIGH);
  delay(3000);                  // dieses Delay blockiert dir den ganzen loop für 3 Sekunden.
  digitalWrite(ledPin, LOW);
}

void duringLongPress() {
  Serial.print(F("duringLongPress"));
  digitalWrite(ledPin, HIGH);
}

void longPressStop() {
  Serial.print(F("longPressStop"));
  digitalWrite(ledPin, LOW);
}