Physical computing/Analoge uitvoer (PWM): verschil tussen versies

Uit Lab
Naar navigatie springen Naar zoeken springen
 
(10 tussenliggende versies door dezelfde gebruiker niet weergegeven)
Regel 1: Regel 1:
{{Zijbalk Physical Computing}}
{{Zijbalk Physical computing}}
== PWM: pulsbreedte-modulatie ==
== PWM: pulsbreedte-modulatie ==
De microbit en de Arduino Uno hebben geen echte analoge uitgang met een Digitaal/Analoog-omzetter.
De microbit en de Arduino Uno hebben geen echte analoge uitgang op basis van een Digitaal/Analoog-omzetter.
Voor het regelen van de snelheid van een motor of de lichtsterkte van een LED kun je een veel eenvoudiger systeem gebruiken: pulsbreedte-modulatie (PWM, pulse width modulation). Een PWM-signaal is een periodiek digitaal signaal waarvan de verhouding tussen "aan" en "uit" tijd (de duty cycle) instelbaar is. Door dit signaal te middelen over een langere periode krijg je een analoog niveau.
Voor het regelen van de snelheid van een motor of de lichtsterkte van een LED gebruik je een eenvoudiger systeem: pulsbreedte-modulatie (PWM, pulse width modulation). Een PWM-signaal is een periodiek digitaal signaal waarvan de verhouding tussen "1" en "0" tijd (de duty cycle) instelbaar is. Door dit signaal te middelen over een langere periode krijg je een analoog niveau.
 
=== Periodiek signaal ===
 
Een periodiek signaal is een signaal dat zichzelf steeds herhaalt: <code>s(t) = s(t + k*Tp), met k=0, 1, 2, ... </code> De duur van het deel dat herhaald word, Tp, heet de ''periode''. De frequentie f = 1/Tp . Voorbeelden van periodieke signalen: sinus, blokgolf, zaagtand, enz. Een periodiek signaal hoeft niet symmetrisch te zijn: het kan een willekeurige vorm aannemen. Een voorbeeld daarvan is de hartslag: dit is (als de hartslag constant is) een periodiek signaal.


=== Pulsbreedte-modulatie ===
=== Pulsbreedte-modulatie ===
Je kun een digitale uitgang aan- en uitzetten: dit komt dan overeen met een spanning van 3V of 0V (bij de microbit). Als je dit met een vaste regelmaat doet, krijg je een ''periodiek signaal''. Een voorbeeld daarvan is het knipperen van de LED, zoals we gezien hebben in de Blink-sketch:
Je kun een digitale uitgang de waarde 0 of 1 geven: dit komt bij de microbit overeen met een spanning van 3V of 0V. Als je dit met een vaste regelmaat doet, krijg je een ''periodiek signaal''. Een voorbeeld daarvan is het knipperen van de LED, zoals we gezien hebben in het Blink-programma:
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
from microbit import *
from microbit import *
Regel 16: Regel 20:
}
}
</syntaxhighlight>
</syntaxhighlight>
[[Bestand:PWM-fig-6.png|thumb|right|300px|Blokgolf met verschillende frequenties en duty-cycles]]
[[Bestand:PWM-fig-6.png|thumb|right|300px|Blokgolf met verschillende frequenties en duty-cycles]]
Het overeenkomstige signaal zien we in de figuur hiernaast. Dit is een ''blokgolf'' met een periode van 2000 msec, wat overeenkomt met een frequentie van 0,5 Hz (een halve periode per seconde). We kunnen deze blokgolf, en daarmee het knipperen van de LED, op twee manieren aanpassen:
 
* we kunnen de periode, dat wil zeggen de combinatie  van de aan- en uit-periode, veranderen;
Het overeenkomstige signaal zie je in de figuur hiernaast. Dit is een ''blokgolf'' met een periode van 2000 msec, wat overeenkomt met een frequentie van 0,5 Hz (een halve periode per seconde). Je kunt deze blokgolf, en daarmee het knipperen van de LED, op twee manieren aanpassen:
** als we beide delay's veranderen in 100 msec, hebben we een frequentie van 5Hz.
 
