Analog Out

Sechs der digitalen Kanäle auf dem Arduino-Boards sind nicht nur digital, sondern auch analog ansteuerbar. Sie sind mit dem Aufdruck PWM gekennzeichnet (Kanal 3, 5, 6, 9, 10, 11).

PWM (Pulse Width Modulation) bedeutet, dass kein konstantes Signal an dem Kanal anliegt, sondern dass dieser Kanal kontinuierlich an- und abgeschalten wird. In der Arduino-Software übergibt man einen Wert zwischen 0 und 255 an den Kanal. 0 entspricht dem GND (Minus-Pol), 255 entspricht 5V+, Zwischenwerte bedeuten für träge Bauteile (LEDs, Motoren, etc.) also eine Spannung zwischen 0 und 5V. Damit kann man also die Geschwindigkeit von Motoren oder die Helligkeit einer LED regulieren.

(Motoren sollten nicht direkt an einen Arduino-Kanal angeschlossen werden. Mehr dazu im Abschnitt Motorsteuerung.)

Das Arduino-Beispiel Fading (File>Examples>Analog>Fading) zeigt, wie man eine LED dimmt. Hier der Code von David A. Mellis:

Im Gegensatz zur digitalen Ausgabe, muss ein analog angesprochener Kanal nicht im Setup deklariert werden. Der Befehl analogWrite erhält als Parameter den Pin, an dem die LED angeschlossen ist und den Wert (0 – 255), wie hell die LED leuchten soll.

