Hallo zusammen, ich habe etwas recherchiert und eine Möglichkeit gefunden mehr als zwei Funktionen über einen Taster sauber auszuführen. Das ganze arbeitet, wie @Thomas-Lehnert auch vorgeschlagen hat, mit der millis Funktion. Fragt mich allerdings nicht genau wie es funktioniert. Folgendes wird ausgeführt:
- Kurzer Tastendruck: Pause/Play
- Doppeldruck: Ansage des aktuellen Tracks
- Langer Druck (zwischen 3 und 8 Sekunden): Ausschalten des Tonuino (ohne Ansage des Tracks)
Bei dem Langen Druck musste die maximale Zeit begrenzt werden (daher 8 Sekunden), da beim Verlassen des Adminmenüs der Tonuino sonst ausgemacht wurde.
Das ist der Code:
// Deklaration von Variablen:
#define LONGER_PRESS 3000 // längerer Druck >= 3 sekunden
// ---------------Zur Erkennung von Mehrfachfunktionen bei Druck auf Play-/Pausetaste-------------------
int lastButtonState = HIGH; // the previous reading from the input pin
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 25; // the debounce time; increase if the output flickers
bool buttonState = HIGH; // saving state of the switch
byte tapCounter; // for saving no. of times the switch is pressed
int timediff; // for saving the time in between each press and release of the switch
bool flag1, flag2; // just two variables
long double presstime, releasetime; // for saving millis at press and millis at release
// in der void loop () eintragen:
// ************** Vorbereitung zur Auswertung der Multifunktionen der Play-/Pausetaste ****************
int reading = digitalRead(ButtonPause);
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
}
}
//when button is pressed
if (buttonState == 0 && flag2 == 0)
{
presstime = millis(); //time from millis fn will save to presstime variable
flag1 = 0;
flag2 = 1;
tapCounter++; //tap counter will increase by 1
//delay(10); //for avoiding debouncing of the button
}
//when button is released
if (buttonState == 1 && flag1 == 0)
{
releasetime = millis(); //time from millis fn will be saved to releasetime var
flag1 = 1;
flag2 = 0;
timediff = releasetime - presstime; //here we find the time gap between press and release and stored to timediff var
//Serial.println(timediff);
//delay(10);
}
// *********** Ende der Vorbereitung zur Auswertung der Multifunktionen der Play-/Pausetaste *************
// ******************* Pause Taste ****************************************************
if ((millis() - presstime) > 300 && buttonState == 1) //wait for some time and if button is in release position
{
if (tapCounter == 1) //if tap counter is 1
{
if (timediff >= LONGER_PRESS && timediff < 8000) //if time diff is larger than LONGER_PRESS = 3s and lower than 8s then its a hold
{
//----fn to call when the button is hold----
#ifdef PUSH_ON_OFF
ShutDown(); // Tonuino Ausschalten
#endif
}
else if (timediff < 300) //if timediff is less than 300 then its a single tap
{
//----fn to call when the button is single taped----
if (activeModifier != NULL) // wenn Modifikation aktiv
if (activeModifier->handlePause() == true) // wenn akt.Modifikation pause Taste sperrt
return; // Abbrechen
if (isPlaying()) // wenn Wiedergabe
{
mp3.pause(); // Pause der Wiedergabe
setstandbyTimer();
}
else if (knownCard) // wenn keine Wiedergabe läuft und karte bekannt
{
mp3.start(); // Wiedergabe starten
disablestandbyTimer();
}
}
}
else if (tapCounter == 2 ) //if tapcounter is 2
{
//----fn to call when doubletap----
if (activeModifier != NULL) // wenn Modifikationskarte aktiv
if (activeModifier->handlePause() == true) // wenn Pausetaste gesperrt - Abbruch
return;
if (isPlaying()) // wenn Wiedergabe läuft
{
uint8_t advertTrack = queue[currentQueueIndex]; // Auslesen der Tracknummer für Ansage Tracknr
// Spezialmodus Von-Bis für Album und Party gibt die Dateinummer relativ zur Startposition wieder
if (myFolder->mode == 8 || myFolder->mode == 9) // Spezialmodus Album oder Spezialmodus Party
{
advertTrack = advertTrack - myFolder->special + 1; // Ansage auf relative Track Nr
}
//************ Rücksetzen - Hörbuch auf Anfang ****************************
// Im Hörbuchmodus wird durch langen Druck Pause Taste der Fortschritt auf Anfang gesetzt
#ifdef HB_Reset
if (myFolder->mode == 5) // Hörbuchmodus
{
currentQueueIndex = 1; // aktueller Track auf 1 setzen
advertTrack = currentQueueIndex; // Ansage auf aktueller Track
mp3.playAdvertisement(advertTrack); // Tracknummer ansagen
#ifndef AiO
EEPROM.update(myFolder->folder, currentQueueIndex); // Track 1 im EEProm speichern
#endif
#ifdef AiO
EEPROM_update(myFolder->folder, currentQueueIndex); // Track 1 im EEProm speichern
#endif
#ifdef DEBUG
Serial.println(F("Hörbuch Modus -> Anfang"));
#endif
mp3.playFolderTrack(myFolder->folder, currentQueueIndex); // aktuellen Track spielen
}
#endif
//************** Ende, Rücksetzen - Hörbuch auf Anfang ***********************
else // alle anderen Abspielmodi
{
mp3.playAdvertisement(advertTrack); // Tracknummer ansagen
}
}
else // wenn keine Wiedergabe läuft
{
playShortCut(0); // Shortcut Pausetaste spielen
}
}
tapCounter = 0;
}
lastButtonState = reading;
// *********** Ende Pausetaste *************************************************
Es funktioniert bisher recht gut. Man hätte sogar noch weitere Funktionen ausführen können. Zum Beispiel lässt sich ein Short Press und danach ein Hold als eine Tastenkombination oder ein Tripple-Druck realisieren.
Quelle zum Nachlesen: https://diyusthad.com/2019/04/arduino-projects-single-switch-multiple-functions.html
Ich werde das mal durch meinen Tester (mein Sohn) ausführlich ausprobieren lassen
Schöne Grüße