Seltsamkeit mit auskommentiertem Serial.println()

Ausgangssituation:

  • Arduino nano an 5* MAX7219 an 5* 5x7 dot matrix Anzeigen
  • Drehender inkl. Pushbutton

Was soll die SW machen?

Per Encoder-Click (per Interrupt eingefangen) soll die Funktion change_source() aufgerufen werden. dort sollen dann per rechts- bzw. Linksdrehung des Encoders verschiedene Texte auf dem Display angezeigt werden.

Ich habe zum "Debuggen" zusätzlich 2 LEDs angesteuert. Einmal LED (intern, Pin13), welche alternierend anzeigt, ob der Pushbutton gedrückt wird oder nicht, LED an Pin12 zeigt an, ob ich in der Funktion change_source() drin bin...
Weiterhin gebe ich einige Ausgaben an den seriellen Monitor aus.

DAS alles funktioniert soweit.

Weil ich nun den Code ein wenig aufräumen wollte, habe ich zunächst mal die Serial.print() und Serial.println() auskommentieren wollen.

Sobald ich das

Serial.println(encoderPos, DEC);

in Zeile 165 auskommentiere, funktioniert die SW nicht mehr richtig.

Die ISR (ISR_doEncoderPush()) funktioniert, denn die entsprechende LED geht an und aus.
Die SW geht auch in die Funktion change_source() rein, denn die andere LED geht an und ich kann meine Anzeigen "durchfahren".

Allerdings wird ein weiterer Klick des Encoders NICHT mit einem Verlassen der Funktion change_source() quittiert. (wie gesagt, der Interrupt wird jedoch erkannt)

Nun bin ich mehr als verwirrt. Was hat denn ein Serial.println() mit dem Rest der SW zu tun?

Wo ist mein Denkfehler?

Danke

myfont.h (1.75 KB)

myMAX7219_02a.ino (8.46 KB)

LedControl.cpp (5.28 KB)

LedControl.h (6.55 KB)

Das wirkt eventuell als unfreiwilliges Delay weil du dir den seriellen Ausgangspuffer damit vollballerst. Dann blockiert erst mal die Ausgabefunktion im Hintergrund

Moin,

die Antwort verstehe ich nicht ganz!

Du meinst, die Funktion Serial.println() wirkt wie ein Delay, gut, da könnte ich noch mitgehen.

Allerdings wird doch der Interrupt des Pushbuttons erkannt, denn meine LED (siehe ISR_doEncoderPush()) geht an und aus...

Ich bin auch in der while-Schleife ab Zeile 167 drin, denn Encoder-Drehen-links/ rechts wird erkannt und ausgewertet.

Was hat jetzt aber das Serial.println "ausserhalb" der while-Schleife (ab Zeile 167) mit der Nichterkennung/ Nichtauswertung des nochmaligen Drückens des Pushbuttons zu tun?

verwirrt drein schauend

Das sind eine typische Symptome wenn Du ein Indexüberlauf eines Array hast oder ein Fehler bei Pointern. Du überschreibst eine Variable die sich im Speicher nach dem Array befindet. Ich weiß jetzt nicht welches Array das ist.

Grüße Uwe

Hmmm...ok.

Also ICH mache nix (bewusst) mit Arrays und Pointern.

Wie kann ich jetzt das Problem lösen?

Ich möchte letztlich ja nicht einfach nen Aufruf von Serial.println() im code haben, wenn der gar nicht benutzt wird... das wäre doch ziemlich blöd...

Grüße Mathias

edit: ok, die auszugebenden Zeichen für das Display liegen natürlich jeweils in einem Array (myfont.h)...

Es hat übrigens nichts mit dem Serial.println() allein zu tun, denn wenn ich Zeile 165 AUSkommentiere, dafür Zeile 164 im Code lasse, dann funktioniert das Program wie gewünscht.

Kommentiere ich dann allerdings auch Zeile 164 aus (also 164 UND 165), entsteht das gleiche Phänomen wie im Eingangspost.

Kontrolliere die Programme ob Du nicht irgendwo ein Array definierst mit x Elementen und anderswo in das x-te oder x+1 te Element speicherst.
Grüße Uwe

Jeix, ich habe den möglichen Fehler gefunden:

mein switch/case in der Funktion change_source() hatte keinen Inhalt für den "default-case".

Nachdem ich dort etwas eingetragen hatte, kann ich nun alle nicht benötigten serial.print entfernen und es funktioniert (vorerst) wie gewünscht.

Für mich als Anfänger ist das sehr verwirrend...

Also ein switch "MUSS" keinen default Zweig haben, es sei denn du musst da etwas wichtiges
erledigen. Ansonsten kann das Fehlen keinen Fehler erzeugen.
Wenn du also im Default nichts wichtiges vergessen hast, gilt das Gleiche wie schon bei
den println's. Da wird ein Speicherfehler nur "maskierst" aber der ist nicht gefunden.
Das ist keine sichere Software -> sie läuft nur aus "Zufall".

Also -> weitersuchen. Sonst fliegt dir das gerade wenn es wichtig ist um die Ohren.

Ulli

Ok. habe weitergesucht. (und den "gelöst"-Tag aus dem Titel wieder entfernt :wink: )

Könnte das "Problem" daran gelegen haben, dass die Variable

PushButtonPressed

für die InterrupServiceRoutine (ISR_doEncoderPush()) als byte und nicht als volatile byte deklariert wurde?

Nachdem ich dies nämlich getan habe, funktioniert der Code, obwohl ich keine Serial.prints und auch keinen default-Zweig meiner switch-case-Anweisung drin habe.

MfG
Mathias

Glaube ich auch nicht wirklich.
Volatile sagt dem Compiler nur das die Variable "Flüchtig" ist.
Im nicht Interruptcode sieht der Compiler nämlich nur eine Variable die nie gesetzt wird.
Wenn die nie gesetzt wird denkt sich mancher Compiler dann kann ich auch die Benutzung wegoptimieren.
Mit volatile verhindert man diese - in diesem Fall - falsche Optimierung.
Hast du die Variable im println oder im default-Zweig angefasst ?
Dann könnte es durchaus die Lösung sein. Das prinln hat dann verhindert das der Compiler sie wegoptimiert !

Ulli

Nein, ich habe die Variable PushButtonPressed nicht im Serial.println() drin gehabt, und auch sonst ausserhalb der ISR nicht verändert.

Gesetzt wird sie in der ISR und dann halt an mehreren Stellen abgefragt...

Die Variable, die in den Serial.println abgefragt und ausgegeben wurde war

encoderPos.

Diese war bereits als volatile signed int deklariert und wird von einer anderen ISR gesetzt...

Allerdings setzte ich die Variable im Programmcode an mehreren Stellen in meiner Funktion change_source() händisch auf 0, quasi ein reset...

Unter Anderem passiert das in der besagten switch-case-Anweisung

Hmm...könnte DAS vielleicht ein Problem sein?

Gesetzt wird sie in der ISR und dann halt an mehreren Stellen abgefragt...

Dann hast du sie mit Fug und Recht als Volatile deklariert!
Und wer das kritisiert, schreibt Unfug und hat unrecht. 8) 8)

Auch sollte sie Atomar ausgewertet werden, wenn sie aus mehren Bytes besteht.