<style>[reveal]{opacity:1 !important;transform:none !important}</style>

Analogspannung aus PWM (RC-DAC)

Echte Gleichspannung aus einem PWM-Pin: Frequenz und Auflösung festlegen, zweistufigen RC-Filter auslegen und mit Rail-to-Rail-OPV puffern – für Arduino und ESP32.

7 Min. LesezeitPWM DACPWM in AnalogspannungArduino analoge Spannung ausgebenRC-Filter PWM

Der Arduino Uno hat keinen Digital-Analog-Wandler. analogWrite() liefert kein analoges Signal, sondern ein Rechteck: Der Pin springt mit 490 Hz zwischen 0 und 5 V, nur das Verhältnis von Ein- zu Ausschaltzeit ändert sich. Eine LED oder ein Motor mitteln das von selbst. Ein Labornetzteil mit Steuereingang, ein Frequenzumrichter mit 0-bis-5-V-Eingang oder ein Oszilloskop sehen dagegen das Rechteck. Mit einem Tiefpass und einem Puffer wird daraus eine saubere Gleichspannung, ein einfacher DA-Wandler.

Wie ein einzelnes RC-Glied eine PWM glättet und warum dabei Welligkeit und Geschwindigkeit gegeneinander stehen, zeigt der RC-Tiefpass. Hier gehst du den nächsten Schritt: höhere PWM-Frequenz, zweistufiger Filter und ein Ausgang, der belastbar ist und die vollen 0 bis 5 V erreicht.

Schaltplan

PWM-DAC: PB1 (D9, Pin 15) des ATmega328P über R1 10 kΩ, C1 10 nF nach Masse, R2 100 kΩ, C2 1 nF nach Masse an den Plus-Eingang (Pin 3) eines MCP6002, der als Spannungsfolger geschaltet ist; Ausgang Pin 1 liefert Ua von 0 bis 5 V
Zwei RC-Stufen glätten die 62,5-kHz-PWM, der Operationsverstärker puffert das Ergebnis.
  • IC1, ATmega328P: erzeugt an D9 (Pin 15) eine PWM mit 62,5 kHz und 8 Bit Auflösung.
  • R1, C1 (10 kΩ, 10 nF): erste Filterstufe, Grenzfrequenz 1,6 kHz.
  • R2, C2 (100 kΩ, 1 nF): zweite Stufe mit derselben Grenzfrequenz. R2 ist zehnmal größer als R1, damit die zweite Stufe die erste kaum belastet.
  • IC2A, MCP6002: ein Operationsverstärker mit Rail-to-Rail-Ein- und -Ausgang, geschaltet als Spannungsfolger. Er trennt den Filter von der Last.

So funktioniert die Schaltung

Ein PWM-Signal ist die Summe aus einem Gleichanteil und vielen Wechselanteilen. Der Gleichanteil ist der Mittelwert:

Ua = D · UCC

mit dem Tastgrad D zwischen 0 und 1. Alle Wechselanteile liegen bei der PWM-Frequenz und ihren Vielfachen. Ein Tiefpass, dessen Grenzfrequenz weit darunter liegt, lässt den Gleichanteil durch und dämpft den Rest.

Zwei Stellschrauben machen den Unterschied zum einfachen RC-Glied:

Höhere PWM-Frequenz. Die Standard-PWM des Uno mit 490 Hz liegt so tief, dass ein Filter erster Ordnung sehr langsam werden muss, um sie zu glätten. Timer 1 kann ohne Vorteiler laufen: Mit 8 Bit Auflösung zählt er bis 256 und erreicht 16 MHz / 256 = 62,5 kHz. Das ist 128-mal schneller, und der Filter darf entsprechend schneller sein.

Zweite Ordnung. Eine RC-Stufe dämpft oberhalb der Grenzfrequenz mit 20 dB pro Dekade, zwei Stufen mit 40 dB (Bode-Diagramm). Bei gleicher Welligkeit kann die Grenzfrequenz deshalb viel höher liegen, und der Ausgang folgt einer Änderung schneller.

