Softwareseitige Mehrfachbelegung der Playtaste

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:

  1. Kurzer Tastendruck: Pause/Play
  2. Doppeldruck: Ansage des aktuellen Tracks
  3. 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 :slight_smile:
Schöne Grüße

2 „Gefällt mir“