TigerJython4Kids
HomeTurtlegrafikRobotikDatenbanken
pwm

13. PULSE WIDTH MODULATION (PWM)

 

 

DU LERNST HIER...

 

was ein PWM-Signal ist und wie du damit Servomotoren betreibst und Helligkeitssteuerungen von LED realisierst.

 

 

WAS IST EIN PWM-SIGNAL?

 

Man schaltet ein Signal repetierend während der Zeit ton ein und während der Zeit toff aus. Die Repetitionsperiode ist also T = ton + toff und das Verhältnis der Einschaltzeit zur Periode, genannt Dutyclyle: D = ton/T  . Die Frequenz des PWM-Signals ist die Anzahl Perioden pro Sekunde, also fPWM = 1/T.

PWM-Signale kannst du beim ESP32-Mikrocontroller auf allen GPIO-Pins erzeugen, die sich auch als Digital-Out konfigurieren lassen. Typische PWM-Frequenzen liegen bei 50 Hz, können aber zwischen 1 und ungefähr 1500 Hz gewählt werden.

 

 

MUSTERBEISPIELE

 


Dimmen einer LED

Versorgt man eine LED mit einem PWM-Signal, so reagiert sie sehr schnell auf die Ein- und Ausschaltvorgänge. Ist die PWM-Frequenz allerdings hoch genug, so ist für das menschliche Auge kein Flackern sichtbar, sondern die LED erscheint in Abhängigkeit vom Dutycycle verschieden hell.

Um an einem Pin ein PWM-Signal abzugeben, erzeugst du ein Objekt der Klasse PWM, wobei du die Frequenz und den Startwert des Dutycycles angibst. Nachher kannst du mit der Methode duty() den Dutycycle im Bereich 0..1023 einstellen. Bei 0 ist das Ausgangssignal abgeschaltet, bei 1023 durchgehend eingeschaltet (Dutycycle = 100%).

Schliesse eine LED am GPIO-Pin 5 über einen Vorwiderstand an, wie du es im Kapitel GPIO gemacht hast. Mit dem folgenden Programm dimmst du die LED dunkel  und schaltest sie dann wieder hell.

Programm:

from machine import PWM, Pin
from time import sleep

P_PWM = 5

servo = PWM(Pin(P_PWM), freq = 50, duty = 1023)
sleep(2)
while True:
    for duty in range(1023, -1, -1):
        servo.duty(duty)
        sleep(0.001) 
► In Zwischenablage kopieren


Ansteuern einer RGB-LED

Eine RGB-LED besteht eigentlich aus drei kleinen LEDs, die rot, grün und blau leuchten und zusammen in einem durchsichtigen Gehäuse eingebaut sind. Eine RGB-LED hat insgesamt 4 Anschlüsse: Für jede LED einen Anodenanschluss (positiv, genannt R, G, B) und einen gemeinsamen Kathodenanschluss (negativ). Durch eine Änderung der Intensität der Farbkomponenten kann die RGB-Farbe eingestellt werden.

Wie jede andere LED musst du die drei LEDs über je einen Vorwiderstand anschliessen (typisch 100 Ohm). Es gibt aber Breakout-Boards, bei denen diese Widerstände bereits eingebaut sind.

 
 
 
 
Selbstbau mit Luminex SSL-LX5097 und 100 Ohm Vorwiderständen
 
KY--016 Breakout mit eingebauten Vorwiderständen
 

Wenn du die oben gezeigte Anordnung verwendest, sind die Zuordnungen der Farben blau, grün und rot auf den Ports IO19, IO18, IO23. Mit dem folgenden Programm erzeugst du ein zufälliges Farbspiel.

Programm:

from machine import Pin, PWM
from time import sleep
from random import randint

P_RED = 23
P_GREEN = 18
P_BLUE = 19
fPWM = 50  

def setColor(r, g, b):
    pwmRed.duty(r)
    pwmGreen.duty(g)
    pwmBlue.duty(b)
            
pwmRed = PWM(Pin(P_RED), freq = fPWM)
pwmGreen= PWM(Pin(P_GREEN), freq = fPWM)
pwmBlue = PWM(Pin(P_BLUE), freq = fPWM)

while True:
    r = randint(0, 1023)
    g = randint(0, 1023)
    b = randint(0, 1023)
    setColor(r, g, b)
    sleep(0.2)
► In Zwischenablage kopieren