* we kunnen de verhouding tussen de aan- en uitperiode veranderen.
* pas de frequentie aan, ofwel de periode aan: de combinatie  van het aan- en uit-gedeelte;
De dutycycle van een dergelijk signaal is de verhouding tussen de aan-periode en de totale periode. Deze verhouding drukken we meestal uit als percentage. In het voorbeeld hierboven is de dutycycle 50%.
** als je beide "sleep"-tijden verandert in 100 msec, krijg je een frequentie van 5Hz.
* als we de LED 150 msec aanzetten, en 50 msec uit, dan is de dutycycle 75% (de totale periode is 200 msec, de frquentie is 5 Hz).
* pas de duty cycle aan, ofwel het gedeelte van een periode dat het signaal "aan" of "hoog" is.
* als we de LED 50 msec aanzetten, en 150 msec uit, dan is de dutycycle 25% (de frequentie is 5 Hz).
** als de LED 150 msec aan is, en 50 msec uit, dan is de dutycycle 150/(150+50) * 100% = 75% (de periode is 200 msec, de frequentie is 5 Hz).
** als de LED 50 msec aan is, en 150 msec uit, dan is de dutycycle 50/(50+150) * 100% = 25% (de frequentie is 5 Hz).


=== Van PWM naar analoog niveau ===
=== Van PWM naar analoog niveau ===
We kunnen een dergelijk pulsbreedte-signaal omzetten in een analoog niveau, door het gemiddelde te nemen van dit signaal over een langere periode.
* als we de LED voldoende snel laten knipperen, dan verzorgt ons oog automatische deze middeling. Het lichtniveau dat we waarnemen is dan evenredig met de dutycycle van het signaal. Dit is het principe van vrijwel alle licht-dimmers.
* soms helpt een bepaald "traag" natuurkundig verschijnsel hierbij. Een voorbeeld is een gloeilamp: deze heeft tijd nodig om aan- en uit te schakelen. Dit betekent dat je een gloeilamp bij een frequentie van 50Hz niet meer ziet knipperen.
* in andere gevallen kunnen we een zogenaamd laagdoorlaatfilter gebruiken, bijvoorbeeld in de vorm van een weerstand en een condensator.


Je kunt dit vergelijken met een vijver met een vaste afvoer waarin regenwater opgevangen wordt: de vijver vangt de pieken door de regenbuien op, en voert een veel constantere stroom water af naar de benedenloop. Een ander voorbeeld van een laagdoorlaatfilter is een schokdemper: de snelle schokken worden gedempt door een combinatie van een buffer (veer) en een weerstand (vloeistof-weerstand).
Het gemiddelde van een PWM-signaal over een langere periode geeft een analoog niveau. Dit middelen kan op verschillende manieren:
 
* door een "traag" natuurkundig verschijnsel. Een voorbeeld hiervan is een motor: de massa van het draaiende deel geeft een vliegwiel-effect. Als je de duty cycle groter maakt, krijgt de motor meer vermogen (energie/tijd), en zal deze sneller draaien.
* door een "traag" biologisch verschijnsel. Als je een LED snel laat knipperen (100 Hz of meer), dan zorgt je oog voor de middeling: je ziet een continu brandende LED. Het lichtniveau dat je waarneemt is dan evenredig met de duty cycle van het signaal. Dit is het principe van vrijwel alle lichtdimmers. (Ook film en TV maken gebruik van de traagheid van ons oog.)


* http://arduino.cc/en/Tutorial/PWM
* http://arduino.cc/en/Tutorial/PWM
Regel 38: Regel 43:


== Analoge uitvoer: PWM ==
== Analoge uitvoer: PWM ==
=== microbit: micropython ===
* https://microbit-micropython.readthedocs.io/en/v2-docs/pin.html
De functie-aanroep <code>pinx.write_analog(d)</code> schrijft een PWM-signaal naar pin <code>pinx</code>, waarbij <code>d</code> de duty-cycle aangeeft, in het bereik 0..1023 voor 0..100%. Voorbeeld: d=255 geeft een duty-cycle van 25%, d=511: 50%, en d=766: 75%.
==== voorbeeld: dimmer ====
Omdat het bereik van een analoge input ook 0..1023 is, hoef je bij bij kopiëren van een analoge input naar een analoge output niet te her-schalen.
Het volgende programma kopieert de analoge input van pin0 (bijvoorbeeld van een potmeter) naar de analoge output op pin1 (bijvoorbeeld een LED).
<syntaxhighlight lang="python">
from microbit import *
while True:
    x = pin0.read_analog()
    pin1.write_analog(x)
    sleep(10)
