Seltsames undefiniertes Verhalten (Anfänger)



  • Hallo Community!

    Ich versuche grade zum ersten Mal ein Arduino Uno zu programmieren
    und folgender Fehler ist aufgetaucht:

    Ich habe eine Wechselschaltung (if/else if) programmiert, um eine Warn-LED zu steuern. Diese ist eingebettet in eine do-while Schleife, die durch das Drücken eines von drei Buttons (Arduino Uno (Micro-Controller)) verlassen werden kann. Solange kein Button gedrückt wird, soll die Warn-LED mit einer bestimmten Frequenz (hier ca. 6hz) blinken.
    Jedes mal wenn die Variable "FreqIndex" den "Blink-Frequenzwert" (WarningLedFreq) der LED erreicht hat, wird die LED entweder eingeschaltet und zwar dann wenn sie aus gewesen ist (if), oder ausgeschaltet, wenn sie zuvor eingeschaltet gewesen ist (else if). Ist der Frequenzwert (hier 170ms) noch nicht erreicht, wird über den else-Block der Index um 5 erhöht. Ist der Wert erreicht, wird, wie beschrieben, der LED-Status umgeschaltet und vor dem nächsten Schleifendurchgang der Index wieder auf Null gesetzt. Dadurch soll das Blinken zustande kommen.
    Die Funktion selbst habe ich mit Ausgabe-Werten (Serial.print(), hier als Kommentare erkennbar) an verschiedenen Punkten getestet und es zeigt sich, dass der Code wie geplant funktioniert. (Die LedState Ausgaben sind: 0-1-0-1-0-1 etc. und entsprechen der "Blink-Frequenz") Das Problem ist: Die LED blinkt dennoch nicht so, wie sie laut Ausgaben im Serial-Monitor (wie Konsole) blinken sollte. (Die Led-Anweisung lautet, für alle die es nicht wissen, digitalWrite()).
    Für mich kurios ist außerdem, dass die LED immer dann ihren Job tut, wenn ich zuvor die Ausgabe Serial.println(FreqIndex) mit bearbeiten lasse, die hier ebenfalls als Kommentar vorhanden ist. Lasse ich die Ausgabe jedoch weg, dann leuchtet die LED entweder durchgehend, oder sie flackert. (Ich glaube, eine Hexe hat mein Arduino verzaubert!)

    FreqIndex = 0;
        LedState = 0;
        digitalWrite(StatusLedYellow, LOW);
        do {
            //Serial.println(FreqIndex);
            if (FreqIndex == WarningLedFreq) {
                //Serial.println(FreqIndex);
                if (!LedState) {
                    digitalWrite(RedCalibLed, HIGH);
                    //Serial.println(LedState);
                    LedState = 1;
                }
                else if (LedState) {
                    digitalWrite(RedCalibLed, LOW);
                    //Serial.println(LedState);
                    LedState = 0;
                }
                FreqIndex = 0;
            }
            else {
                FreqIndex += 5;
            }
        } while (!digitalRead(ProgButton) && !digitalRead(ScaleButton) && !digitalRead(CalibButton));
    


  • @Motze
    Frage: Wenn du deine serielle Funktionen auskommentierst, leuchtet deine LED dann mittel?

    Ich sehe da nämlich keine nennenswerte zeitliche Verzögerung zwischen Led an und Led aus.

    Probiere mal ein delay_ms(166) oder ähnlich nach dem setzen der Led aus.



  • Hey, vielen Dank für die schnelle Antwort, Quiche Lorraine!
    Ich habe Deine Empfehlung ausprobiert. Wenn ich alles kommentiere, also alle
    im geposteten Code als Kommentare sichtbaren print-Befehle ausführen lasse, entsteht das
    selbe seltsame Phänomen. Die LED blinkt wie gewünscht und geht alle 170ms entweder an, oder
    aus (sie brennt also immer 170ms am Stück und ist dann die selbe Zeitspanne über aus).
    Eine Veränderung des Delays bringt ebenfalls keine Lösung ein, wenn ich die Ausgaben tätige, blinkt die LED daraufhin
    ungleichmäßig, lasse ich die Ausgaben weg, blinkt sie wieder durchgehend..., obwohl sie eigentlich ungleichmäßig blinken
    müsste.



  • Deine do ... while-Schleife läuft doch ohne zu warten, d.h. die WarningLedFreq (170) sind doch in ein paar Nanosekunden erreicht.
    Baue in die Schleife ein Delay ein (durch die langsamen printf-Ausgaben hast du zwar ähnliches erreicht, aber die Zeitspanne ist nicht vorhersehbar).



  • @Motze Und überleg mal, welchen Zustand LedState in Zeile 13 hat, wenn das else angesprungen wird.

    Da reicht ein einfaches else aus.

    Statt eines delay oder sleep solltest du WarningLedFreq hoch setzen. Später gehört das Erhöhen von FreqIndex in einen Interrupt.



  • Wow, ich bin ein Trottel!!!
    Danke für die Hilfe, hat mittlerweile funktioniert...
    LG


Anmelden zum Antworten