← Back to CoursesStemExpert
StemExpert
Intermediate · Handboek · 25. Van analoog naar digitaal
StemExpert · Brecht Corbeel · schoolium.me
StemExpert
I25. Van analoog naar digitaal
IIntermediate · deel I6 · Elektronica

Handboek · hoofdstuk 25Van analoog naar digitaal

Van een spanning naar een getal, en van een getal terug naar licht

De wereld is analoog: een temperatuur of een lichtsterkte kan elke waarde aannemen, op elk moment. Een microcontroller kent alleen enen en nullen. In dit hoofdstuk leer je hoe die twee elkaar vinden: hoe je met bits getallen schrijft, hoe een ADC een spanning in 1024 trapjes meet, hoe vaak je moet meten om niets te missen, en hoe een digitale pin met PWM toch 'een beetje' aan kan staan. Met dat laatste dim je de groeilampen van de klimaatmodule zo, dat ze het daglicht precies aanvullen.

8× uitleg5× uitgewerkt voorbeeld1× proef1× naslag1× verhaal1× het geheel2× code16 opdrachten in het werkboek± 8 lestijden
Als de zon zakt, gaan de lampen niet plots aan, maar geleidelijk: zoveel als er aan daglicht ontbreekt.
Als de zon zakt, gaan de lampen niet plots aan, maar geleidelijk: zoveel als er aan daglicht ontbreekt.
Na dit hoofdstuk
Verhaal · 25.1

Een wereld in enen en nullen

1/19

In 1948 publiceerde de Amerikaanse wiskundige en ingenieur Claude Shannon een artikel met een bescheiden titel, 'A Mathematical Theory of Communication'. Hij toonde dat je elke boodschap (tekst, een telefoongesprek, een beeld) kan meten in één eenheid: het aantal ja-neevragen dat je nodig hebt om ze te beschrijven. Die eenheid noemde hij, met een woord van zijn collega John Tukey, de bit, van binary digit.

Een jaar later bewees Shannon ook hoe vaak je een geluid of een ander signaal moet meten om het perfect te kunnen terugmaken: meer dan twee keer per trilling van de snelste toon erin. Harry Nyquist had het idee al in 1928 aangevoeld. Op die regel rust de muziek-cd uit 1982: 44 100 metingen per seconde, elk in 16 bits, genoeg voor tonen tot boven 20 000 Hz, de grens van het menselijk gehoor.

Een microcontroller doet op kleine schaal hetzelfde. Hij meet een spanning, maakt er een getal van 10 bits van, rekent ermee, en stuurt dan weer iets 'analoogs' aan: een led die half brandt, een motor die half zo snel draait. Hoe dat heen en terug gaat, is het onderwerp van dit hoofdstuk.

Waarom dit hoofdstuk ertoe doet

Elke sensor van Habitat komt binnen via een ADC, en elke actuator die meer kan dan aan en uit, wordt met PWM gestuurd. Wie weet hoe groot een ADC-stap is en hoe vaak je moet meten, weet ook welke metingen je kan vertrouwen.

Het oppervlak van een cd: miljarden putjes en vlakjes, samen 44 100 getallen van 16 bits per seconde en per kanaal.
Het oppervlak van een cd: miljarden putjes en vlakjes, samen 44 100 getallen van 16 bits per seconde en per kanaal.
Uitleg · 25.2

Analoog en digitaal

2/19

Wat je al weet. Een digitale pin is hoog of laag (F24); analogRead geeft een getal van 0 tot 1023 (F25), en dat getal hoort bij een spanning in stappen van 4,88 mV (hoofdstuk 22).

Een analoog signaal kan elke waarde aannemen, op elk moment: de temperatuur in de kweekruimte stijgt niet in sprongetjes van een graad, en ze bestaat ook tussen twee metingen. Een digitaal signaal is op twee manieren beperkt:

  • in de tijd: je meet maar op bepaalde ogenblikken, bijvoorbeeld elke seconde (bemonsteren);
  • in de waarde: je rondt af op een eindig aantal niveaus (kwantiseren), bij een ADC van 10 bit op 1024 niveaus.

De grafiek toont het met een bewust grove versie: om de seconde gemeten en afgerond op stappen van 2 °C. Wat tussen twee metingen gebeurt, is verloren, en elke meting is tot 2 °C te laag. Met meer niveaus en vaker meten komt de digitale versie dichter bij het origineel, maar het kost meer bits. De kunst is te kiezen wat genoeg is.

Waarom dan digitaal?

Een digitaal signaal kan je zonder verlies kopiëren, versturen, opslaan en bewerken: een 1 blijft een 1, ook na een lange draad met wat ruis. Een analoge spanning verandert bij elke stap een beetje. Daarom meet je zo dicht mogelijk bij de sensor, en reken je daarna digitaal verder.

01234567891016182022242628t (s)T (°C)analoog: elke waarde, op elk momentdigitaal: om de seconde, in stappen van 2 °C
Het analoge signaal (blauw) en de digitale versie (rood): een trap die pas bij de volgende meting verandert.
Uitleg · 25.3

Het binaire talstelsel

3/19

Ons talstelsel is decimaal: tien cijfers, en elke plaats is tien keer zoveel waard als de plaats rechts ervan. In 407 staat de 4 voor . Een computer heeft maar twee toestanden (spanning of geen spanning) en rekent daarom binair: twee cijfers, 0 en 1, en elke plaats is twee keer zoveel waard. Eén binair cijfer is een bit; acht bits samen zijn een byte.

Van binair naar decimaal: tel de gewichten op van de plaatsen met een 1. In de figuur: .

Van decimaal naar binair: deel telkens door 2 en noteer de rest. De resten, van onder naar boven gelezen, zijn de bits. Voor 200:

delingquotiëntrest
200 : 21000
100 : 2500
50 : 2250
25 : 2121
12 : 260
6 : 230
3 : 211
1 : 201

De resten van onder naar boven: 1100 1000.

