PWM (Pulsweitenmodulation) wird beim Arduino beispielsweise als Möglichkeit zum Dimmen von LEDs oder zum Ansteuern von Servo-Motoren verwendet. Allerdings ist die Anzahl der Pin, die für PWM verwendet werden können, beschränkt:
Board | PWM-fähige Pins | PWM-Frequenz |
---|---|---|
Arduino Uno/Nano/Mini | 3, 5, 6, 9, 10, 11 | 490 Hz (pins 5 + 6: 980 Hz) |
Arduino Mega | 2 - 13, 44 - 46 | 490 Hz (pins 4 + 13: 980 Hz) |
Arduino Leonardo/Micro/Yún | 3, 5, 6, 9, 10, 11, 13 | 490 Hz (pins 3 + 11: 980 Hz) |
Es gibt jedoch Möglichkeiten diese Einschränkung zu erweitern, z.B. mit der Library bhagman/SoftPWM, die alle verfügbaren Pins des Arduino in PWM-fähige Ausgänge verwandelt. Diese Library wurde ursprünglich zum Dimmen von LEDs geschrieben, kann aber wohl auch auf andere Aufgaben angewendet bzw. umgeschrieben werden.
Um PWM auf einem beliebigen Pin des Arduino zu ermöglichen, verwendet die Library SoftPWM einen Hardware-Timer
(Timer 2
auf AVR-Systemen bzw. IntervalTimer
auf Teensy 3.x).
Es können allerdings nur maximal 20 PWM-Kanäle gleichzeitig erstellt werden, wobei die Wahl der Pins
völlig frei ist. Zusätzliche Features der Library sind separate Dimmzeiten für ON und OFF, sowie ein
echtes Ausschalten beim Modus OFF.
Zuächst wird SoftPWM initialisiert und mit einem Pin (hier 13) als PWM eingerichtet. Dann wird die
Dimmzeit gesetzt (hier 1s = 1000ms). Sobald im loop()
ein Wert (=Tastrate/Duty cycle) für den
Pin mit SoftPWMSetPercent
gesetzt wird, fängt die angeschlossene LED an, sich zu dimmen.
Wichtig bei der Verwendung von SoftPWMSetPercent
bzw. SoftPWMSet
ist, dass sie
den weiteren Verlauf des Sketches nicht blockiert. Im folgenden Sketch wird allerdings der Einfachheit
halber ein delay()
-Aufruf zum Warten verwendet.
#include <SoftPWM.h>
#define PIN_LED 13
#define FADE_DELAY 1000 // in ms
void setup()
{
SoftPWMBegin();
SoftPWMSet(PIN_LED, 0); // init LED and turn it off
SoftPWMSetFadeTime(PIN_LED, FADE_DELAY, FADE_DELAY);
}
void loop()
{
static byte setValue = 0;
setValue += 100;
setValue %= 200;
SoftPWMSetPercent(PIN_LED, setValue);
delay(FADE_DELAY);
}
In diesem Beispiel werden zwei LEDs abwechselnd gedimmt, wobei hierbei eine nicht-blockierende Methode des Wartens zwischen den Sequenzen verwendet wird.
#include <SoftPWM.h>
#define PIN_LED_1 12
#define PIN_LED_2 13
#define FADE_DELAY 1000 // in ms
void setup()
{
SoftPWMBegin();
SoftPWMSet(PIN_LED_1, 0);
SoftPWMSet(PIN_LED_2, 0);
SoftPWMSetFadeTime(PIN_LED_1, FADE_DELAY, FADE_DELAY);
SoftPWMSetFadeTime(PIN_LED_2, FADE_DELAY, FADE_DELAY);
}
void loop()
{
static long nextAction = (long)millis() + FADE_DELAY;
static byte setValue = 0;
if ((long)millis() - nextAction >= 0) {
nextAction = (long)millis() + FADE_DELAY;
setValue += 100;
setValue %= 200;
SoftPWMSetPercent(PIN_LED_1, setValue);
SoftPWMSetPercent(PIN_LED_2, (setValue+100)%200);
}
}
zurück