Zum Inhalt springen
Arduino LED Fading PWM

Lektion 13 – LEDs dimmen mit der analogen Ausgabe

    Du kannst LEDs jetzt schon ein- und ausschalten. Nun wollen wir versuchen, ob wir sie auch dimmen, also weniger stark leuchten lassen können.

    Dein Zimmerlichtschalter kann das Licht ein- und ausschalten. Alles, was genau zwei Zustände kennt, nennt Arduino digital. Du hast das mit den Befehlen digitalWrite() und digitalRead() schon kennengelernt. An manchen Lampen hat man aber auch ein Drehrädchen oder einen Schieber, mit dem man die Lampe dimmen kann. Die Leuchtstärke kennt dann nicht nur An und Aus, sondern auch Zustände dazwischen. Das nennt Arduino analog.

    Um eine LED zu dimmen, können wir den Befehl analogWrite() benutzen.

    analogWrite(ledPin, leuchtstaerke);

    Auch hier übergeben wir zwei Parameter. Der erste Parameter ist wie bei digitalWrite() die Pinnummer. Der zweite Parameter ist nun nicht HIGH oder LOW, sondern ein Wert zwischen 0 und 255. Damit können wir die Leuchtstärke der LED in 256 Stufen beeinflussen.


    Sieh dir jetzt meinen neuen Arduino-Videokurs an: Jetzt ansehen!


    Benötigte Teile

    Bauteile

    Schaltung

    Bauplen Analoge Ausgabe

    Die Schaltung kennst du ja schon. Es handelt sich um eine LED, die über einen Vorwiderstand mit dem Minus-Pol (GND) und direkt mit dem Pin 9 verbunden ist.

    So könnte ein Programmtext zum Testen aussehen:

    int ledPin = 9;
    
    void setup(){
    
    }
    
    void loop(){
      analogWrite(ledPin, 200);
    }

    Ist dir aufgefallen, dass im Setup gar nichts steht? Wenn wir die analoge Ausgabe verwenden, müssen wir – im Gegensatz zur digitalen Ausgabe – keine Grundeinstellungen im Arduino vornehmen.
    Probier jetzt einfach ein paar andere Werte anstelle der 200 aus (z.B. 50, 250, 0, 100) und sieh, was passiert.

    Info: PWM

    Um LEDs zu dimmen, benutzt Arduino einen Trick. Normalerweise müsste man dafür nämlich die Spannung reduzieren. Arduino kann das nicht. Es ist nur in der Lage, Pins an- und auszuschalten. Das kann es dafür aber sehr schnell. Das Verhältnis der Zeit zwischen An und Aus entscheidet darüber, wie hell die LED leuchtet. Wenn sie lange an und nur kurz ausgeschaltet wird, dann leuchtet sie heller, als wenn sie lange aus und nur kurz angeschaltet wird. Dieses Verfahren wird Pulsweitenmodulation (PWM) genannt. Arduino kann die Pulsweitenmodulation aber nicht an jedem Pin ausführen, sondern nur an denen, die mit einer Wellenlinie gekennzeichnet sind. Das sind die Pins 3, 5, 6, 9, 10 und 11.

    Dimmen mit der for-Schleife

    Im Kapitel 10 haben wir uns die for-Schleife angesehen. Lass uns diese jetzt benutzen, um die LED automatisch zu dimmen. Bei der for-Schleife können wir eine Variable pro Schleifendurchlauf verändern. Ich schlage vor, wir benutzen sie für die Helligkeit der LED. Die Variable soll bei 0 anfangen und bis 255 zählen. Das sieht dann so aus:

    for (int helligkeit=0; helligkeit <=255; helligkeit = helligkeit +1){
    
    }

    Wenn man nicht so viel schreiben möchte, kann man statt

    helligkeit = helligkeit + 1

    auch

    helligkeit++

    schreiben. Das erhöht die Variable auch um 1. Der Klarheit halber bleiben wir aber bei der ausgeschriebenen Variante. Der Code könnte dann so aussehen:

    int ledPin = 9;
    
    void setup(){
    
    }
    
    void loop(){
      for (int helligkeit =1; helligkeit <= 255; helligkeit = helligkeit +1){
        analogWrite(ledPin, helligkeit);
        delay(20);
      }
    }

    Ein kleines delay ist nötig, damit wir die Änderung wahrnehmen können. Lade das Programm nun auf das Arduino.

    Jetzt dimmt sich die LED langsam an. Was müssen wir jetzt machen, wenn sie sich danach wieder ausdimmen soll? Wir müssen eine zweite for-Schleife schreiben, bei der die Variable “helligkeit” bei 255 anfängt und sich pro Durchlauf um 1 reduziert. Das soll so lange durchgeführt werden, wie Helligkeit größer 0 ist.

    Probier es einmal selber zu schreiben. Ansonsten findest du hier die Lösung:

    int ledPin = 9;
    
    void setup(){
    
    }
    
    void loop(){
      for (int helligkeit =1; helligkeit <= 255; helligkeit = helligkeit +1){
        analogWrite(ledPin, helligkeit);
        delay(20);
      }
      for (int helligkeit =255; helligkeit >= 0; helligkeit = helligkeit -1){
        analogWrite(ledPin, helligkeit);
        delay(20);
      }
    }

    33 Gedanken zu „Lektion 13 – LEDs dimmen mit der analogen Ausgabe“

    1. Wenn ich dieses einfache Programm mit meinem Ardurio ESP32 sterten will:

      int ledPin = 9;
      void setup(){
      }
      void loop(){
      analogWrite(ledPin, 200);
      }

      kommt immer die Fehlermeldung: ‘analogWrite’ was not declared in this scope

      Was mache ich falsch?
      Vielen Dank.

      1. Hi Volker,

        der Code sieht gut aus. Welches ESP32-Board nutzt du denn? Ist der Pin D9 denn ausgeführt und ein PWM? Ansonsten versuche mal einen anderen Pin.

        Liebe Grüße Stefan

    2. Hallo, erstmal Danke für die ausführliche Erklärung.
      Wie funktioniert das ganze wenn man einen LDR mit in die Schalten packt, also dass je mehr Licht auf den Sensor trifft, die LED dunkler wird und umgekehrt.
      Vielen Dank schonmal im Voraus.

    3. Hallo und vielen Dank für die ausführliche Erklärung!
      Beim Dimmen mit der for-Schleife schaltet sich meine LED allerdings bei PWM-Werten von 128-255 ganz an und von 0-127 komplett aus. Ich habe mir die Werte über die Serial.print() Funktion ausgeben lassen und sie steigen/fallen wie erwartet in 1er Schritten an/ab.

      1. Hallo Alexander,

        das liegt daran, dass diese LED an ihrem aktuellen pin nur digital (also “ganz aus” oder “ganz an”) angesteuert werden kann.

        VG

        Achim

    4. Hallo und vielen Dank für die ausführliche Erklärung!
      Beim Dimmen mit der for-Schleife schaltet sich meine LED allerdings bei PWM-Werten von 128-255 ganz an und von 0-127 komplett aus. Ich habe mir die Werte über die Serial.print() Funktion ausgeben lassen und sie steigen/fallen wie erwartet in 1er Schritten an/ab.

    5. Hallo,
      wie kann man dem Arduino mitteilen, dass die LED erst nach Tastendruck sich langsam aufdimmt und bei erreichten 255 dass er diesen Wert beibehält. Ein anderer Taster soll diesen wieder langsam abdimmen und bei 0 bleiben bis der erste Taster wieder gedrückt wird. Haben Sie eine Idee und könnten mir helfen?
      LG

      1. Hi Tom, vielen Dank für die Frage. Das hier ist eine mögliche Lösung:

        int ledPin = 10;                        // muss PWM Pin sein
        int buttonPin = 8;                      // hier ist der Taster angeschlossen
        
        int myDirection = -1;                   // die Richtung, in die die LED gedimmt werden soll, <0 = ausdimmen, >0 andimmen
        bool lastButtonState = false;           // der Zustand des Buttons beim letzten Schleifendurchlauf
        int brightness = 0;                     // anfängliche Helligkeit
        int delayTime = 10;                     // steuert die Geschwindigkeit des Dimmens, je höher, desto langsamer
        
        void setup() {
          pinMode(buttonPin, INPUT_PULLUP);     // der Taster wird mit internem Pullup verwendet, d.h. er ist mit dem GND und dem digitalen Input verbunden
          Serial.begin(112500); 
        }
        
        void loop() {
          bool myCurrentButtonState = digitalRead(buttonPin);                           // liest den aktuellen Zustand des Tasters aus
          if ((lastButtonState!=myCurrentButtonState)&&(myCurrentButtonState==LOW)){    // wenn dieser HIGH ist, aber beim letzten Durchlauf nicht
            myDirection = myDirection * (-1);                                           // ändere Dimm-Richtung                          
            Serial.println("change");
          }
          brightness = brightness + myDirection;                                        // zähle den Wert je nach dem hoch oder runter
          if (brightness>255) brightness=255;                                           // obere Grenze des Dimmens = 255
          else if (brightness<0) brightness = 0;                                        // untere Grenze des Dimmens = 0
          
          analogWrite(ledPin, brightness);                                              // sende den Leuchtwert an die LED
          
          lastButtonState=myCurrentButtonState;                                         // merke dir den aktuellen Tasterzustand für den nächsten Durchlauf
          delay(delayTime);
        }
        

        Ist das nur eine Übung, oder hast du ein konkretes Projekt im Kopf? Vielleicht kann ich daraus ein Projekt für diese Seite machen.

        Liebe Grüße

        Stefan

        1. Hallo Stefan,
          habe deinen Beitrag gelesen, finde sehr hilfreich. Auch ich bin ein Anfänger in Sachen Arduino-Programmierung.
          Ich möchte auch gerne meine Idee realisieren, weiß ich aber nicht, ob diesen Code dafür verwenden kann. Ich arbeite mit einem Arduion UNO.
          Ich möchte zB: eine Led stufenlos auf und abdimmen, indem ich eine Taste drücke zum Aufhellen und eine zweite taste zum Abdunkeln. Die Tasten sollen aber solange gedrückt gehalten werden, bis max. Helligkeit bzw. Abdunkeln erreicht werden.
          Die max. Zeit zum Aufhellen und Abdunkeln könnte zB. jeweils 5sek. betragen. Das bedeutet dann nach 2,5sek. hat die Led 50% ihrer Helligkeit erreicht und wenn ich die Taste weitere 2,5 sek. drücke, erreiche ich nach insgesamt 5sek. die max. Helligkeit. und umgekehrt natürlich auch.

          Ich wäre dir sehr dankbar, wenn du mir bei meinem Projekt auch helfen könntest.
          Beste Grüße, Adil

    6. Hallo Stefan,

      Ich bin heute den ersten Tag mit dem Arduino am Start und finde Deine angebotenen Lösungen echt klasse.

      Ich hab folgende Herausforderung:

      Eine LED soll pulsieren (also an- und ausfaden) und vor dem nächsten Durchgang 5 Sekunden pausieren.
      Gleichzeitig sollen 2 andere Ausgänge blinkende LEDs erzeugen.

      Für einen Lösungsansatz (oder einen Sketch) wär ich sehr dankbar.

      Viele Grüße
      Falk

      1. Hallo Falk,

        interessante Frage. Ich werde mal gucken, ob ich die nächsten Tage was dazu schreiben kann. Willst du das nur als Übung, oder ist das ein Projekt, was irgendwas macht? Was wäre das? Ich schreibe gern Tutorials zu Projekten :-)

        Bis dahin wäre mein Tipp aber, Timer zu verwenden, denn im Grunde musst du von den Delays weg. Dazu habe ich hier mal was geschrieben: https://starthardware.org/timer-mit-arduino-alternative-zu-delays/ Das bekommst du bestimmt hin.

        Bleib gesund und liebe Grüße

        Stefan

        1. Ich hätte da ein konkretes Projekt im Kopf. ;)
          Möchte mit einem ESP 8266 über einen TOF Sensor LEDs (Streifen) steuern. Wenn jemand eine gewisse Zeit lang (zb 10secs) in einem gewissen Abstand (zb 20-50cm) vor dem Sensor steht, sollen die LEDs gedimmt angehen und anbleiben. Danach wieder gedimmt ausgehen. Die Einzelteile anzusteuern (TOF distanz auslesen, leds dimmen..) hat geklappt, alles zu einem funktionierenden Code zusammenzuführen… nicht. Freue mich über jeden Input :D

        1. Hi Stefan,

          absolut großartig! Ich hab mit meinen „2 Tage Arduino Kenntnissen“ auch eine Lösung gebastelt, welche, so leidlich, funktioniert.

          Aber verglichen mit Deiner Lösung ist das Kreisklasse vs. Champions League.
          Funktioniert absolut top und macht genau, was es soll.

          Jetzt werde ich Deinen Sketch nutzen, um weiter praxisorientiert zu lernen.
          Also, nochmals vielen Dank und macht mit Eurer Seite so weiter,
          Daumen hoch.

          Viele Grüße und
          bleib gesund
          Falk

          1. Hi Falk, schön, dass es dir gefällt. Es ist am Ende egal, wie man sein Ziel erreicht. Ich mach das zwar schon länger, aber ich bin mir sicher, dass es noch wesentlich elegantere Ansätze gibt. Davon darf man sich nicht zurück halten lassen. Wenn du also auf eine Lösung kommst, die für dich funktioniert ist das perfekt. Ich drück dir auf jeden Fall die Daumen und bleib am Ball. Wenn es läuft, würde ich mich über ein Foto deiner Anlage – besonders von den Tonnen – freuen. :-) Liebe Grüße Stefan

    7. Hallo kann ich die for schleife auch in eine methode packen habs versucht aber krieg es nicht hin will eine led dimmen und in eine methode packen
      MfG. Tom

      1. Hallo Tom, interessante Frage. Probier das mal:

        int ledPin = 9; // Pin der LED (muss PWM-Pin sein, also Pin 3,5,6,9,10 oder 11)
        int helligkeit = 0; // speichert die Helligkeit zwischen

        void setup(){
        // nichts zu tun hier
        }

        void dimmen(int richtung){ // Methode dimmen, erwartet richtung als Parameter (-1 oder 1)
        helligkeit = helligkeit + richtung; // addiere richtung zu helligkeit (das zählt je nachdem hoch oder runter)
        if (helligkeit>255) { // wenn oberes Ende erreicht
        helligkeit = 255; // stoppe weiteres Hochzählen
        richtung = richtung * (-1); // ändere die Dimm-Richtung
        }
        if (helligkeit<0) { // stoppe, wenn unteres Ende erreicht
        helligkeit < 0; // stoppe weiteres Runterzählen richtung = richtung * (-1); // ändere die Dimm-Richtung } analogWrite(ledPin, helligkeit); // übergib Helligkeit an die LED } void loop(){ if (millis()%20==0) dimmen(1); // rufe dimmen() alle 20 Millisekunden auf // also immer, wenn die aktuellen Millisekunden durch 20 einen Rest von 0 ergeben }

    8. Gute Info für Anfänger! Ich möchte eine LED für eine gewisse Zeit, ca. 10 sec., gedimmt einschalten. Danach soll sie wieder ausgehen. Wie würde der Code dann aussehen?

      1. Hallo Peter,

        ich denke, das geht so:

        ledPin = 9;

        void setup(){} // nichts zu tun hier

        void draw(){
        analogWrite(ledPin, 100); // statt der 100 kannst du Werte zwischen 0 und 255 eingeben
        delay(10000);
        analogWrite(ledPin, 0);
        delay(10000);
        }

        Ich hoffe, das hilft Dir weiter.

        Liebe Grüße

        Stefan

    9. super LED dimmen ! einfach erklärt !

      ich möchte aber das die LED nach dem hochfahren an bleibt !
      und
      nach dem runterfahren aus bleibt.

      das Programm wird ja immer neu gestartet !!!!!

    Schreibe einen Kommentar

    Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

     

    Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.