Wozu braucht man die ignoreXxxButton

Schönen Abend an die Software Experten. Ich gucke mir grad den Code an und bin über die ignoreXxxButton Variablen gestolpert. Erkenne aber nicht warum man die eingeführt hat. Hat jemand einen Tipp. Würde das gerne verstehen.

if (pauseButton.wasReleased())                              // wenn Pausetaste gedrückt wurde
{
  if (activeModifier != NULL)                               // wenn Modifikation aktiv
    if (activeModifier->handlePause() == true)              // wenn akt.Modifikation pause Taste sperrt
      return;                                               // Abbrechen
  if (ignorePauseButton == false)                           // Wenn Taste gelesen
    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();
    }
  ignorePauseButton = false;                                // Pausetaste auswerten
}

Gute Nacht

Guten Morgen Nick,
ich stehe auch noch nicht im Code, aber ich denke für den Krabbelmodus.
Denn dort werden die Tastendrücke ignoriert.

Der Krabblermodus wird in einem Modifier geregelt und kontrolliert über das handlePause() die Pause Funktion.

Ich müsste jetzt auch schauen wo die ignoreButton wieder auf true gesetzt werden um eine Ausage zu treffen.
Aber das ist denke ich zum entprellen. Das definitiv nur einmal mp3.pause ausgeführt wird.

Ich glaube, ignoreXXXButton verhindert, dass nach .pressedFor(LONG_PRESS) auch noch .wasReleased() ausgeführt wird.

if (downButton.pressedFor(LONG_PRESS)) {
#ifndef FIVEBUTTONS
  if (isPlaying()) {
    if (!mySettings.invertVolumeButtons) {
      volumeDownButton();
    }
    else {
      previousButton();
    }
  }
  else {
    playShortCut(2);
  }
  ignoreDownButton = true;
#endif
} else if (downButton.wasReleased()) {
  if (!ignoreDownButton) {
    if (!mySettings.invertVolumeButtons) {
      previousButton();
    }
    else {
      volumeDownButton();
    }
  }
  ignoreDownButton = false;
}
1 „Gefällt mir“

Hallo @Gute_Laune,

ich hatte auch eine Art Semaphore vermutet, aber wenn pressedFor(LONG_PRESS) ausgeführt wird, dann wird wegen des else if wasReleased() sowieso nicht mehr abgefragt. Daher macht es irgendwie keinen Sinn. Jedenfalls nicht vor dem Hintergrund.
Aber über mehrere Zyklen gedacht macht es ggf. Sinn. Wenn ich die Taste lange drücke, passt er das Volume an und unterdrückt für den nächsten Zyklus ein previous, wenn man den Button irgendwann wieder los lässt. Aber warum hat man dann nicht einfach ein shortPressed definiert?

Ich denke ich habs verstanden. Danke für den Denkanstoß.

Dann noch ne Frage für die ganz Dummen. invertVolumeButtons meint vermutlich keine Invertierung des VolumeButtons (z.B. + wird zu - oder umgekehrt) als solches, sondern einen Swap von Volume und Next/Prev-Buttons, oder?

MfG, Nick

Ja genau, die Funktion tauscht was bei langem und was bei kurzem Druck passiert. Standardmäßig ist der Wert true also getauscht. Deshalb muss man im Menü zum ändern „Nein“ auswählen um das umzustellen

Ich meine das hat die Funktion, dass eine betätigte taste nur einmal ausgewertet wird. Ansonsten würde eine gedrückte taste bei jedem Durchlauf der Loop erneut ausgewertet werden und einen vielfachen Aufruf der Aktion ausführen. So wird der Tastendruck nur einmal ausgewertet und die Aktion nur einmal ausgeführt. Ausnahme ist hier Longpress. Hier wird die gewünschte Aktion mehrfach ausgeführt solange die betreffende taste gedrückt ist. Sieh Lautstärke erhöhen oder verringern durch Longpress.
Muss mich etwas korrigieren. Es ist so wie gute Laune schreibt. Für die einmalige Auswertung ist das Release verantwortlich, das erst auf das Loslassen der taste die Aktion auslöst.

es hat etwas mit dem Longpress zu tun.

??? ah, klar ;o).

Ich habe es so verstanden wie Thomas angedeutet hat, jedoch mit einer Mischung Gute Laune.
Der Longpress wird bei langem Tastendruck zyklisch durchlaufen und bewirkt damit eine immer wiederkehrende Lautstärkeerhöhung, solange die Taste gedrückt ist. Gleichzeitig setzt er das ignore, dass für seinen eigene Funktion nicht relevant ist. Durch die else if Konstellation kommt der Released Zweig sowieso nicht zum Tragen.
Irgendwann lässt man die Taste los. Dadurch wird der Longpress Zweig nicht mehr bearbeitet, aber das wasRelease würde anschlagen und somit ungewollt ein previous auslösen. Da aber im vorhergehenden Zyklus das ingnore gesetzt wurde, wird der wasReleased zweig einmalig nicht bearbeitet und somit das Released Event unterdrückt.