Der Puffer ist nötig, weil der Filter hochohmig ist. Schon 100 kΩ Last am Ausgang würden die Spannung halbieren. Der MCP6002 nimmt am Eingang praktisch keinen Strom auf und liefert am Ausgang einige Milliampere. Ein LM358 wäre hier falsch: Sein Ausgang kommt an 5 V Versorgung nur bis etwa 3,5 V.

Dimensionierung

1. Auflösung und Frequenz. Ein Timer mit N Bit erzeugt bei fCPU höchstens fPWM = fCPU / 2N. Mehr Bits bedeuten feinere Stufen, aber eine tiefere Frequenz:

BitStufenSchritt bei 5 VfPWM am Uno (16 MHz)
825619,5 mV62,5 kHz
1010244,9 mV15,6 kHz

Gewählt: 8 Bit, 62,5 kHz.

2. Ziel für die Welligkeit. Sie soll kleiner sein als ein halber Schritt: 19,5 mV / 2 ≈ 9,8 mV. Am größten ist sie bei 50 % Tastgrad.

3. Einstufig zum Vergleich. Mit der Näherung aus dem Artikel zum RC-Tiefpass:

R · C ≥ UCC · D · (1 − D)fPWM · ΔU = 5 V · 0,2562,5 kHz · 9,8 mV ≈ 2,0 ms

Mit 20 kΩ und 100 nF erfüllt das ein einziges RC-Glied. Es braucht aber 12 ms, bis der Ausgang nach einem Sprung auf einen halben Schritt genau steht.

4. Zweistufig. Beide Stufen erhalten fg = 1 / (2π · 10 kΩ · 10 nF) ≈ 1,6 kHz, die zweite mit zehnfachem R und einem Zehntel C. Jede Stufe dämpft die 62,5 kHz etwa um fg / fPWM ≈ 0,025, beide zusammen um 0,0252 ≈ 0,00065. Die Grundschwingung der PWM hat bei 50 % eine Amplitude von 2 · 5 V / π ≈ 3,2 V; übrig bleiben rund 2 mV Amplitude, 4 mV Spitze-Spitze. Die Simulation bestätigt 4,0 mV und eine Einschwingzeit von 0,9 ms.

Rechner

Grenzfrequenz von RC-Tief- und Hochpass

Grenzfrequenz fg
1,59 kHz
Zeitkonstante τ
100 µs
uaus / uein
30,3 %
Dämpfung
-10,4 dB
Phase
-72,3°
R = 1 kΩC = 100 nFueinuaus|uaus / uein| in dB0−10−20−30−4010 Hz100 Hz1 kHz10 kHz100 kHzf (logarithmisch)fg = 1,59 kHz (−3 dB)5 kHz: −10,4 dB

Bei fg ist die Ausgangsspannung auf 70,7 % gesunken (−3 dB), die Phase um 45° verschoben.

Ausgangsspannung nach dem Umschalten auf 50 % Tastgrad: Der zweistufige Filter erreicht 2,5 V nach weniger als 1 ms, der einstufige mit gleicher Welligkeit braucht rund 12 ms
Zweite Ordnung: gleiche Glättung, aber mehr als zehnmal schneller am Ziel.

5. Grenzwerte prüfen.

Code

const int DAC_PIN = 9;     // OC1A

void setup() {
  pinMode(DAC_PIN, OUTPUT);
  // Timer 1: Fast PWM 8 Bit, ohne Vorteiler → 16 MHz / 256 = 62,5 kHz
  TCCR1A = _BV(COM1A1) | _BV(WGM10);
  TCCR1B = _BV(WGM12) | _BV(CS10);
}

void setzeSpannung(float u) {             // 0 … 5 V
  int stufe = round(u / 5.0 * 256.0);     // 0 … 256
  if (stufe <= 0) {                       // ganz aus: Ausgang vom Timer trennen
    TCCR1A &= ~_BV(COM1A1);
    digitalWrite(DAC_PIN, LOW);
  } else {                                // Tastgrad = (OCR1A + 1) / 256
    TCCR1A |= _BV(COM1A1);
    OCR1A = min(stufe, 256) - 1;
  }
}