Met bits schrijf je verschillende waarden, van 0 tot . Een byte gaat dus van 0 tot 255, en een ADC van 10 bit van 0 tot 1023:

bits12348101216
niveaus 248162561024409665 536
grootste getal137152551023409565 535
Bits in je programma

Op de Uno en de Mega is een int 16 bits: van −32 768 tot 32 767 (één bit voor het teken). millis() geeft een unsigned long van 32 bits: tot 4 294 967 295 ms, ongeveer 49,7 dagen. Daarna begint de teller weer bij 0: daarom schrijf je altijd nu - start >= wachttijd (hoofdstuk 23 en 29). Ook tekst is binair: de letter A wordt verstuurd als de byte 65.

1128270642613225116240823142212210120gewicht van elke plaats128 + 32 + 16 + 4 + 2 = 1821011 0110 (binair) = 182 (decimaal) = B6 (hexadecimaal)
Elke plaats is twee keer zoveel waard als de plaats rechts ervan; de blauwe bits tellen mee.
Uitgewerkt voorbeeld · 25.4

Omrekenen tussen decimaal, binair en hexadecimaal

4/19

(a) Schrijf 1023 binair. (b) Welk decimaal getal is ? (c) Een Arduino-programma bevat 0x3FF en 0xB6. Welke getallen zijn dat? (d) Hoeveel bits heb je minstens nodig om de ADC-waarden van 0 tot 1023 op te slaan, en hoeveel bytes neemt dat in?

B610110110=hex: twee cijfersbinair: twee groepjes van vier bits
B is 11 = 1011, 6 = 0110: zo lees je hexadecimaal meteen binair.
Gegeven
  • tabel met machten van 2; hexadecimale cijfers 0-9, A = 10 … F = 15
Gevraagd
  • 1023 binair
  • decimaal
  • 0x3FF en 0xB6
  • bits en bytes voor 0-1023
Oplossing
  1. 1
    (a) : tien enen, . (Met delen door 2 kom je hetzelfde uit: elke rest is 1.)
  2. 2
    (b) .
  3. 3
    (c) Hexadecimaal (grondtal 16) gebruikt 0-9 en A-F. Eén hexcijfer is precies vier bits, dus een byte is twee hexcijfers. , of per vier bits: . .
  4. 4
    (d) is te weinig, precies genoeg: 10 bits. Computers bewaren per hele byte, dus 2 bytes (16 bits, waarvan 6 ongebruikt).
Antwoord
; ; 0x3FF = 1023 en 0xB6 = 182; 10 bits, dus 2 bytes per ADC-waarde.
Klopt dit? Hexadecimaal is handig omdat je het zonder rekenen omzet naar binair: elk cijfer wordt vier bits. Je ziet het in de kleurcode van webpagina's (#FF8800: rood 255, groen 136, blauw 0) en in het geheugen van een microcontroller.
Uitleg · 25.5

De ADC: resolutie en bereik

5/19

Een ADC (analoog-digitaalomzetter) verdeelt een spanningsgebied, van 0 V tot de referentiespanning , in gelijke stappen. Twee getallen bepalen wat hij kan:

  • het bereik: van 0 tot . Negatieve spanningen worden 0, spanningen boven worden 1023. (Boven de voedingsspanning mag een pin nooit komen: dan kan hij stukgaan.)
  • de resolutie: de grootte van één stap, .
ADC van n bit
: naar beneden afronden. Alles tussen en stappen geeft hetzelfde getal: de meting zegt 'ergens in deze stap'. De fout door afronden is hoogstens één stap (of een halve, als je met het midden van de stap rekent).

De grafiek toont het principe met maar 3 bits: 8 niveaus, stappen van 0,625 V. Een ADC van 10 bits heeft hetzelfde trappetje, maar met 1024 treden van 4,88 mV.

Resolutie is niet hetzelfde als nauwkeurigheid (hoofdstuk 1). Een stap van 4,88 mV zegt hoe fijn je kan aflezen, niet of het getal klopt. Als de referentie 4,95 V is in plaats van 5,00 V, is elke meting 1 % te hoog, hoe fijn de trapjes ook zijn. En ruis op de sensor maakt de laatste bit vaak onzeker.

De referentie kiezen. Wie kleine spanningen meet, verspilt het grootste deel van de treden. Met analogReference(INTERNAL) meet een Uno tegen een ingebouwde referentie van ongeveer 1,1 V (op de Mega INTERNAL1V1 of INTERNAL2V56): de stap wordt . Het bereik krimpt dan wel tot 1,1 V. De interne referentie ligt per chip ergens tussen 1,0 en 1,2 V: ijk ze. En gooi de eerste metingen na het omschakelen weg.

0,0000,6251,2501,8752,5003,1253,7504,3755,00012345678U (V)N (3 bit)één stap = 5 V / 8 = 0,625 Vuitgang van een ADC van 3 bitideaal: N = 8 · U / 5 V
Elke tree is 0,625 V breed; de trap ligt telkens onder de ideale rechte (naar beneden afronden).
Uitgewerkt voorbeeld · 25.6

Habitat: hoe fijn meet de TMP36 van de meetkas?

6/19

De TMP36 op A1 van de meetkas (F25) geeft . (a) Hoeveel graden is één ADC-stap met de standaardreferentie van 5 V? (b) En met de interne referentie van 1,1 V? Tot welke temperatuur kan je dan meten? (c) Welke ADC-waarde geeft 25,0 °C in beide gevallen? (d) Is 1,1 V een goed idee voor de kas, die op een zonnige dag 32 °C haalt?

Gegeven
  • (V, °C)
  • 10 bit; of
Gevraagd
  • °C per stap
  • bereik met 1,1 V
  • ADC-waarde bij 25 °C
  • keuze
