Arduino - PWM

From SPAD-it Wiki
Jump to: navigation, search

PWM: Pulse Width Modulation

PWM betekent Pulse Width Modulation, of in het Nederlands Pulse Breedte Modulatie (PBM). Het woord modulatie wijst op veranderingen in de tijd. Een modulerend signaal is dus niet constant, maar veranderend. In het geval van pulse breedte modulatie gaat het om een signaal dat wisselt tussen 0 Volt en 5 Volt, waarbij de mate waarin het 5 Volt is ingesteld kan worden. Dit gaat in een vast patroon dat zich steeds herhaald. Zo'n patroon heet dan een cyclus. De duur van elke cylus is gelijk en in ons geval ongeveer 2 milli seconde. Gedurende een fractie hiervan staat het signaal op 5 Volt; de resterende tijd staat het op 0 Volt. Het is ofwel 0 Volt ofwel 5 Volt; tussenwaarden komen niet voor.

PWM cycle.png
Een cyclus in een PWM signaal

Het deel waarbij het signaal op 5 Volt staat heet de pulse en de breedte ervan is dus de pulse breedte. Deze pulse breedte is belangrijk omdat de gemiddelde spanning natuurlijk toeneemt met de pulse breedte. Als de pulse breedte de hele cyclus omvat is die gemiddelde spanning 5 Volt en als de pulse breedte nul is, geldt dat ook voor de gemiddelde spanning. Hieronder een paar voorbeelden:

PWM.png
Een cyclus in een PWM signaal

Een PWM signaal geeft dus, afhankelijk van de pulse breedte, een hogere of lagere gemiddelde spanning af. Als we een LED-lampje aansluiten op een pin met PWM, kunnen we de helderheid van het lampje regelen door de pulse breedte te moduleren. In feite gaat het LED lampje heel snel knipperen, maar de frequentie is zo hoog dat het voor ons totaal onzichtbaar is. Het enige dat we zien is dat de helderheid van het lampje verandert.

Waarom PWM?

Op het eerste gezicht zou je denken dat PWM onnodig ingewikkeld is. Waarom niet gewoon de spanning aanpassen? Daar zijn echter veel goede redenen voor. Natuurlijk is de processor in de Arduino primair een digitaal ding, maar PWM heeft toch vooral te maken met efficient energiegebruik. Bij 5 Volt geeft de Arduino alles door wat het zelf krijgt en wordt er door de processor geen energie opgenomen. Bij 0 Volt geeft de Arduino niks door en blijft er ook geen energie achter. Zonder hier verder op in te gaan zou de Arduino bij alle tussenwaarden wel energie moeten opnemen. Dat is niet alleen zonde, maar ook gevaarlijk voor de levensduur van de processor omdat die dan al snel te warm zou kunnen worden.

Een andere reden om PWM te gebruiken is dat het vaak beter werkt. Een gewoon LEDje heeft bijvoorbeeld zo'n 1.5 Volt nodig. De hoeveelheid licht die er vanaf komt is echter helemaal niet evenredig met die spanning. Maar de hoeveelheid licht (per seconde gemiddeld) is natuurlijk wel evenredig aan de breedte van een PWM signaal. Door PWM te gebruiken kun je dus met meer zekerheid de lichtintensiteit, of algemener, de energietoevoer regelen. En het mooiste is: de PWM techniek zit ingebouwd in de chips op de diverse Arduino bordjes. Je hoeft er vrijwel niks extra's voor de doen.

De schakeling

Onderstaande schakeling bevat een zogenaamde potmeter of potentiometer. Dat is een weerstand met een glijdende aftakking in het midden. De weerstand tussen de buitenste pootjes is een constante weerstand van, in dit geval 10kΩ. In de huidige toepassing wordt de ene kant van de potmeter verbonden met de 5 Volt en de andere kant met de 0 Volt. De aftakking daartussen krijgt daardoor een tussenspanning. Helemaal de ene kant op gedraaid zal die spanning 5 Volt zijn, helemaal aan de andere kant 0 Volt en halvewege 2,5 Volt. Door de potmeter te draaien kun je de spanning op pin A0 traploos regelen tussen 0 en 5 Volt. Het woord potentiaal betekent spanning. Het woord potmeter zou je dus kunnen vertalen als spanningsmeter. Natuurlijk is het geen spanningsmeter, maar in de klassieke potentiometerschakeling kon hij gebruikt worden om de spanning te bepalen. De instelbare spanningsdeler die daarin wordt gebruikt is potentiometer of potmeter gaan heten. Hieronder een plaatje hoe een potmeter van binnen werkt:

Potmeter.png
De werking van een potmeter

Extra benodigdheden:

  • 1 LED
  • 1 weerstand van 180Ω-220Ω
  • 1 potmeter van 10kΩ
LED dimming.png
Een LED-dimmer schakeling

Het programma

Upload het volgende programma naar je Arduino:

int potpin=0;                 // de potmeter zit aan pin A0; dat is een '''analoge input pin'''
int ledpin=6;                 // het LEDje zit aan pin 6 (een pin met PWM mogelijkheden)

void setup()
{
  pinMode(ledpin,OUTPUT);      // maak de ledpin “output”
  // de potpin hoeft niet als input te worden aangemeld: analoge pins zijn altijd “input”
}

void loop()
{
  int val=analogRead(potpin);  // lees de analoge instelling van de pot (waarde tussen 0 en 1023)
  analogWrite(ledpin,val/4);   // stuur een PWM signaal (waarde tussen 0 en 255:  1024/4=256) naar de LED
}

Uitleg

Allereerst worden er twee variabelen gedefinieerd: ledpin en potpin. De LED komt natuurlijk aan de LEDpin en de potmeter aan de potpin. De ledpin moet een pin zijn die PWM ondersteund; lang niet alle uitgangen van de Arduino doen dat. Op de printplaatjes is dat meestal aangegeven met een ~. Pins 3, 5, 6, 9, 10 en 11 ondersteunen PWM. De potmeter moet aan een analoge input pin. Dat zijn speciale aansluitingen die een analoge waarde kunnen inlezen. Hier staat de term analoog tegenover digitaal. Bij analoog moet je denken aan een glijdende schaal, terwijl digitaal vooral slaat op 0 of 1. De spanning van de potmeter tussen 0 en 5 Volt is analoog. Analoge pins van de Arduino UNO worden aangeduidt met A0 tm A5. Achter zo'n analoge ingang schuilt een AD convertor. Dat is een stukje elektronica waarmee een analoge spanning wordt omgezet naar een getal. Bij de Arduino UNO zijn dat getallen tussen 0 en 1023, waarbij 0 duidt op 0 Volt en 1023 op 5 Volt. De letter A wijst erop dat het een analoge ingang gaat. De Arduino UNO heeft geen echte analoge uitgangen, maar dus wel vijf PWM uitgangen. Let op dat pin 0 kan wijzen op digitale in/output pin '0' en op analoge input pin A0. De functie analogRead() zal altijd kijken naar een van de pins A0 tm A5, aangeduidt als pin 0 tm 5. De functie digitalRead() zal daarentegen bij dezelfde nummers naar andere pins kijken!

De setup() spreekt voor zich. Bijzonder is wel dat van analoge pins niet hoeft te worden aangegeven dat het om INPUT pins gaat - deze pins zijn altijd input pins.

De loop() functie leest de waarde van de analoge input pin A0 met de functie analogRead(). Dit is een getal tussen 0 en 1023 en komt in variabele val. De LED hangt aan een PWM pin en PWM signalen moeten worden opgegeven als getal tussen 0 (=> hele cyclus 0 Volt) en 255 (=> hele cyclus 5 Volt). Daarom sturen we een waarde naar de LED gelijk aan val gedeeld door 4. Dit betekent dat de LED oplicht in een mate die overeenkomt met de stand van de potmeter.

Beetje spelen

  • Na een tijdje spelen vind je dat het handiger zou zijn als de potmeter andersom zou werken: het lampje gaat zachter branden als de pot de andere kant opdraait. Kun je dit oplossen door de verbindingen op je breadboard aan te passen?
  • Vaak is het handiger om de software te veranderen, bijvoorbeeld als de hardware al in elkaar is gesoldeerd! Misschien moet je even naar het programma kijken of je het daarmee ook kunt omdraaien.
  • Bij het vorige project hebben we een knopje gebruikt om de LED aan en uit te zetten. We zouden de pot kunnen vervangen door het knopje van de vorige keer, maar in plaats van alleen aan- en uitzetten, zou dat knopje ook moeten kunnen dimmen. Denk er eerst zelf eens even goed over na en probeer desnoods wat. Hier is in elk geval ook een oplossing.

Navigatie