Tonuino-Always queue Update

Hi @Thomas-Lehnert Thomas.

Ich wollte heut ein Update auf die Version „2022-01-18-Vordef-AiO-5Ta-LEDAnim“ machen, erhalte aber eine Fehlermeldung beim hochladen.

exit status 1
‚JumpForw‘ was not declared in this scope

Er bezieht sich dabei bei mir auf Zeile 5405

       JumpForw();                          // Titelsprung Vorwärts bei longpress im 5 Tastenmodus

Ich hatte in Zeile 96 Longpress ausgeschaltet.

//#define JumpLongPress // Titelsprung bei Longpress Vorw. Rückw. Taste bei der 5 ButtonVersion

Wenn ich es einschalte dann ist dei Fehlermeldung weg und das Update läuft durch.

Da ist wohl noch ein bisher unentdeckter Bug drin. Ich werde das prüfen und beseitigen. Danke für die Info.

Du kannst das im Scetch selbst fixen. Dazu über suchen JumpForw(); finden und wie unten gezeigt in die #ifdef und #endif einklammern.

          #ifdef JumpLongPress
           JumpForw();                          // Titelsprung longpress im 5 Tastenmodus
           #endif

Das gleiche mit JumpBackw(); . Auch hier in die #ifdef und #endif einklammern.

        #ifdef JumpLongPress
         JumpBackw();                   // Sprung rückwärts 5 Tastenmodus durch longpress
        #endif

Ich werde das auch gleich auf Github fixen, so dass da auch wieder alles ok. ist.
Das musst du insgesamt für 4 Buttons machen. Button 2 bis 5 jeweils bei Longpress.

So, Auf Github ist es gefixt.

1 „Gefällt mir“

moin @Thomas-Lehnert nachdem du mir letztens geholfen hast die Ordnerwiederholfunktion zu Programmieren, benötige ich nun deine Hilfe erneut.

Ich möchte gerne für die nächste Box den KY-040 Drehgeber verbauen scheitere aber grade beim kompilieren,

KY-040 Drehgeber TonUino

ich habe versucht diesen Code bei deinem zu Integrieren

sieht zur Zeit so aus.

// ************************************************************************************************
// *************** Einbinden der Bibliotheken *****************************************************

#include <DFMiniMp3.h>
#include <EEPROM.h>
#include <JC_Button.h>
#include <MFRC522.h>
#include <SPI.h>
#include <SoftwareSerial.h>
#ifndef AiO
#include <avr/sleep.h>
#endif
#ifdef LED_SR
#include <Adafruit_NeoPixel.h>
#endif
#ifdef ROTARYENCODER
#include <ClickEncoder.h>
#include <TimerOne.h>
#define ENCODER_PIN_A    5
#define ENCODER_PIN_B    6
#define ENCODER_PUSH_BUTTON A3

ClickEncoder *encoder;
int16_t EncoderLast, EncoderValue;

#endif
// =========================================================================================
// *****************************************************************************************
//                           SETUP
// *****************************************************************************************
#ifdef ROTARYENCODER
// Interrupt Service Routine für Timer1
void timerIsr() {
  encoder->service();
}
#endif