Oplossing
  1. 1
    (a) Eén stap is 4,88 mV; de sensor geeft 10 mV per graad: per stap.
  2. 2
    (b) Met 1,1 V: , dus per stap, bijna vijf keer fijner. Hoogste meetbare spanning 1,1 V: .
  3. 3
    (c) Bij 25,0 °C is . Met 5 V: . Met 1,1 V: .
  4. 4
    (d) Ja: tot 60 °C is ruim genoeg voor de kas (32 °C), ook in de volle zon. Maar de TMP36 zelf is maar op ongeveer ±2 °C nauwkeurig (daarom de ijkcorrectie van −1,5 °C uit F25): de fijnere stap maakt de meting vloeiender (kleine veranderingen worden zichtbaar), niet juister.
Antwoord
0,49 °C per stap met 5 V, 0,11 °C met 1,1 V (bereik tot 60 °C); 25,0 °C geeft 153 of 698. De interne referentie loont voor een vloeiender verloop, niet voor een juistere temperatuur.
Klopt dit? Met 5 V kan een regeling op 28 °C (het dakraam, F25) alleen kiezen tussen 27,8 en 28,3 °C: net genoeg. Met 1,1 V gaat dat per 0,1 °C. Let op: de andere sensoren op de Uno (bodemvocht, LDR) hebben de 5 V-referentie nodig; wie wisselt tussen referenties, moet na elke omschakeling enkele metingen weggooien.
Uitleg · 25.7

Binnen in de ADC: tien vragen voor tien bits

7/19

In hoofdstuk 22 bleef open hoe de ADC zijn getal vindt. De ADC van de ATmega werkt met opvolgende benadering, het spelletje 'raad mijn getal' met ja-neevragen. Hij heeft een kleine digitaal-analoogomzetter die een proefspanning maakt, en een comparator die zegt of de gemeten spanning groter of kleiner is.

  1. Eerst houdt hij de ingangsspanning vast op een condensatortje van ongeveer 14 pF (hoofdstuk 24): de sample and hold.
  2. Dan probeert hij het hoogste bit: is stappen (2,5 V)? Ja: dat bit blijft 1. Nee: het wordt 0.
  3. Daarna het volgende bit (256), dan 128, en zo verder tot het laatste bit (1).

Na tien vragen staan alle tien bits vast. Voor :

vraagbitproefgetalproefspanningU ≥ proef?tussenstand
19 (512)5122,5000 Vja: 110 0000 0000
28 (256)7683,7500 Vnee: 010 0000 0000
37 (128)6403,1250 Vja: 110 1000 0000
46 (64)7043,4375 Vnee: 010 1000 0000
55 (32)6723,2812 Vnee: 010 1000 0000
64 (16)6563,2031 Vnee: 010 1000 0000
73 (8)6483,1641 Vja: 110 1000 1000
82 (4)6523,1836 Vja: 110 1000 1100
91 (2)6543,1934 Vja: 110 1000 1110
100 (1)6553,1982 Vja: 110 1000 1111

Resultaat: , en inderdaad is . Elke vraag halveert het gebied waarin het antwoord ligt: na tien vragen is dat één stap breed. Op een Arduino kost één analogRead 13 tikken van de ADC-klok van 125 kHz: 104 µs, dus hoogstens ongeveer 9600 metingen per seconde.

012345678910110,00,51,01,52,02,53,03,54,04,55,0stapproefspanning (V)te meten: 3,20 Vja: U is groter, bit blijft 1nee: bit wordt 0
Elke proef halveert het overblijvende gebied: van 2,5 V naar 3,75, 3,125 … tot op 4,9 mV na 3,20 V.
Uitleg · 25.8

Bemonsteren: hoe vaak moet je meten?

8/19

Een microcontroller meet niet voortdurend, maar op vaste ogenblikken. Het aantal metingen per seconde is de bemonsteringsfrequentie , in hertz; de tijd ertussen is . Hoe vaak is genoeg? Dat hangt af van hoe snel het signaal verandert. De temperatuur van het voedingsreservoir verandert in uren: eens per minuut is ruim. Een wisselspanning van 50 Hz verandert elke milliseconde: daar heb je honderden metingen per seconde nodig.

Te traag meten is erger dan weinig informatie. De grafiek toont een signaal van 9 Hz, gemeten met . Tussen twee metingen gaat het signaal bijna één keer volledig rond. De metingen liggen daardoor netjes op een traag signaal van 1 Hz, dat er in werkelijkheid niet is. Dat heet aliasing: een snel signaal doet zich voor als een traag. Je kan het achteraf niet meer herkennen: de metingen van het signaal van 9 Hz zijn precies dezelfde als die van een signaal van 1 Hz. Je ziet het ook in films, waar de wielen van een auto soms achteruit lijken te draaien: de camera bemonstert 24 beelden per seconde.

de regel van Nyquist (intuïtief)
Meet meer dan twee keer per periode van de snelste verandering in het signaal. In de praktijk neem je vijf tot tien keer, of je filtert de snelle veranderingen eerst weg (een RC-filter, hoofdstuk 24). In hoofdstuk E21 zie je waarom de regel werkt en hoe je signalen in frequenties ontleedt.

De schijnbare frequentie is de afstand tot het dichtstbijzijnde veelvoud van : 9 Hz ligt op 1 Hz van 10 Hz, dus je ziet 1 Hz. Een signaal van 50 Hz dat je precies 50 keer per seconde meet, lijkt zelfs stil te staan (0 Hz): je meet elke keer op hetzelfde punt van de golf.

toepassingbemonsteringbitsdatastroom
temperatuur van de kweekruimte1 keer per 10 s101 bit/s
klimaatmodule: 7 analoge sensoren (A0-A6)1 keer per 10 s7 × 16 (2 bytes)120 960 bytes per dag
telefoongesprek8000 per s864 000 bit/s
muziek-cd (stereo)44 100 per s2 × 161 411 200 bit/s

Meer metingen en meer bits kosten geheugen. De datalogger van de klimaatmodule (hoofdstuk 30) bewaart zeven analoge waarden om de 10 s: 2 bytes per waarde is 120 960 bytes per dag, ongeveer 44 MB per jaar. Als tekst (CSV) met datum en tijd per regel wordt dat al snel vier keer meer.