</syntaxhighlight>
* De microbit kan voor maximaal 3 output-pinnen tegelijk een PWM-signaal genereren.
* Met de functie <code>pin.set_analog_period(period)</code> kun je de periode (in ms) van het PWM-signaal voor die pin aanpassen.
=== Arduino ===
We kunnen in een Arduino-sketch aangeven dat we een pin als analoge uitvoer willen gebruiken. Dit betekent dat deze uitgang een PWM-signaal met een bepaalde frequentie en een bepaalde duty-cycle te zien geeft. De (byte-)waarde die we wegschrijven naar deze pin geeft de duty-cycle aan: 0 staat voor 0%, 255 staat voor 100%.. De frequentie van dit PWM-signaal kunnen we ook instellen, door het programmeren van de timers. (Dit bespreken we verderop.)
We kunnen in een Arduino-sketch aangeven dat we een pin als analoge uitvoer willen gebruiken. Dit betekent dat deze uitgang een PWM-signaal met een bepaalde frequentie en een bepaalde duty-cycle te zien geeft. De (byte-)waarde die we wegschrijven naar deze pin geeft de duty-cycle aan: 0 staat voor 0%, 255 staat voor 100%.. De frequentie van dit PWM-signaal kunnen we ook instellen, door het programmeren van de timers. (Dit bespreken we verderop.)


Regel 75: Regel 107:
}
}
</syntaxhighlight>
</syntaxhighlight>
== microbit ==

Huidige versie van 3 jun 2021 om 08:02

Physical computing
Arduino Basis
  1. Led-0: breadboard, LED, weerstand
  2. Blink-1
  3. Button-1
  4. Blink-freq: frequentie
  5. Blink-PWM: pulsbreedte-modulatie
  6. Analoge input

PWM: pulsbreedte-modulatie

De microbit en de Arduino Uno hebben geen echte analoge uitgang op basis van een Digitaal/Analoog-omzetter. Voor het regelen van de snelheid van een motor of de lichtsterkte van een LED gebruik je een eenvoudiger systeem: pulsbreedte-modulatie (PWM, pulse width modulation). Een PWM-signaal is een periodiek digitaal signaal waarvan de verhouding tussen "1" en "0" tijd (de duty cycle) instelbaar is. Door dit signaal te middelen over een langere periode krijg je een analoog niveau.

Periodiek signaal

Een periodiek signaal is een signaal dat zichzelf steeds herhaalt: s(t) = s(t + k*Tp), met k=0, 1, 2, ... De duur van het deel dat herhaald word, Tp, heet de periode. De frequentie f = 1/Tp . Voorbeelden van periodieke signalen: sinus, blokgolf, zaagtand, enz. Een periodiek signaal hoeft niet symmetrisch te zijn: het kan een willekeurige vorm aannemen. Een voorbeeld daarvan is de hartslag: dit is (als de hartslag constant is) een periodiek signaal.

Pulsbreedte-modulatie

Je kun een digitale uitgang de waarde 0 of 1 geven: dit komt bij de microbit overeen met een spanning van 3V of 0V. Als je dit met een vaste regelmaat doet, krijg je een periodiek signaal. Een voorbeeld daarvan is het knipperen van de LED, zoals we gezien hebben in het Blink-programma:

from microbit import *

while True:
    pin0.digitalWrite(1)
    sleep(1000)              # wait 1000 msec
    pin0.digitalWrite(0)
    sleep(1000)
}
Blokgolf met verschillende frequenties en duty-cycles

Het overeenkomstige signaal zie je in de figuur hiernaast. Dit is een blokgolf met een periode van 2000 msec, wat overeenkomt met een frequentie van 0,5 Hz (een halve periode per seconde). Je kunt deze blokgolf, en daarmee het knipperen van de LED, op twee manieren aanpassen:

  • pas de frequentie aan, ofwel de periode aan: de combinatie van het aan- en uit-gedeelte;
    • als je beide "sleep"-tijden verandert in 100 msec, krijg je een frequentie van 5Hz.
  • pas de duty cycle aan, ofwel het gedeelte van een periode dat het signaal "aan" of "hoog" is.
    • als de LED 150 msec aan is, en 50 msec uit, dan is de dutycycle 150/(150+50) * 100% = 75% (de periode is 200 msec, de frequentie is 5 Hz).
    • als de LED 50 msec aan is, en 150 msec uit, dan is de dutycycle 50/(50+150) * 100% = 25% (de frequentie is 5 Hz).

