Arduino lessen/les 3
Les 3 Analoge uitvoer
Een Arduino heeft niet een echte analoge uitgang: er is geen Digitaal/Analoog-omzetter (D/A converter). Dit betekent dat het niet goed mogelijk is om een analoog signaal, zoals spraak of muziek, weer te geven. Maar als het gaat om een analoog niveau, bijvoorbeeld voor de lichtsterkte van een LED, of de snelheid van een motor, dan kunnen we de pulsbreedtemodulatie (pulse width modulation, PWM) van de Arduino gebruiken. De onderstaande opdrachten zijn bedoeld om hiermee te leren werken.
Opdracht 1. Dimmer zonder invoer
Bij deze opdracht gebruik je een LED met serieweerstand op het breadboard, aangesloten op pin 9 van de Arduino. Zie hiervoor het schema van "Blink" voor de bedrading op het breadboard.
- De pinnen van de Arduino waarvoor een PWM-uitvoer mogelijk is, worden op het bord aangegeven door "~". Dit zijn de pinnen 3, 5, 6, 9, 10, 11.
Gebruik programma Voorbeelden-> 01.Basic-> Fade, met de LED aangesloten op pin 9.
Een samenvatting van het programma Fade
:
int led = 9; // the PWM pin that the LED is attached to
int brightness = 0; // brightness state for the LED
int fadeAmount = 5; // change in brightness state per step
void setup() {
pinMode(led, OUTPUT); // use pin 9 as output
}
void loop() {
analogWrite(led, brightness); // set LED to brightness state
brightness = brightness + fadeAmount; // change brightness
if (brightness == 0 || brightness == 255) { // at end of fade cycle
fadeAmount = -fadeAmount ; // reverse the fade direction
}
delay(30); // wait for 30 milliseconds
}
Uitleg bij dit programma:
- we gebruiken de variabelen
brightness
om het lichtniveau van de LED bij te houden; - elke doorgang van de lus tellen we
fadeAmount
op bij dezebrightness
- als
fadeAmount
negatief is, verlagen we hiermee debrightness
- als
- het symbool
||
staat voor "or": de logische (inclusieve) of. Deze levert true als tenminste één van de twee operanden true is.- Dit is anders dan de exclusieve of die we in het dagelijks leven vaak gebruiken, bijvoorbeeld: de prijs is voor Jan of Joke.
- als we aan het eind van het bereik komen (0 of 255), veranderen we het teken van
fadeAmount
Let op: 255 moet deelbaar zijn door fadeAmount
- anders komen we aan het eind niet uit. Hoe zou je dat kunnen aanpassen?
Variaties
- Pas het programma aan zodat de LED in een ander tempo verandert.
- Pas het programma aan zodat de LED varieert tussen de halve en de hele lichtsterkte.
Opdracht 2. Dimmer met drukknoppen
Bij deze opdracht gebruik je de drukknoppen om een hoger of een lager lichtniveau te schakelen. Hiervoor gebruik je de techniek voor het schakelen met een drukknop: zie Arduino lessen/les 2 - opdracht 2.
- sluit een LED aan (op de normale manier, via een serieweerstand) pin 9. Dit is één van de pinnen die als analoge output (PWM) gebruikt kan worden.
- sluit twee schakelaars aan: op pin 2, voor de "up", en op pin 3 voor de "down" knop.
const int led = 9; // PWM ("analog out")
const int upButton = 2;
const int downButton = 3;
int ledLevel = 1; // always a power of 2, 1..256
void setup() {
pinMode(led, OUTPUT);
pinMode(upButton, INPUT);
pinMode(downButton, INPUT);
}
void loop() {
if (digitalRead(upButton)) {
if (ledLevel < 256) {
ledLevel = ledLevel * 2;
}
delay(300);
}
if (digitalRead(downButton)) {
if (ledLevel > 1) {
ledLevel = ledLevel / 2;
}
delay(300);
}
analogWrite(led, ledLevel - 1);
}
Uitleg bij dit programma:
- we gebruiken de variabele
ledLevel
om het niveau van de LED bij te houden. We zorgen ervoor dat dit een macht van 2 is (1, 2, 4, 8, ..., 256): die kunnen we altijd eenvoudig halveren en verdubbelen. - voor het aansturen van de led gebruiken we
ledLevel - 1
: dat is een getal in het bereik 0..255, precies wat we nodig hebben voor een PWM uitvoer. - als
upButton
ingedrukt is, verdubbelen weledLevel
, tot maximaal 256. - als
downButton
ingedrukt is, halveren weledLevel
, tot minimaal 1. - we gebruiken geen aparte variabele om de toestand van de button in te bewaren: we gebruiken direct het resultaat van de
digitalRead(...)
in de conditie van de if. We hebben dit resultaat alleen maar op deze plek nodig. - de
delay(300);
gebruiken we om te voorkomen dat bij het indrukken van een button, direct het maximale of het minimale niveau bereikt wordt. Computers zijn erg snel!- een betere methode is om alleen te kijken naar het indrukken van de knop, niet naar het "ingedrukt zijn". Zie bijvoorbeeld:
Vragen:
- in hoeveel stappen heb je het maximale niveau bereikt?
- wat gebeurt er als je een knop ingedrukt houdt?
Variaties
- gebruik in plaats van verdubbelen of halveren, het veranderen van
ledLevel
met een vaste waarde, zoals in opdracht 1.- denk erom dat je de test voor de maximale en de minimale waarde hierop aanpast.
Achtergrondinformatie
Voor voorbeelden en een uitleg van de verschillende begrippen, zie:
- achtergrondmateriaal, Analoge uitvoer