0,00,10,20,30,40,50,60,70,80,91,01,11,21,31,41,51,61,71,81,92,0−1,5−1,0−0,50,00,51,01,5t (s)signaalecht signaal: 9 Hzmetingen: 10 per secondewat de metingen tonen: 1 Hz
Tien metingen per seconde (bolletjes) van een signaal van 9 Hz liggen precies op een golf van 1 Hz (stippellijn).
Uitgewerkt voorbeeld · 25.9

Habitat: de lampstroom meten terwijl de lampen gedimd zijn

9/19

De stroomsensor ACS712 op A4 meet de stroom van de batterij (hoofdstuk 16), en het programma telt de lading op om de laadtoestand te kennen. Het meet eenmaal per seconde. Straks worden de groeilampen gedimd met PWM van 490,2 Hz en een duty cycle van 72 % (verder in dit hoofdstuk): de lampstroom springt 490 keer per seconde tussen 0 en 14,8 A. (a) Wat meet het programma? (b) Hoe groot is de gemiddelde stroom echt? (c) Hoe los je het op?

02468101214161820024681012141618t (s)gemeten stroom (A)lampen aan: 14,8 Aéén meting per secondeecht gemiddelde: 10,7 A
Eén meting per seconde: telkens de volle stroom of niets, in een patroon van 5,1 s. Het gemiddelde (stippellijn) zie je niet.
Gegeven
  • PWM: ;
  • lampen aan: ; één meting per seconde
Gevraagd
  • wat de metingen tonen
  • het echte gemiddelde
  • een betere meetmethode
Oplossing
  1. 1
    (a) Elke meting valt op een willekeurige plaats in een PWM-periode: ofwel 'aan' (14,8 A), ofwel 'uit' (0 A). Tussen twee metingen verlopen er 490,196 perioden. Het deel achter de komma, 0,196, schuift het meetpunt elke seconde 19,6 % van een periode op. De metingen vormen zo een schijnbaar signaal van 0,196 Hz: een patroon dat zich elke 5,1 s herhaalt.
  2. 2
    (b) Gemiddeld: . Eén meting is dus 4,1 A te veel of 10,7 A te weinig.
  3. 3
    (c) Meet niet één keer, maar een geheel aantal PWM-perioden lang en neem het gemiddelde: bijvoorbeeld 100 metingen in 20,4 ms, precies tien perioden (één analogRead duurt 104 µs, dus kies 204 µs tussen twee metingen). Of filter de sensorspanning eerst met een RC-filter, zoals in de proef van dit hoofdstuk.
Antwoord
Het programma ziet willekeurig 14,8 A of 0 A, in een patroon dat zich elke 5,1 s herhaalt, terwijl de echte stroom 10,7 A is. Gemiddeld over tien PWM-perioden meet je wel juist.
Klopt dit? Over lange tijd middelt de fout vaak een beetje uit, maar niet altijd: als de PWM-frequentie en het meetritme precies samenvallen, meet je altijd op hetzelfde punt, en is de laadtoestand na een dag volledig fout. Aliasing is geen zeldzaam randgeval: het ontstaat overal waar iets snel schakelt en iets anders traag meet.
Uitleg · 25.10

Van digitaal naar analoog: PWM

10/19

De Uno en de Mega hebben geen DAC (digitaal-analoogomzetter): een pin kan niet 2,5 V geven, alleen 0 of 5 V. Maar hij kan heel snel wisselen. Dat is pulsbreedtemodulatie (PWM): het signaal gaat met een vaste frequentie aan en uit, en je kiest welk deel van elke periode het aan is: de duty cycle .

PWM
: periode; : hoe lang het signaal hoog is; : de spanning als het hoog is (5 V aan een pin, 12,8 V over een last achter een MOSFET).

Met analogWrite(pin, waarde) kies je de duty cycle in 256 stappen (8 bits): 0 is altijd uit, 255 altijd aan, en daartussen is . Niet elke pin kan het: alleen de pinnen met een tilde (~) op het bord, die aan een ingebouwde timer hangen.

bordPWM-pinnenfrequentie
Uno (meetkas)3, 5, 6, 9, 10, 11490 Hz; pin 5 en 6: 980 Hz
Mega (klimaatmodule)2 tot 13 en 44 tot 46490 Hz; pin 4 en 13: 980 Hz

Die frequenties zijn afgerond: de klok van 16 MHz, gedeeld door 64 en door 510, geeft (periode 2,040 ms); op de pinnen met 980 Hz is het . Die snelle pinnen delen hun timer met millis() en geven een iets grotere duty cycle dan waarde/255.

Waarom werkt dat? Omdat wat je aanstuurt traag is tegenover 2 ms. Een led flikkert echt 490 keer per seconde, maar je oog middelt dat uit: het ziet het gemiddelde licht. Een motor heeft massa en een spoel: zijn toerental en zijn stroom volgen het gemiddelde (hoofdstuk 26). En een RC-filter maakt er een echte gelijkspanning van (de proef hierna).

Half de spanning is half het vermogen

Voor een weerstand die aan PWM hangt, is de gemiddelde spanning , maar het gemiddelde vermogen is niet . Tijdens de aan-tijd krijgt de weerstand de volle spanning en het volle vermogen , daarna niets: gemiddeld . Bij 50 % is dat de helft van het volle vermogen, niet een kwart. Hetzelfde voor leds met een voorschakelweerstand: vermogen en licht zijn evenredig met .

analogWrite(9, 64)gem. 1,25 VanalogWrite(9, 128)gem. 2,51 VanalogWrite(9, 191)gem. 3,75 V0123456t (ms)
Periode 2,04 ms (490 Hz). Hoe langer het signaal hoog is, hoe hoger het gemiddelde (stippellijn).
Uitgewerkt voorbeeld · 25.11