Du kannst die Farben besonders schön erkennen, wenn du ein weisses Papier als Diffusor über die LED legst.


Servomotoren

Bei einem Servomotor kannst du die Motorachse programmgesteuert in eine bestimmte Richtung drehen. Der Servomotor hat 3 Eingänge: GND, POWER und SIGNAL und wird mit einem PWM-Signal angesteuert. Über den Dutycyle stellst du die Achsrichtung ein. Den Zusammenhang zwischen Dutycycle und Achsrichtung findest du am besten experimentell heraus.

 (Es gibt auch "kontinuierliche" Servomotoren, die je nach Dutycycle verschieden schnell rotieren).

Im Hobbybereich sind  kleine Servomotoren mit einem Dreifachkabel bekannt (z.B. Tower Pro SG90). Die Kabelfarben sind üblicherweise braun: GND; rot(od. orange): VCC; gelb. Signal. Die Stromversorgung durch die Oxocard reicht allerdings nur für ganz kleine Servomotoren aus, darum solltest du Servomotoren grundsätzlich mit einer externen Spannungsquelle speisen. Du kannst das gleiche Kabel verwenden, das du für den Betrieb der NeoPixels konfektioniert hast (siehe Kapitel Neopixels). Die Verkabelung ist einfach:

 

Im folgenden Programm wird der Servomotor, der am Pin 18 angeschlossen ist, ständig mit zunehmendem Dutycycle angesteuert und wieder zurückgesetzt.

Programm:

from machine import PWM, Pin
from time import sleep

P_PWM = 18

servo = PWM(Pin(P_PWM), freq = 50)

while True:
    for duty in range(25, 126):
        servo.duty(duty)
        print(duty)
        sleep(0.1)
► In Zwischenablage kopieren

 

 

MERKE DIR...

 

PWM-Signale können zur Leistungssteuerung von Lichtquellen und Gleichstrommotoren eingesetzt werden, aber auch Servomotoren positionieren. Wichtigste Kenngrössen sind die PWM-Frequenz und der Dutycycle.

 

 

ZUM SELBST LÖSEN

 

 

1.

Ein PWM-Ausgang kann auch dazu verwendet werden, eine LED blinken zu lassen, ohne dass das Programm blockiert. Schreibe ein Programm, dass zuerst das Blinken einer LED mit der Frequenz 1 Hz startet und dann endlos den Text "Programmieren macht Spass" auf dem LED-Display ausschreibt.

2.

Schreibe ein Programm so, das, wie bei einem Lichtregler, beim Gedrückt halten des rechten Buttons die Helligkeit einer LED ansteigt, bis du den Button loslässt und analog beim Gedrückt halten des linken Buttons die Helligkeit absinkt.

3.

Befestige an einem Servomotor eine kleine Flagge, die du mit Buttons der Oxocard heben und senken kannst.

 

 

 

ZUSATZSTOFF


 

MIT JOYSTICK AUF POSITION FAHREN

 

Ein Joystick ist ein Sensor, der die Lage des Knüppels als x- und y-Werte abgibt. Zusätzlich wird beim Drücken des Knüppels noch ein Tastenschalter geschlossen. Das Modell KY-023 ist Teil von diversen Sensorkits, kann aber auch einzeln (z.B. über eBay) beschafft werden. Im Innern befinden sich zwei Potentiometer, welche durch Bewegung des Knüppels ihren Wert ändern. Die 5 Anschlüsse sind wie folgt geschaltet:

 

Du verbindest GND und VCC und legt die Ausgangsspannungen X und Y an zwei Kanäle eines ADC an. Damit erhältst du digitale Werte für die Knüppelpositionen. Du willst damit einen Roboterkopf mit zwei Servomotoren positionieren. Dein Programm verwendet den ADS1015 als ADC.

Programm:

from machine import PWM, Pin
from ads1x15 import ADS1015

P_PWM_HORZ = 18
P_PWM_VERT = 19
VMAX = 1600

def valueToDuty(v):
    return int(v / VMAX * 100 + 30)

servoHorz = PWM(Pin(P_PWM_HORZ), freq = 50)
servoVert = PWM(Pin(P_PWM_VERT), freq = 50)

adc = ADS1015()
while True:
    horz = VMAX - adc.read(0)
    vert = adc.read(1)
    servoHorz.duty(valueToDuty(horz))
    servoVert.duty(valueToDuty(vert))
► In Zwischenablage kopieren