Bei digitalen Signalen gibt es nur zwei Werte: An oder Aus bzw. 1 oder 0. Manchmal benötigt man allerdings auch Werte dazwischen und mit der Pulsweitenmodulation (PWM) kann man diese Zwischenwerte abbilden, auch wenn man eigentlich nur digitale Signale zur Verfügung hat. Praktische Einsatzmöglichkeiten sind das Dimmen von LED bzw. die Geschwindigkeitssteuerung von Motoren. Auch zum Ansteuern von Servomotoren wird PWM genutzt.

Doch wie funktioniert PWM?

Bei PWM ändert sich ein Signal laufend von 1 nach 0 bzw. von 0 nach 1. Der Wechsel passiert immer:

  • in bestimmten zeitlichen Abständen (Periode / Frequenz)
  • und mit einem bestimmten zeitlichen Verhältnis zwischen der Dauer des 1-Signals und des 0-Signals (Pulsweite / Duty cycle)

Bei der LED wird der schnelle Wechsel von an und aus nicht warhrgenommen. Die LED scheint nur schwächer zu leuchten. Beim schnellen An und Aus beim Motor fährt dieser in einer gedrosselten Geschwindigkeit.

PWM beim Calliope

Nicht alle Pins des Calliope mini können ein PWM-Signal liefern. Möglich ist dies an den Pins P1, P2, C4, C5, C6, C16 und C17. Für Servos geht die Programmierung in Makecode über den Befehl:

“setze Puls von Servo an auf (µs)"

aus dem Bereich “Fortgeschritten - Pins”.

Durch diesen Befehl wird der Pin als PWM-Ausgang konfiguriert und die Peroide auf 20ms (entspricht 50 Hz) festgelegt sowie die Pulsweite festgelegt. Bei einer Pulsweite von 0 ist auch das Signal dauerhaft 0. Bei einer Pulsweite von 20.000 µs (20ms) ist das Signal dauerhaft 1. Dazwischen liegen die möglichen Zwischenwerte.

PWM-Signale mit einer anderen Periode können über “setze Zeitraum für analogen Pin auf x µs” generiert werden (noch nicht getestet).

PWM beim Raspberry Pi

Beim Rasperry Pi gibt es mehrere Varianten für PWM:

  • Software-timed PWM
  • Hardware PWM
  • Hardware(DMA)-timed PWM

Software-timed kann man der Bibliothek RPi.GPIO an allen GPIO-Pins erzeugen: https://sourceforge.net/p/raspberry-gpio-python/wiki/PWM/

Hardware PWM kann man mit der Bibliothek pigpio an den GPIO-Pins, die Hardware-PWM unterstützen (12/18 + 13/19): http://abyz.me.uk/rpi/pigpio/python.html#hardware_PWM

Hardware(DMA)-timed PWM kann mit der Bibliothek pigpio an allen GPIO-Pins erzeugen. http://abyz.me.uk/rpi/pigpio/python.html#set_PWM_dutycycle

Mit Software-timed PWM kann es bei Servos zu einem Jitter kommen. Hardware(DMA)-timed PWM funktioniert nach meiner Erfahrung auch für Servos gut.

In der Bibliothek gpiozero gibt es eine Klasse PWMOutputDevice und davon abgeleitete Klassen für PWMLED, und Servo. Diese kann man gut verwenden und bei Bedarf die PinFactory auf pigpio ändern.

PWM beim Arduino

((TODO))

PWM bei ESP32

Beim ESP32 unterstüzten alle als Ausgang geschalteten PIN PWM. Mit Micropython kann man PWM wie folgt aktivieren und konfigurieren:

import machine

pin = machine.Pin(4, machine.Pin.OUT)
pwm_pin = machine.PWM(pin)

pwm_pin.freq(500) # zwischen 1 Hz und 40000000 Hz
pwm_pin.duty(512) # zwischen 0 (off) und 1023 (on)

Zunächst konfiguriert man den entsprechenden Pin als Output. Dan erzeugt man ein PWM-Objekt. Darauf kann man dann sowohl die Frequenz, als auch den Duty-Cycle konfiguirieren.

Links: https://docs.micropython.org/en/latest/esp32/quickref.html?highlight=pwm https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo/wiki/pwm