De ledstrip van de meetkas dimmen

11/19

De ledstrip van de meetkas (12 V, 0,40 A, 4,8 W) hangt nu aan relais K1 op D7: alleen aan of uit. Je vervangt het relais door een IRLZ44N op pin 9 van de Uno, die nog vrij is en PWM kan. (a) Welke waarde geef je aan analogWrite voor 30 % licht? (b) Hoe lang is de strip dan aan per periode? (c) Welk vermogen neemt de strip, en welke gemiddelde stroom trekt ze? (d) Hoeveel energie spaar je per winterdag (4 h licht, F17) als 30 % volstaat?

Gegeven
  • ledstrip 12 V, 0,40 A; licht evenredig met de stroom
  • Uno pin 9: 490,2 Hz,
Gevraagd
  • waarde
  • vermogen en gemiddelde stroom
  • energie per dag
Oplossing
  1. 1
    (a) : kies 77 ().
  2. 2
    (b) ; .
  3. 3
    (c) Tijdens de aan-tijd trekt de strip de volle 0,40 A (4,8 W), daarna niets. Gemiddeld: en .
  4. 4
    (d) Vol: ; gedimd: . Je spaart per winterdag, ongeveer een vijfde van het winterverbruik van de hele meetkas (62,9 Wh, F21).
Antwoord
analogWrite(9, 77): 0,62 ms aan per periode van 2,04 ms; 1,45 W en 0,12 A gemiddeld; 13,4 Wh minder per winterdag.
Klopt dit? De MOSFET schakelt de hele strip, en in de strip bepaalt de weerstand van elk segment (hoofdstuk 23) nog altijd de stroom: tijdens de aan-tijd is alles zoals zonder PWM. Ons oog vindt 30 % licht overigens niet 'een derde zo fel': het ziet het verschil tussen weinig en een beetje meer veel beter dan tussen veel en iets meer. Voor een lamp voor mensen maakt men daarom de stappen onderaan kleiner (een gammacurve).
Proef · 25.12

Een PWM-signaal gladstrijken en meten

12/19
Onderzoeksvraag

Wordt een PWM-signaal door een RC-filter echt een gelijkspanning van ? En hoeveel rimpel blijft er over?

Materiaal
  • Arduino Uno
  • weerstand 10 kΩ, elco 10 µF
  • multimeter
  • breadboard, draadjes
  • eventueel een oscilloscoop
VeiligheidElco met de min aan GND. Alles op 5 V: geen risico.
ArduinoUnoD9A0GND10 kΩ10 µFVV (DC)
Het RC-filter tussen pin 9 en A0; de voltmeter meet de gelijkspanning over de condensator.
Werkwijze
  1. 1Bouw het filter: pin 9 → 10 kΩ → knooppunt → 10 µF → GND. Het knooppunt gaat naar A0 en naar de voltmeter (DC).
  2. 2Schrijf een programma dat analogWrite(9, waarde) geeft en daarna 200 keer analogRead(A0) leest en het laagste en hoogste getal toont.
  3. 3Meet voor de waarden 0, 64, 128, 191 en 255: de voltmeter en het laagste en hoogste A0-getal.
  4. 4Vergelijk met . Meet ook eens met de voltmeter rechtstreeks op pin 9, zonder filter.
Waarneming
analogWriteduty cycleverwacht voltmeterA0 (laagste-hoogste)rimpel
00,0 %0,000 V0,00 V0-0geen
6425,1 %1,255 V1,25 V254-25819 mV
12850,2 %2,510 V2,51 V511-51626 mV
19174,9 %3,745 V3,75 V764-76820 mV
255100,0 %5,000 V5,00 V1023-1023geen

Voorbeeldmeting (berekend met het exacte RC-model). De voltmeter geeft netjes . A0 springt een paar stappen op en neer. Rechtstreeks op pin 9 toont de voltmeter bij waarde 128 ook ongeveer 2,5 V: een multimeter op DC middelt zelf al.

Verklaring

Het filter heeft , vijftig keer langer dan een PWM-periode (2,04 ms). Tijdens de aan-tijd laadt de condensator een beetje bij, tijdens de uit-tijd ontlaadt hij een beetje: gemiddeld blijft hij op hangen. Na ongeveer 5τ = 0,5 s is dat evenwicht bereikt. De rimpel is ongeveer : bij 25 % 19 mV, bij 50 % het grootst (ongeveer 26 mV, vijf ADC-stappen).

Zo maak je met PWM en een RC-filter een eenvoudige DAC. Een grotere τ geeft minder rimpel, maar een tragere reactie op een nieuwe waarde: dat is de afweging van elk filter (hoofdstuk E21).

0,00,10,20,30,40,50,60,00,20,40,60,81,01,21,41,6t (s)UC (V)5τover de condensator (10 kΩ, 10 µF)gemiddelde van het PWM-signaal: 1,25 V
Na ongeveer 0,5 s (5τ) schommelt de spanning rond het gemiddelde van 1,25 V.
01234561,2451,2501,2551,2601,2651,270t (ms), in de stabiele toestandUC (V)rimpel over de condensator
Uitvergroot: 19 mV rimpel. In de gele stroken is pin 9 hoog en laadt de condensator.
Uitleg · 25.13

PWM voor motoren en pompen

13/19

Ook een motor stuur je met PWM, via dezelfde MOSFET als in hoofdstuk 23. Tijdens de aan-tijd krijgt de motor de volle 12,8 V en neemt zijn stroom toe; tijdens de uit-tijd neemt de vrijloopdiode de stroom over en neemt ze langzaam af. De spoel van de motor houdt de stroom dus ongeveer constant, en de massa van de rotor houdt het toerental constant: de motor draait alsof hij de gemiddelde spanning kreeg. Zo regel je de pomp van de waterkringloop op D9 traploos, in plaats van 10 minuten per uur vol aan (hoofdstuk 23). Hoe toerental en spanning samenhangen, zie je in hoofdstuk 26.