16 Comments

  1. Atalanttore

    Was bedeuten <= und += in der Bedingung
    for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5)
    ???

  2. GoTo

    Das Bedeutet quasi: Solange fadeValue kleiner oder geich 255 ist (<=), setze fadeValue auf seinen eigenen Wert + 5 (+=5)…

    Er geht also die Schleife in 5er Schritten bis 255 durch.

  3. Atalanttore

    Danke für die Erklärung.

    Das int fadeValue = 0 in der Schleifenbedingung wird nur beim ersten Durchgang der Schleife durchlaufen oder irre ich mich da? Ein anderes Verhalten würde aus der Schleife ja eigentlich eine Dauerschleife machen.

  4. Chris

    Also alles, was ins Void Setup gehört schreibt man vor..

    „void setup() {

    }“

    Alles was permanent „bearbeitet“ werden soll schreibt man nach..

    void loop() {

    ?

  5. Marco

    @Atalanttore.

    Für eine for Schleife oder auch Zählschleife gilt
    for (initalisierung; abbruchbedingung; anweisung) {
    inhalt
    }

    * Beim eintritt in die schleife wird die „initialisierung“ durchgeführt.
    * Für jeden durchlauf wird die „abbruchbedingung“ geprüft und entweder abgebrochen (false) oder der inhalt (true) ausgeführt
    * Nach Durchführung von „inhalt“ wird „anweisung“ ausgeführt.

    Würde man die for schleife aus dem Beispiel als while schleife implementieren würde diese z.B. so aussehen:

    int fadeValue = 0;
    while (fadeValue <= 255) {
    analogWrite(ledPin, fadeValue);
    delay(30);
    fadeValue +=5
    }

  6. Nick

    vorab super Tutorial-Page!

    spiele auch gerade mit einem Arduino 2560, und möchte eine PWM erzeugen welche meine Vollbrücke steuert. Brauch ein inventiertes Signal von analogWrite(FET_HS_L, 125);
    hab mir gedacht das folgend zu erstellen,
    analogWrite(FET_HS_L, 125);
    analogWrite(FET_LS_L, -125);
    jedoch ist das Signal gleich dem anderem.
    jemand eine Idee?

  7. @Nick: Da mach dir keine Sorgen. Das ist einfach: Strom fließt ja von + zu –

    Motor links rum:
    analogWrite(pin1,0) ist GND
    analogWrite(pin2,255) ist 5V+

    Motor rechts rum:
    analogWrite(pin1,255) ist 5V+
    analogWrite(pin2,0) ist GND

    Liebe Grüße

    Stefan“

  8. Nick

    Danke für die schnelle Rückmeldung.
    Soweit ist das Verständlich, jedoch möchte ich ein Kanal Phasenverschoben steuern damit sich bei der PWM, die ungewünschte Induktivität meines Motors nicht die Freilaufdiode zerstört, dies wollte ich gerne per Software sicherstellen…

    Ist es den prinzipiell mögliche mittels analogWrite-Befehl ein Signal Phasenverschoben zu generieren? Oder wird hier nur die Modulationsbreite bestimmt?

  9. Hi Nick,

    wow. Was hast du vor. Die Diode ist doch genau dafür da. Wenn die zu klein ist, kannst du selbst noch Freilaufdioden verschalten.

    Ansonsten kann man analogWrite nicht phasenverschieben, soviel ich weiß, aber du kannst die Phasen mit digitalWrite selbst pulsen. Es gibt einen delayMicroseconds Befehl. Das sollte exakt genug sein.

    Liebe Grüße

    Stefan“

  10. Nick

    Hallo Stefan,

    zusätzliche Dioden sind vorerst keine Lösung :-)

    das delay ist eine tolle und elegante Idee, jedoch wird mein Signal doch nur verzögert ausgegeben, die Phasen werden letztendlich dennoch gleich sein. Oder verwechsele ich hier was?

    bsp.

    analogWrite(FET_HS_R, 125);
    delay (—);
    analogWrite(FET_LS_R, 125);

    Gruß,
    Nick

  11. Nick

    digitalWrite(FET_LS_R, LOW);
    delay (1);
    digitalWrite(FET_HS_R, HIGH);
    delay (5);
    digitalWrite(FET_HS_R, LOW);
    delay (1);
    digitalWrite(FET_LS_R, HIGH);
    delay (5);
    break;

    ein Lösungsansatz für alle die dasselbe Problem besitzen, jedoch kleine Frequenz..

    Nochmals besten Dank!

  12. Doce

    Der Vollständigkeit halber: LED sind eigentlich keine „trägen“ Bauteile im ursprünglichen Sinne des Wortes – träge ist vielmehr das Auge, das das PWM-Flackern ab einer bestimmten Frequenz einfach nicht mehr wahrnimmt

  13. Chris

    Eine grundsätzliche Frage eines Einsteigers an der Stelle: Die Pins, die (so wie ich das verstanden habe) grundsätzlich PWM könnten, sind demnach universell? Wenn ich also die Einsteiger-Beispiele (z. B. das einfache BLINK) abwandle, brauche ich dann keine Rücksicht auf diese Beschriftung zu nehmen? Sprich – eine LED kann ich mit den gleichen Befehlen genausogut über Pin 5 wie über Pin 8 ansteuern?

  14. 我研究出來囉~~其實也沒啥研究拉…就是照Cooper的方式實作XD分享在這下面是Arduino端的程式其實也就是接收電腦端從com port傳來的數字訊號,然後在判讀訊號發射相對應的紅外線:))至於C#那邊的程式太多拉…貼這會報掉XDD#include // 引用 IRRemote 函式庫IRsend irsend; // 定義 IRsend 物件來發射紅外線訊號int iinnmcogByte = 0; // 用來儲存收進來的 data bytevoid setup() { // 開啟 Serial port, 通訊速率為 9600 bps Serial.begin(9600);}void loop() { // 檢查是否有資料可供讀取 if (Serial.available() > 0) { // 讀取一個 byte iinnmcogByte = Serial.read(); // 決定打開或關掉 LED if (incomingByte == ‚1‘) irsend.sendNEC(0xFB30CF, 32); //前進 else if(incomingByte == ‚2‘) irsend.sendNEC(0xFBF20D, 32); //後退 else if(incomingByte == ‚3‘) irsend.sendNEC(0xFB9867, 32);//左轉 else if(incomingByte == ‚4‘) irsend.sendNEC(0xFB32CD, 32); //右轉 else irsend.sendNEC(0xFBA05F, 32); //停止 }}

  15. Maik

    Zu beachten ist dass der Wert 255 einer Pulsdauer von 2ms entspricht.
    Somit ist der Ausgang bei dem Wert 127 für eine 1ms auf +5V und dann wieder für 1ms auf 0V. Und beim Wert 63 für eine 0,5ms auf +5V und dann wieder für 1,5ms auf 0V.

  16. Maik

    Die Frequenz beträgt also 500Hz und ist somit für das Auge nicht wahrnehmbar.
    Für eine Oszilloskop aber schon. ;-)

Schreibe einen Kommentar

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