LED Millis Frage

  • Vielleicht noch ergänzend:


    Switch und Case gehören untrennbar zusammen. Wenn Du nur „case 1:“ schreibst kann es sein, dass der Compiler das nicht anmeckert, allerdings erzeugst Du dann eine Sprungmarke für den „goto“ Befehl. Das ist etwas völlig anderes.


    Eine gute Beschreibung zur „switch/case“ Konstruktion findet sich hier.


    Damit der von René gezeigte Code funktioniert, muss die Variable „zustand“ natürlich deklariert und mit einem Wert initialisiert werden. Das wurde mit „int zustand=1“ erledigt.


    Hätte er das nicht geschrieben, würde der Compiler meckern, dass die Variable „ zustand“ nicht existiert. Hätte er nur „int zustand“ geschrieben, wäre der Wert von „zustand“ rein zufällig, irgendetwas zwischen 0 und 65535 und somit nicht klar definiert. Des Ergebnis der nachfolgenden Operation nicht vorhersagbar.


    Gruß Kai

  • Hallo Nicole,


    nur der Vollständigkeit halber. Der Code ist nur ein Beispiel, das hilft die Sache zu erklären. Zu kleine Codeschnipsel sagen oft nicht viel aus. Bei Erklärungen ist es aber immer wichtig, dass alle wesentlichen Elemente vorhanden sind. Die einfachste Art eine Variable einzuführen ist die Deklaration mit Wertzuweisung. In einem realen Programm kommt die Selektionsvariable normalerweise irgendwo aus den Tiefen des Programms.


    Gruss

    René

  • Hallo René,


    vielen Dank für die Erklärung.


    Das hat bestens funktioniert.

    Jetzt musst Du mir bitte nur noch sagen warum Du es so geschrieben hast ?


    Code
    1. int zustand = 1;
    2. switch (zustand) {

    Ich hatte es ja so geschrieben:

    Code
    1. case 1:
    2. eins();

    Weshalb schreibst Du noch das int zustand mit dazu ?

    Welchen Vorteil hat das ?


    Vielen Dank

    Nicole

  • Hallo Nicole,


    case ist ein etwas spezielles Konstrukt, das immer wieder zu Fehlern Anlass gibt. Da du keinen vollständigen Code gepostet hast, kann ich nicht sagen, ob du in die Falle getappt bist.


    Ein Beispiel:

    Code
    1. int zustand = 1;
    2. switch (zustand) {
    3.     case 1: eins();
    4.     case 2: zwei();
    5. }

    Das Resultat wird hier vielleicht nicht den Erwartungen entsprechen. Es wird nämlich eins() und zwei() ausgeführt, obwohl offensichtlich nur die erste case - Bedingung erfüllt ist. Das liegt daran, dass die Befehle, die nach dem übereinstimmenden case ausgeführt werden, nicht beim ; oder dem nächsten case stoppen. Es werden einfach alle nachkommenden Befehle ausgeführt.


    Um die Befehlsausführung zu stoppen, brauchst du noch das Schlüsselwort break. Bei diesem stoppt dann die Ausführung und der switch .. case - Block wird verlassen.


    Code
    1. int zustand = 1;
    2. switch (zustand) {
    3. case 1: eins();
    4.             break;
    5. case 2: zwei();
    6.             break;
    7. }

    Das zweite break könnte auch weggelassen werden, da der Befehl dann sowieso beendet ist.


    Gruss

    René

  • Hallo Kai,


    danke für die Tips.


    Es gibt ja einen Grund warum ich das so gemacht habe ;)

    Wenn ich beides so wie Du es sagst in den loop einfüge funktioniert das ganze wie schon gesagt ohne Probleme.

    Ich möchte aber nicht, das die LED andauernd blinken.


    Aktuell versuche ich mich mit case.

    Und die beiden LED möchte ich nutzen damit ich sehe in welchem Case ich aktuell bin.

    Somit sehe ich sofort den Unterschied und weis ob das Umschalten funktioniert hat.


    case 1 = led 1

    case 2 = led 2


    Quasi so:

    Code
    1. case 1:
    2. eins();


    Was mir aber bei meinen Test aufgefallen ist, wenn ich per Taster die case Wechsel fängt die LED dauerhaft an zu leuchten.

    Die LED leuchtet nicht im Eingestellten Takt sondern Sie leuchtet dauerhaft.


    Was mache ich hier falsch ?

    Muss ich in des jeweilige case noch etwas anderes hinzufügen ?

    Normal sollte das case sich die richtigen Informationen ja aus der Funktion eins(); holen.

    Oder läuft das bei einem case wieder etwas anders ab ?


    Irgend wie läuft der Zeitablauf falsch ab.

  • Naja Nicole,


    ich würde das, was ich Dir eben geholfen habe zu "fixen", nicht machen. Kaskadiere nicht die Funktionsaufrufe, wenn es keinen zwingenden Grund dafür gibt.

    Bei so ein paar Zeilen Code macht das nichts, aber wenn es mal viel Code wird, wird das unübersichtlich und kann die Fehlersuche sehr beeinträchtigen.


    Schreibe beide Funktionsaufrufe in die "loop()"


    Code
    1. void loop() {
    2. currentMillis = millis();
    3. eins();
    4. zwei();
    5. }


    Da ist der Programmablauf klar und sofort ersichtlich. In deinem Beispiel ist das nicht mehr der Fall, weil die Aufrufe verschachtelt werden.


    Des Weiteren fällt auf, dass die Funktionen "eins()" und "zwei()" nahezu identisch sind. In diesem kleinen Beispiel macht das sogar Sinn, weil es einfach und klar verständlich ist. Ansonsten sollte aber eher versucht werden, nahezu identische Funktionen zu einer Funktion zusammen zu fassen und mit Übergabeparametern zu arbeiten.


    Gruß Kai

  • Hallo Kai,


    vielen Dank für deine genaue Erklärung und deine Hilfe.


    Du hast Recht, jetzt funktioniert es wie es sein soll :)

    Vielen Dank !


    Gibt es sonst noch etwas was ich an meinem Code verbessern könnte ?

  • Das liegt wahrscheinlich daran, dass du "zwei()" IN der IF-Bedingung von eins() aufrufst und somit die Funktion "zwei()" nur alle 500ms aufgerufen wird. Aus dem Grund kann die LED nicht im 100ms Intervall blinken. Weil beim Aufruf nach 500 ms die Bedingung in der Funktion "zwei()" auch zutrifft, blinkt sie nahezu synchron mit Eins. Anders herum klappt es halt, weil das Zeitintervall "Zeit1 (100ms)" kürzer ist als "Zeit (500ms)". In deinem geposteten Quellcode wird "eins()" fünf mal aufgerufen (alle 100ms) ... darum blinkt es in dem Fall asynchron, so wie Du es erwartest.


    Nimm also die Aufrufe der Funktionen aus der Klammer der IF-Bedingung raus.




    Gruß Kai

  • Hallo zusammen,


    ich bin ganz neu hier im Forum und hätte da auch gleich mal eine Frage an Euch :)


    Bin gerade dabei mit den Millis etwas zu spielen.

    Es funktioniert soweit schon recht gut, nur ab und an gibt es ein Problem das ich nicht ganz verstehe.


    Ich habe in meinem Code 2 LED die unterschiedlich blinken sollen.

    Das machen Sie auch wenn ich beide Funktionen einzeln in den Loop aufrufe.


    Aber was nicht funktioniert ist, wenn ich die Funktion zwei(); zusammen mit der Funktion eins(); aufrufe.

    Weshalb blinken die beiden LED dann im gleichen Takt ?


    Wenn ich die Funktion zwei zusammen mit der Funktion eins(); aufrufe blinken beide LED im richtigen Takt.

    Warum geht es anders rum nicht ?


    Hier mal mein Code wie es richtig funktioniert.



    Es wäre sehr nett, wenn Ihr mir bitte sagen könnt welchen Fehler ich genau mache ?


    Vielen Dank für Eure Mühe.


    Nicole