Twee praktische punten:

  • De vrijloopdiode moet snel zijn: bij PWM schakelt ze honderden keren per seconde. Daarom koos hoofdstuk 23 een Schottkydiode (1N5819).
  • Een motor op 490 Hz zingt: de wikkelingen trillen mee en je hoort een toon van 490 Hz. Wie dat stoort, zet de timer op een frequentie boven het hoorbare (rond 31 kHz kan dat met een andere deler). Dan schakelt de MOSFET wel zestig keer vaker, en elke schakeling kost een beetje energie (volgend blad).
Niet voor alles

PWM werkt voor lasten die traag reageren (lampen voor het oog, motoren, verwarming). Een toestel met eigen elektronica, zoals de 5 V-omvormer of een wifi-module, wil een gewone gelijkspanning: 490 keer per seconde aan en uit laat het telkens opnieuw opstarten.

Met PWM en een potentiometer regel je het debiet van een pompje traploos.
Met PWM en een potentiometer regel je het debiet van een pompje traploos.
Uitgewerkt voorbeeld · 25.14

Habitat: de groeilampen traploos dimmen

14/19

In hoofdstuk 22 gingen de groeilampen aan onder 4000 lux en uit boven 6000 lux daglicht. Nu wil je dat het kweekbed tijdens de lichtperiode (16 uur) altijd 200 µmol/(m²·s) krijgt: daglicht plus lamplicht. De twee lampen samen geven op 100 % precies 200 (hoofdstuk 22). Ze hangen via één IRLZ44N op een koelplaat (hoofdstuk 23) aan een PWM-pin van de Mega. (a) Kies de pin. (b) Welke PWM-waarde hoort bij 3000 lux daglicht? (c) Hoeveel vermogen nemen de lampen dan, en hoeveel verliest de MOSFET? (d) Hoe warm wordt hij?

+12,8 V (rail)massa20 Agroeilamp 95 Wgroeilamp 95 WIRLZ44N op koelplaatMegaD5GND220 Ω10 kΩ
Eén MOSFET schakelt beide lampen; een zekering van 20 A beschermt de tak. Leds zijn geen spoel: geen vrijloopdiode nodig.
Gegeven
  • lampen: 190 W, 14,8 A op 12,8 V; ; MOSFET + koelplaat
  • zonlicht: 54 lux per µmol/(m²·s); schakeltijd per flank ±3 µs
  • vrije PWM-pinnen: D3-D8, D12, D13, D44-D46
Gevraagd
  • pin
  • PWM-waarde
  • vermogen lampen en verlies MOSFET
  • opwarming
Oplossing
  1. 1
    (a) D5: 490 Hz (timer 3), met . D4 en D13 geven 980 Hz en een iets afwijkende duty cycle; D44-D46 verliezen hun PWM als er ooit een servo bij komt (de servobibliotheek gebruikt op de Mega eerst timer 5); D6-D8 houden we vrij voor de dakmotor (hoofdstuk 26).
  2. 2
    (b) Daglicht: µmol. Tekort: , dus en de waarde . (Het programma leest via de LDR , rekent dat terug naar 2983 lux en komt op 185: één stap meer, door het afronden van de ADC.)
  3. 3
    (c) Lampen: . Geleiding in de MOSFET: tijdens de aan-tijd , gemiddeld .
  4. 4
    Schakelen: bij elke flank staan even spanning én stroom over de MOSFET: ongeveer , twee flanken per periode, 490 keer per seconde: . Samen .
  5. 5
    (d) boven de omgeving; op 100 % (geen schakelen) .
Antwoord
D5, analogWrite(5, 184) bij 3000 lux. De lampen nemen 137 W; de MOSFET verliest ongeveer 4,3 W en wordt 30 °C warmer dan de omgeving (op 100 %: 39 °C).
Klopt dit? De gate trekt alleen stroom bij het schakelen: hoogstens ongeveer 50 nC per flank, 980 flanken per seconde, gemiddeld minder dan 0,05 mA uit de pin. De LDR ziet het flikkeren van de lampen niet: hij reageert pas na enkele tientallen milliseconden, en hij hangt zo dat hij vooral daglicht ziet (hoofdstuk 22). En de stroommeting op A4 moet nu middelen over tien PWM-perioden (vorig voorbeeld). Eén voorwaarde bij de aankoop: de lampen moeten 'PWM-dimbaar' zijn, zoals ledpanelen van 12 V met een weerstand per segment (net als de ledstrip) of met een led-driver die een dimingang heeft (hoofdstuk 23). Een lamp met een eigen voeding die bij elke puls opnieuw opstart, dim je zo niet.
Uitleg · 25.15

Habitat: een bewolkte lentedag, aan/uit tegenover gedimd

15/19

Wat levert dimmen op? Neem een bewolkte lentedag: de zon komt op om 6.30 u en gaat onder om 19.30 u, met hoogstens 8000 lux daglicht op het kweekbed. De lichtperiode loopt van 6 tot 22 u.

  • Aan/uit (hoofdstuk 22): de lampen gaan uit om 10.01 u (boven 6000 lux) en weer aan om 17.20 u (onder 4000 lux). Ze verbruiken 1650 Wh. Het kweekbed krijgt tot 311 µmol als de lampen net nog aan zijn, en maar 111 als ze net uit zijn: een zaagtand.
  • Gedimd: de lampen vullen precies aan tot 200. Ze verbruiken 1875 Wh, en het kweekbed krijgt de hele dag 200 µmol: 11,5 mol per m² over de dag, tegenover 10,7 met aan/uit.
  • Altijd vol zou 3040 Wh kosten.

Dimmen spaart dus 38 % tegenover altijd vol aan. Op deze dag verbruikt het wel 225 Wh meer dan aan/uit, omdat aan/uit de planten tussen 10.01 en 17.20 u te weinig licht gaf. Op een zonnige dag (meer dan 10 800 lux) zijn de lampen gedimd ook uit. Het energiebeheer van hoofdstuk 20 wordt met PWM ook zachter: in plaats van de lampen uit te schakelen als de batterij laag staat, kan het de lampen op halve kracht zetten.