Van PWM naar analoog niveau

Het gemiddelde van een PWM-signaal over een langere periode geeft een analoog niveau. Dit middelen kan op verschillende manieren:

  • door een "traag" natuurkundig verschijnsel. Een voorbeeld hiervan is een motor: de massa van het draaiende deel geeft een vliegwiel-effect. Als je de duty cycle groter maakt, krijgt de motor meer vermogen (energie/tijd), en zal deze sneller draaien.
  • door een "traag" biologisch verschijnsel. Als je een LED snel laat knipperen (100 Hz of meer), dan zorgt je oog voor de middeling: je ziet een continu brandende LED. Het lichtniveau dat je waarneemt is dan evenredig met de duty cycle van het signaal. Dit is het principe van vrijwel alle lichtdimmers. (Ook film en TV maken gebruik van de traagheid van ons oog.)

Analoge uitvoer: PWM

microbit: micropython

De functie-aanroep pinx.write_analog(d) schrijft een PWM-signaal naar pin pinx, waarbij d de duty-cycle aangeeft, in het bereik 0..1023 voor 0..100%. Voorbeeld: d=255 geeft een duty-cycle van 25%, d=511: 50%, en d=766: 75%.

voorbeeld: dimmer

Omdat het bereik van een analoge input ook 0..1023 is, hoef je bij bij kopiëren van een analoge input naar een analoge output niet te her-schalen. Het volgende programma kopieert de analoge input van pin0 (bijvoorbeeld van een potmeter) naar de analoge output op pin1 (bijvoorbeeld een LED).

from microbit import *

while True:
    x = pin0.read_analog()
    pin1.write_analog(x)
    sleep(10)
  • De microbit kan voor maximaal 3 output-pinnen tegelijk een PWM-signaal genereren.
  • Met de functie pin.set_analog_period(period) kun je de periode (in ms) van het PWM-signaal voor die pin aanpassen.

Arduino

We kunnen in een Arduino-sketch aangeven dat we een pin als analoge uitvoer willen gebruiken. Dit betekent dat deze uitgang een PWM-signaal met een bepaalde frequentie en een bepaalde duty-cycle te zien geeft. De (byte-)waarde die we wegschrijven naar deze pin geeft de duty-cycle aan: 0 staat voor 0%, 255 staat voor 100%.. De frequentie van dit PWM-signaal kunnen we ook instellen, door het programmeren van de timers. (Dit bespreken we verderop.)

Deze analoge uitvoer is (voor de Arduino Uno) beschikbaar op de pinnen 3, 5, 6, 9, 10, en 11. De frequentie van het PWM-signaal is ongeveer 490 Hz. De werkelijke duty-cycle van de pinnen 5 en 6 is iets groter dan de opgegeven waarde, doordat dezelfde timer gebruikt wordt voor de delay en millis-functies.

Setup

  pinMode(analogLedPin, OUTPUT);

(Ik begrijp dat dit niet strikt nodig is.)

Besturing (loop)

  analogWrite(analogLedPin, level);

Voorbeeld: dimmer

Dimmer

Dit voorbeeld-programma is een dimmer waarbij het niveau ingesteld wordt door een spanning op pin XX, door middel van een potmeter (variabele weerstand). Dit niveau wordt uitgelezen, en omgezet in een waarde voor de duty-cycle van een LED. De waarde die van de analoge ingang gelezen wordt ligt tussen 0 en 1023; de waarde voor de analoge uitgang moet liggen tussen 0 en 255. Dit bereiken we door de ingelezen waarde door 4 te delen.

N.B. we kunnen de PWM-dimmer in software realiseren, zonder de PWM-hardwareondersteuning van de Atmega.

const ledPin = 9;     // LED connected to digital pin 9
const inputPin = 3;   // potentiometer connected to analog pin 3

void setup () {
  pinMode(inputPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

void loop () {
  int inLevel;
  inLevel = analogRead(inputPin);
  analogWrite(ledPin, inLevel / 4);
}

microbit