Gibt es für solche Unterscheidungen keine fertige Button Bibliothek, in der man die unterschiedlichen Tast-Szenarien definiert und die dann nur ein Event auslöst? Dann erspart man sich die ganzen Fallunterscheidungen im Code.

Vermutilch wird deshalb im Rewrite mit der AceButton library gearbeitet.

@Thorsten
Habe mich die Tage mal durch den Code der „alten“ Version gegraben und versucht kleine, einfache Ergänzungen zu machen. Einfache „Hintergrunddienste“. Also eigentlich banale Zyklische Abfragen: wenn das, dann das. Z.B. sowas wie Status LED’s aktualisieren, blinken, faden und zustandsabhängige Aktionen. Oder Abfrage einer IR Schnittstelle. Sowas hängt man eigentlich nur unten in die Main Loop, fragt die Triggerbedingung zyklisch ab und es läuft so nebenher mit.

Dabei hatte ich ziemlich zu kämpfen. Insbesondere mit den Nebenwirkungen des Admin Menüs. Hat man das mal betreten, fängt sich das Menü gerne in internen Warteschleifen (do loop until Tast x). In der Zeit wir die Main Loop für längere Zeit schlicht nicht mehr abgearbeitet. Es gibt also auch keinen Ort mehr, von dem man weiß, dass der regelmäßig abgearbeitet wird für all diese Hintergrundaktualisierungen.

Ein schönes Beispiel, wo das schon mal aufgefallen sein muss ist z.B. der set und checkStandbytimer, oder die readButton Funktion. Eigentlich alles Funktionen die hinten in der Main Loop liegen und einfach in jedem Zyklus einmalig aufgerufen werden müssten, um konsistent für den gesamten Durchlauf die Buttons zu aktualisieren, oder eben die Standbyfunktion oder andere Timeouts zu überwachen. Statt dessen tauchen die Aufrufen an diversen Stellen im Code auf. Derjenige, welcher den Standby implementiert hat, wir ne weile gebraucht haben um alle Stellen zu finden, an denen er den Timer Triggern muss. In der Loop wäre das simpel gewesen. Zurücksetzen wenn beliebiger Button oder isPlaying.

Sowas kann z.B. bei den Mehrfachaufrufen von readButtons fiese Nebeneffekte mit sich bringen. Beim ersten Lesen am Anfang der Loop war es noch kein Long pressed, 100 Takte weiter in einem anderen Zweig mit erneuter Aktualisierung ist es dann doch einer?!

Daher möchte ich für das Redesign vorschlagen, dass man sich auferlegt, auf delays oder Warteschleifen zu verzichten um sicher zu stellen, dass die main loop zuverlässig zyklisch durchlaufen wird. Statt dessen würde sich ein Zustandsautomat anbieten. Wenn die Weiterschaltbedingung nicht erfüllt ist, dann guckt man halt im nächsten Zyklus wieder. Dann kann der Prozessor in der Zwischenzeit was sinnvolles tun, oder sogar schlafen gehen.
Habt Ihr in Erwägung gezogen den Sleepmode des ATMEL und den PinChange Interrupt zu nutzen?

Weiß jemand, ob sich schon einer die Mühe gemacht hat, das Admin Menü auf Zustandsautomat oder ähnliches umzustellen? Bei dem ganzen If else while do ist mir ganz schwindelig geworden ;o).

Hab mal gespickt, gibt interessante Bibliotheken dafür:
Sehr einfach: Zustände mit Transitionen (Wechselbedingung) GitHub - jrullan/StateMachine: State machine library for Arduino
Advanced: Zustände mit Transitionen + Enter und Exit Methode. GitHub - jonblack/arduino-fsm: Arduino library for implementing a finite state machine.
Die Enter Methode kann insbesondere interessant für das Admin Menü sein, um hier einmalig die Audioansage für den Zustand zu triggern.
Und super spannend klingt dieses Paket. GitHub - tinkerspy/Automaton: Reactive State Machine Framework for Arduino

Bis wann kann man denn mit einem ersten Release der neuen Version rechnen?

MfG, Nick

Evtl sollte man auch auf eine andere Hardware umsteigen die fast gleich groß ist, aber mehr Speicher hat. Die Esp bieten sich an.

Da gibt es schon diverse Forks, die auf den ESP aufbauen.