567891011121314151617181920212223050100150200250300uurlicht op het kweekbed (µmol/(m²·s))doel 200daglichtlampen met PWMsamen
Het daglicht (geel) plus de gedimde lampen (blauw) geeft de hele lichtperiode 200 µmol/(m²·s).
567891011121314151617181920212223050100150200250300350uurlicht op het kweekbed (µmol/(m²·s))aan/uit (hoofdstuk 22)gedimd met PWM
Aan/uit geeft sprongen van 111 naar 311 µmol; gedimd blijft het kweekbed op 200.
Code · 25.16

C++: de groeilampen dimmen

16/19

Het programma leest vijf keer per seconde de LDR, rekent het daglicht om naar µmol (hoofdstuk 22), berekent hoeveel de lampen moeten bijgeven en stuurt de PWM-waarde. Het regelt zacht bij: hoogstens één stap per 200 ms. Een wolk die even voor de zon schuift, laat de lampen dus niet meteen aanspringen, en je ziet nooit een sprong in het licht. Zonder echte klok (die komt in hoofdstuk 30) neemt het aan dat het om 6 u gestart is.

C++ (Arduino)groeilampen.ino56 regelsDownload
// groeilampen.ino - de groeilampen van de klimaatmodule dimmen met PWM (Arduino Mega)// Daglicht: LDR onder een kapje op A1, 1,0 kOhm naar GND (hoofdstuk 22). Lampen: IRLZ44N op D5 (490 Hz).const int LDR = A1;const int LAMPEN = 5;const float R_VAST = 1000.0;          // ohmconst float KAPJE = 0.10;             // het kapje laat 10 % doorconst float DOEL = 200.0;             // umol/(m2 s) op het kweekbed: daglicht + lampen samenconst float LAMPEN_VOL = 200.0;       // wat de twee lampen op 100 % gevenconst float LUX_PER_UMOL = 54.0;      // zonlichtconst unsigned long DAG_MS = 24UL * 3600UL * 1000UL; int stand = 0;                        // huidige PWM-waarde, 0 tot 255unsigned long vorige = 0; float daglichtLux() {  int n = analogRead(LDR);  if (n < 1) n = 1;                                   // niet delen door nul in het donker  float r = R_VAST * (1024.0 - n) / n;               // weerstand van de LDR (spanningsdeler omgekeerd)  float eLdr = 10.0 * pow(r / 15000.0, -1.0 / 0.7);  // lux op de LDR (model uit hoofdstuk 22)  return eLdr / KAPJE;                               // lux daglicht} int uurVanDeDag() {                  // eenvoudige klok: het programma start om 6 uur (echte klok: hoofdstuk 30)  return (6 + (millis() % DAG_MS) / 3600000UL) % 24;} void setup() {  pinMode(LAMPEN, OUTPUT);  analogWrite(LAMPEN, 0);  Serial.begin(9600);} void loop() {  unsigned long nu = millis();  if (nu - vorige < 200) return;      // vijf keer per seconde bijregelen  vorige = nu;   int doelStand = 0;  int uur = uurVanDeDag();  if (uur >= 6 && uur < 22) {         // lichtperiode van 16 uur    float dag = daglichtLux() / LUX_PER_UMOL;          // daglicht in umol/(m2 s)    float f = constrain((DOEL - dag) / LAMPEN_VOL, 0.0, 1.0);    doelStand = (int)(f * 255 + 0.5);  }  // zacht bijregelen: hoogstens 1 stap per 200 ms (van 0 naar 255 in 51 s)  if (doelStand > stand) stand++;  else if (doelStand < stand) stand--;  analogWrite(LAMPEN, stand);   if (nu % 60000UL < 200) {           // eens per minuut melden    Serial.print("uur ");    Serial.print(uur);    Serial.print(", PWM ");    Serial.println(stand);  }}

Een test tegen een gesimuleerde dag geeft bij 3000 lux daglicht de waarde 185: de ADC rondt de LDR-spanning af, zodat het programma 2983 lux ziet (voorbeeld hierboven: 184). In het donker loopt de waarde in 51 s op van 0 naar 255. constrain houdt de fractie tussen 0 en 1: bij meer dan 10 800 lux zou ze negatief worden. De energiebeheerregels van hoofdstuk 20 voeg je toe in opdracht 25.13.

Code · 25.17

Python: bits, ADC en aliasing narekenen

17/19

Drie kleine functies vatten het hoofdstuk samen: omzetten naar binair door te delen door 2, een ADC die naar beneden afrondt en nooit boven 1023 gaat, en de schijnbare frequentie na bemonsteren.

Pythonbits.py33 regelsDownload
# bits.py - binair, hexadecimaal, de ADC en bemonsteren in een paar functies  def naar_binair(getal, bits=8):    """Deel telkens door 2: de resten zijn de bits, van achter naar voor."""    resten = []    for _ in range(bits):        resten.append(getal % 2)        getal = getal // 2    return "".join(str(b) for b in reversed(resten))  def adc(u, u_ref=5.0, bits=10):    """Zoals de ADC: 2**bits niveaus, naar beneden afgerond, nooit meer dan het hoogste niveau."""    return min(int(u / u_ref * 2 ** bits), 2 ** bits - 1)  def schijnbaar(f, fs):    """Schijnbare frequentie na bemonsteren met fs: de afstand tot het dichtste veelvoud van fs."""    k = round(f / fs)    return abs(f - k * fs)  for g in (5, 182, 200, 255):    print(f"{g:4d} = {naar_binair(g)} = 0x{g:02X}")print(f"1023 = {naar_binair(1023, 10)} = 0x{1023:X}") for u in (0.75, 1.25, 3.20, 4.999, 6.0):    n = adc(u)    print(f"U = {u:5.3f} V  ->  N = {n:4d} = {naar_binair(n, 10)}") for f in (0.2, 9.0, 11.0, 50.0):    print(f"{f:4.1f} Hz, 10 keer per seconde gemeten: lijkt {schijnbaar(f, 10.0):.1f} Hz")