void loop() {
  for (float u = 0; u <= 5.0; u += 0.5) {
    setzeSpannung(u);
    delay(500);
  }
}

Im Fast-PWM-Modus ist der Tastgrad (OCR1A + 1) / 256; selbst mit 0 bliebe ein schmaler Puls übrig. Deshalb trennt die Funktion für 0 V den Pin vom Timer. Die Frequenz ändert sich auch an D10, der Timer 1 mit D9 teilt, und die Servo-Bibliothek kannst du nicht gleichzeitig nutzen.

Bauteilliste

BezeichnerWert/TypHinweis
R110 kΩ, 1 %
R2100 kΩ, 1 %
C110 nF, C0G oder X7R
C21 nF, C0G
IC2MCP6002 (DIP-8 oder SOIC-8)Rail-to-Rail, 1,8–6 V; 100 nF an Pin 8

Varianten

ESP32. Der LED-PWM-Baustein teilt 80 MHz; mit 10 Bit erreicht er 78 kHz. Damit genügt derselbe Filter für feinere Stufen von 3,2 mV, Ausgang 0 bis 3,3 V. In Arduino ab Version 3 legst du das mit ledcAttach(25, 78000, 10); und ledcWrite(25, wert); fest. Der klassische ESP32 hat zusätzlich zwei echte 8-Bit-DACs an GPIO 25 und 26 (dacWrite), die Varianten S3 und C3 nicht.

Größere Ausgangsspannung. Soll der Ausgang 0 bis 10 V liefern, etwa für eine Steuerung, versorgst du den OPV mit 12 V und schaltest ihn als nichtinvertierenden Verstärker mit Verstärkung 2. Ein MCP6002 verträgt nur 6 V; nimm dann einen Typ für 12 V mit Rail-to-Rail-Ausgang.

Mehr Auflösung. Für 12 Bit ohne Filterprobleme gibt es fertige DAC-Bausteine wie den MCP4725 am I²C-Bus (I²C-Bus richtig beschalten).

Ohne Puffer. Geht der Ausgang nur an einen hochohmigen Eingang, etwa an einen ADC mit Kondensator oder einen Komparator, genügt der Filter allein. Die Last sollte dann mindestens hundertmal größer sein als R2.

Typische Fehler

  • Ausgang erreicht nur 3,5 V: OPV ohne Rail-to-Rail-Ausgang, etwa LM358 an 5 V.
  • Ausgang zappelt hörbar oder sichtbar: Frequenz nicht umgestellt, die PWM läuft noch mit 490 Hz.
  • Ausgang bricht unter Last ein: Puffer fehlt.
  • Spannung stimmt nicht genau: Die Versorgung ist die Referenz. Nachmessen und im Programm mit der tatsächlichen Spannung rechnen.
  • delay() und millis() gehen falsch: Timer 0 umgestellt statt Timer 1. Timer 0 gehört der Zeitmessung der Arduino-Software; für D5 und D6 deshalb Finger weg.

Selbsttest

Welche Spannung liefert der Ausgang bei OCR1A = 63?

Der Tastgrad ist (63 + 1) / 256 = 25 %, also 1,25 V.

Welche PWM-Frequenz erreicht ein 16-MHz-Timer mit 10 Bit ohne Vorteiler?

16 MHz / 1024 ≈ 15,6 kHz.

Warum ist R2 zehnmal größer als R1?

Damit die zweite Stufe die erste kaum belastet und beide Stufen ihre Grenzfrequenz behalten.

Warum genügt ein LM358 als Puffer an 5 V nicht?

Sein Ausgang kommt nur bis etwa 1,5 V unter die Versorgung; die oberen 1,5 V des Bereichs fehlen.

Um welchen Faktor dämpfen zwei RC-Stufen mit 1,6 kHz Grenzfrequenz ein Signal bei 62,5 kHz ungefähr?

Jede um etwa 0,025, zusammen um rund 0,00065, also etwa 64 dB.