Anzeige

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, leuchtstärke);

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 bis 255. Damit können wir die Leuchtstärke der LED in 256 Stufen beeinflussen.

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 solange 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);
  }

}

Stefan Hermann

Ich bin Stefan und arbeite seit 2007 mit Arduino. Als Designer und Produktmanager setze ich das Board in erster Linie zum Bau von Prototypen ein. Hier teile ich meine Faszination und Erfahrung mit dir!

20 thoughts on “Lektion 13 – LEDs dimmen mit der analogen Ausgabe

  1. 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

  2. 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

  3. 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 }

  4. 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

  5. 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.