Uitvoer (gedraaid bij het bouwen van deze pagina):

   5 = 00000101 = 0x05
 182 = 10110110 = 0xB6
 200 = 11001000 = 0xC8
 255 = 11111111 = 0xFF
1023 = 1111111111 = 0x3FF
U = 0.750 V  ->  N =  153 = 0010011001
U = 1.250 V  ->  N =  256 = 0100000000
U = 3.200 V  ->  N =  655 = 1010001111
U = 4.999 V  ->  N = 1023 = 1111111111
U = 6.000 V  ->  N = 1023 = 1111111111
 0.2 Hz, 10 keer per seconde gemeten: lijkt 0.2 Hz
 9.0 Hz, 10 keer per seconde gemeten: lijkt 1.0 Hz
11.0 Hz, 10 keer per seconde gemeten: lijkt 1.0 Hz
50.0 Hz, 10 keer per seconde gemeten: lijkt 0.0 Hz

Let op 6,0 V: dat is meer dan de referentie, en de ADC blijft op 1023 staan (in het echt mag een pin nooit boven 5 V komen). En 50 Hz, gemeten met 10 Hz, lijkt 0 Hz: een constante. Wie de netbrom meet met een veelvoud van 50 Hz, ziet ze niet.

Naslag · 25.18

Overzicht: van analoog naar digitaal en terug

18/19
n bits
symboolbetekeniseenheid
aantal bits–
ADC
symboolbetekeniseenheid
ADC-waarde–
referentiespanning (5 V, 1,1 V …)V
resolutie
symboolbetekeniseenheid
10 bit, 5 V: 4,88 mVV
bemonsteren (Nyquist, intuïtief)
symboolbetekeniseenheid
bemonsteringsfrequentieHz
snelste verandering in het signaalHz
PWM
symboolbetekeniseenheid
duty cycle–
periode (490 Hz: 2,04 ms)s
bits12348101216
niveaus 248162561024409665 536
grootste getal137152551023409565 535
decimaal0123456789101112131415
binair0000000100100011010001010110011110001001101010111100110111101111
hex0123456789ABCDEF
bordPWM-pinnenfrequentie
Uno (meetkas)3, 5, 6, 9, 10, 11490 Hz; pin 5 en 6: 980 Hz
Mega (klimaatmodule)2 tot 13 en 44 tot 46490 Hz; pin 4 en 13: 980 Hz
Arduinobereikbetekenis
analogRead(A0)0-102310 bit; 104 µs per meting
analogReference(INTERNAL)Uno: referentie ±1,1 V (Mega: INTERNAL1V1, INTERNAL2V56)
analogWrite(9, v)0-2558 bit PWM, op de 490 Hz-pinnen
int / unsigned long16 / 32 bit−32 768 tot 32 767 / 0 tot 4 294 967 295
Het geheel · 25.19

Waar analoog en digitaal elkaar raken

19/19

Dit hoofdstuk is de brug tussen de elektronica (spanningen, stromen, transistors) en het programmeren (getallen, bits, lussen). Het verbindt ook de wiskunde: machten van 2, afronden, en de periode en frequentie van een signaal, die in Expert terugkomen als sinussen en Fourier.

Digitale pinnen: hoog of laag.

analogRead en de eerste sensoren; de TMP36 van de meetkas.

Resolutie is niet hetzelfde als nauwkeurigheid.

De ADC-omrekening en de LDR die hier de lampen stuurt.

De MOSFET die met PWM schakelt, en de snelle vrijloopdiode.

Het RC-filter dat PWM gladstrijkt, en de sample-and-hold-condensator.

PWM voor het toerental van een motor; servo's met pulsen van 1 tot 2 ms.

analogRead, analogWrite, int en unsigned long in C++.

Hoeveel data de logger maakt, en hoe vaak hij meet.

Nyquist en aliasing precies; frequenties in een signaal.

Bits worden poorten, flipflops en tellers.

PWM op hoge frequentie in omzetters en motorsturingen.

HabitatDe groeilampen hangen nu via één IRLZ44N op een koelplaat aan D5 van de Mega (490 Hz), met een zekering van 20 A. Ze vullen het daglicht aan tot 200 µmol/(m²·s) op het kweekbed. Op een bewolkte lentedag kost dat 1,88 kWh in plaats van 3,04 kWh. De batterijstroom op A4 wordt voortaan gemiddeld over tien PWM-perioden (100 metingen in 20,4 ms).
Samenvatting

In het kort

Begrippen

Wat je nu kent

bit
Kleinste eenheid van informatie: 0 of 1. Met bits schrijf je verschillende waarden.
byte
Groep van 8 bits: 256 waarden, van 0 tot 255.
binair talstelsel
Talstelsel met grondtal 2: elke plaats is twee keer zoveel waard als de plaats rechts ervan.
hexadecimaal
Talstelsel met grondtal 16 (cijfers 0-9 en A-F); één hexadecimaal cijfer is vier bits.
resolutie (van een ADC)
De kleinste spanningsverandering die een ADC kan onderscheiden: , bij 10 bit en 5 V 4,88 mV.
bemonsteringsfrequentie
Hoeveel metingen per seconde een digitaal systeem van een signaal neemt.
aliasing
Een signaal dat te traag bemonsterd wordt, lijkt een ander, trager signaal.
PWM
Pulsbreedtemodulatie: een digitale uitgang die snel aan en uit gaat, zodat het gemiddelde tussen 0 en de volle spanning ligt.
duty cycle
Het deel van de periode waarin een PWM-signaal hoog is, in procent.
DAC
Digitaal-analoogomzetter: maakt van een getal een spanning.
Aan de slag in het werkboek16 opdrachten, van oefenen tot uitdagen