void setup()
{
  SETUP = true;                          // Marker setzen, Setup wird durchlaufen
   
   
   #ifdef ROTARYENCODER
    encoder = new ClickEncoder(ENCODER_PIN_A, ENCODER_PIN_B, ENCODER_PUSH_BUTTON);
    Timer1.initialize(1000);
    Timer1.attachInterrupt(timerIsr);
    EncoderLast = -1;
  #endif

  Serial.begin(115200);                  // serielle Schnittstelle initialisieren

 

// ************************************************************************************
// ************************* Tasten auslesen ******************************************

void readButtons() 
{
  ButtonOne.read();
  ButtonTwo.read();
  ButtonThree.read();
#ifdef FIVEBUTTONS
  ButtonFour.read();
  ButtonFive.read();
#endif
#ifdef ROTARYENCODER

  EncoderValue += encoder->getValue();

  if (EncoderValue != EncoderLast) {
    if (EncoderValue > EncoderLast) {
      volumeUpButton();
    }
    if (EncoderValue < EncoderLast){
      volumeDownButton();
    }
    EncoderLast = EncoderValue;
    Serial.print(F("Encoder Value: "));
    Serial.println(EncoderValue);
  }
  
  ClickEncoder::Button EncoderButton = encoder->getButton();
  if (EncoderButton != ClickEncoder::Open){
    Serial.print(F("EncoderButton: "));
    Serial.print("Button: ");
    #define VERBOSECASE(label) case label: Serial.println(#label); break;
    switch (EncoderButton) {
      VERBOSECASE(ClickEncoder::Pressed);
      VERBOSECASE(ClickEncoder::Held)
        VERBOSECASE(ClickEncoder::Released)
        VERBOSECASE(ClickEncoder::Clicked)
    case ClickEncoder::DoubleClicked:
      Serial.println("ClickEncoder::DoubleClicked");
      encoder->setAccelerationEnabled(!encoder->getAccelerationEnabled());
      Serial.print("  Acceleration is ");
      Serial.println((encoder->getAccelerationEnabled()) ? "enabled" : "disabled");
    }
  }
#endif
}

Ich weiß leider nicht wieso ich diesen Fehler bekomme.

PS: das ganze soll auf der Classic Platine laufen.

was not declared in this scope ist meistens ein Hinweis darauf, dass vorher irgendwo eine Klammer zu viel ist.
Nur mit Ausschnitten ist das suchen helfen da schwierig.

Leider kann ich den kompletten Code nicht einfügen weil es zu viele Zeichen sind. Mit den Klammern muss ich nochmal prüfen.

Ändere mal diese Zeile in

int16_t EncoderLast ;
int16_t EncoderValue ;

vielleicht hilft das.
Ich habe bisher mit dem rotary Encoder nichts gemacht, deshalb bin ich mit der Programmierung nicht so vertraut. Aber die Fehlermeldung weist darauf hin, dass die Variable EncoderValue nicht deklariert ist. @marco-117 hat in seinem Fork den Rotaryencoder integriert. Vielleicht hat er noch einen Tipp für dich.

Muss ich bei Gelegenheit Mal testen,
@marco-117 s fork unterscheidet sich sehr stark von deinem, hatte ich zuerst versucht die Codeschnipsel von dort zu nehmen hat aber nicht geklappt.

Dein Tipp hat leider nicht funktioniert, habe es aber trotzdem hinbekommen :smiling_face:xD

zum Einen gab es das Problem, dass mir die Library fehlte hab ich dann hierRotaryEncoder Library
gefunden und Runtergeladen.

den Rest hatte ich dann wie Oben, nachdem ich nochmal alles Gelöscht und dann nochmal neu eingefügt hatte kompiliert.

für das Problem, dass der Encoder recht sensibel reagiert habe ich mich an @marco-117 s Trick bedient

#ifdef ROTARYENCODER
  EncoderValue += encoder->getValue();

  if ((EncoderValue >= EncoderLast +3)|| (EncoderValue <= EncoderLast -3)){
    if (EncoderValue >= EncoderLast +3) {
      EncoderValue = EncoderValue -1;
      EncoderLast = EncoderValue;
      volumeUpButton();
    }
    else if (EncoderValue <= EncoderLast -3) {
      EncoderValue = EncoderValue -1;
      EncoderLast = EncoderValue;
      volumeDownButton();
    }

nun Funktioniert erstmal alles zur Zufriedenheit.

Danke Nochmal für Hilfe und Tipps

1 „Gefällt mir“

moin @Thomas-Lehnert, ich hab da nochmal eine Frage zum Ausschalten der Box.

Und zwar hab ich bei mir einen Pololu verbaut, habe ich das richtig verstanden, das ich die Box dann auch über einen Taster ausschalten kann? oder ist das nur so gedacht das die Box nur über den Standbytimer ausgeht und über Pololu eingeschaltet wird?

LG Dennis

Beim Pololuswitch wird die Box nur über den Standby-Timer ausgeschaltet. Wenn du sie zusätzlich über eine Taste Ausschalten willst, brauchst du eine extra Taste. Diese geht von 5V auf den Off Anschluss des Pololuswitch. Es muss aber mit Zwei Dioden eine Entkopplung zum Arduino gemacht werden um den Prozessor nicht zu beschädigen. Schaltung schick ich dir morgen.

Mein Gedanke war eher wie bei @marco-117 s affenbox-fork das über die Software zu lösen, da in Unserer Box zu wenig Platz für noch mehr Komponenten ist xD.

Wenn es da keine Möglichkeit gibt, dann bleibt’s beim 5min standBy Timer.

Das geht auch über Software. Da würde sich anbieten, Play/Pause und Zurück als Tastenkombination mit Longpress. Vor und Zurück sind ja schon zum Ein oder Ausschalten der LEdAnimation belegt. Über die Tastenkombination Shutdown aufrufen, das wär’s.

Moin @Thomas-Lehnert ich bin mir nicht sicher ob ich das richtig verstanden habe was du mir vorgeschlagen hast. Ich Versuche immernoch ein generelles Verständnis für das Programmieren aufzubauen, daher habe ich mir versucht was zu basteln.

Das ganze sieht dann so aus:

static const uint16_t LONGER_PRESS = 2000;
Void ShutDown()

{
.
.
.
#ifdef HW_PowerOff
  digitalWrite(ShutDownPin, LOW);                                   // Ausschalten!, Low Pegel zum Rücksetzen des Einschalt-Flip-Flop
  delay(500);
  digitalWrite(ShutDownPin, HIGH);                                  // Ausschalten!, High Pegel für Pololu Switch
  delay(500);
  digitalWrite(ShutDownPin, LOW);                                   // Widerholung!, Low Pegel zum Rücksetzen des Einschalt-Flip-Flop
  delay(500);
  
if (ButtonTwo.pressedFor(LONGER_PRESS))
{
    shutDown();
}
#endif
.
.
.
.

Meine Idee war über einen längeren Tastendruck die Box auszuschalten. Ist das wie im Code eine Möglichkeit oder hab ich da absoluten Humbug produziert.?

Es ist ein bisschen schwer zu erkennen, was du wie genau einfügen willst. Du machst die Klammer von Shutdown nicht zu. So ist nicht zu erkennen, ob die Abfrage des Buttons innerhalb der Shutdownfunktion machst. Die Abfrage muss auf jeden Fall zu den anderen Buttonabfragen, damit sie ständig geprüft wird. Es bringt ja nix, wenn shutdown erst ausgeführt werden muss, damit geprüft wird, ob der Button gedrückt wurde.

Worauf du bei den Buttons grundsätzlich auch immer achten musst, ist, dass du abfängst, dass mehrere Dinge aufgrund des einen Buttondrucks passieren. Der Longpress für 1 Sekunde passiert ja bevor die 2 Sekunden um sind.

In diesem Thema Ausschalten über Lautstärketasten sind einige Beispiele, wie man das mit den Buttons auch machen kann. Auch mit Kombinationen, sodass man das Problem, das 2 Dinge passieren umgehen kann

Prinzipiell ist dein Ansatz möglich. Du musst die Abfrage für den longerPress aber mit in die Buttons Routine einarbeiten, und zwar direkt hinter der Abfrage für den Longpress. Und direkt das Shutdown aufrufen. In der Poweroff Funktion brauchst du im Scetch nichts ändern. Ich würde den longerPress auch auf wenigstens 5 Sekunden festlegen um ein unbeabsichtigtes abschalten bei Longpress zu verhindern. Aber ganz unproblematisch ist das trotzdem nicht. Besser wäre ein longerPress in zweitastenkombination, z.B. zurück+Pause.
Schau dir Mal in meinem Code an wie die ab und Einschaltung der Led-animation als Kombination von vor und zurück Taste gemacht ist. Auf diese Weise kannst du auch den Shutdown programmieren auch in Verbindung mit longerPress.

1 „Gefällt mir“

Hallo @ClausiusMaximus
So, ich habe das mal ausprobiert. Folgender Code funktioniert über Longpress Pause+Zurück Tasten.

    readButtons();                                      // Tasten auslesen

   // ********************* Ausschalten des Tonuino über Longpress Play und Zurück *****************
if ((ButtonOne.pressedFor(5000)               // 2 Tastendruck 5 sekunden zum Ausschalten
        || ButtonThree.pressedFor(5000))
        && ButtonOne.isPressed()
        && ButtonThree.isPressed()
        && !(ButtonTwo.isPressed()))
        ShutDown();
        
    // ***************** Adminmenu über longPress 3 Tasten aktivieren **************************
.
.
.

Du musst auch keine Variable für LongerPress deklarieren, sondern kannst die Zeit in ms direkt in die Klammer bei pressedFor() schreiben. Es wird zwar kurzzeitig die Leiser Funktion mit gestartet, aber das spielt keine Rolle, weil ja eh abgeschaltet wird.

1 „Gefällt mir“

Das kannst du aber auch unterdrücken, wenn du folgendes ergänzt.

    // ******************* Taste 1 (Play/Pause Taste) ****************************************************
// ------------- ShortPress --------------------------------
.
.
.
.
// ab hier ändern
// ---------------- LongPress -------------------------------------
    else if (ButtonOne.pressedFor(LONG_PRESS)
             && !(ButtonThree.isPressed())
             && ignoreButtonOne == false)                       // Langer Druck Pausetaste für Ansage des aktuellen Tracks
    {                                                           // oder Hörbuch auf Anfang zurücksetzen
.
.
.
    // *************** Taste3 (Zurück/Vol -)  *********************************************
    // ---------------- LongPress -------------------------------------
#ifdef LED_SR_Switch
    if (ButtonThree.pressedFor(LONG_PRESS) 
    && !(ButtonOne.isPressed())
    && lsrSwitch == false)
#endif
#ifndef LED_SR_Switch
    if (ButtonThree.pressedFor(LONG_PRESS)
    && !(ButtonOne.isPressed()))
#endif

Hi @Thomas-Lehnert, vielen Dank für die Hilfe und die Mühe, Ich hab Tatsächlich heute morgen bevor du den Code geschrieben hast mir was in die button abfrage programmiert.

void readButtons()
{
  ButtonOne.read();
  ButtonTwo.read();
  ButtonThree.read();
#ifdef FIVEBUTTONS
  ButtonFour.read();
  ButtonFive.read();
#endif
#ifdef HW_PowerOff
    if ( (ButtonTwo.pressedFor(LONGER_PRESS)) && ButtonTwo.isPressed())
    {
      ShutDown();
    }
#endif    

das ganze sieht so aus.
Testen konnte ich das ganze jetzt erst und ich bin erstaunt es Funktioniert ^^ :grin:

Für mich reicht der Longer_press volkommen, da ich keine LED animation definiert hab.

nächstes ziel ist evtl. ein ausschalt Sound als Shortcut zu definieren, aber das muss zur Zeit nicht sein, da ein Lichtwellenleiter mir anzeigt ob das System an oder aus ist ^^.