Arduino/Digitale invoer: verschil tussen versies
k (1 versie) |
|||
Regel 132: | Regel 132: | ||
==== Ontdenderen (debouncing) ==== | ==== Ontdenderen (debouncing) ==== | ||
Sommige schakelaars zijn zo goed dat deze nauwelijks dender geven. Als je dit effect wilt illustreren, dan kun je zelf een "schakelaar" maken door twee draden met de hand te verbinden. | Sommige schakelaars zijn zo goed dat deze nauwelijks [http://nl.wikipedia.org/wiki/Denderen dender] geven. Als je dit effect wilt illustreren, dan kun je zelf een "schakelaar" maken door twee draden met de hand te verbinden. | ||
==== Schakelen van een toestand ==== | ==== Schakelen van een toestand ==== |
Huidige versie van 25 mei 2014 om 20:31
Digitale invoer
We kunnen vrijwel elke i/o-pin van de Arduino gebruiken als een digitale invoer. Hiermee kunnen we een "digitale" spanning (0V of 5V) lezen als een digitale waarde (0 of 1).
Software
Setup
In de setup
geven we voor een digitale pin aan dat we deze als invoer gebruiken door middel van:
pinMode(pinNr, INPUT);
Strikt genomen is dit niet nodig, omdat de default-mode van een pin INPUT is. Maar voor de volledigheid is dit wel zo netjes: je ziet dan in de software welke pinnen als (digitale?) input gebruikt worden.
Een alternatieve manier om een pin als digitale input aan te geven is door:
pinMode(pinNr, INPUT_PULLUP);
Hiermee geef je aan dat de interne pull-up weerstand van deze input-pin gebruikt moet worden. Het resultaat is dat het lezen van deze pin in de waarde HIGH (1) resulteert, tenzij een externe schakelaar deze input-pin met GND verbindt: dan wordt de waarde LOW (0) gelezen. (Zie verderop de uitleg van pull-up en pull-down.)
Besturing (loop)
Je kunt de waarde van een invoer-pin uitlezen door middel van een aanroep van digitalRead(pinNr)
, bijvoorbeeld
val = digitalRead(pinNr);
waarin val
een variabele is waarin je het resultaat bewaart voor verdere verwerking. Het resultaat is een waarde LOW (0) bij een spanning van minder dan 1,5 V, en een waarde HIGH (1) bij een spanning van 3V of meer.
Let op: het lezen van de waarde van de pin is een momentopname, waarvan je het resultaat bijvoorbeeld bewaart in een variabele. De waarde van de variabele val
verandert niet automatisch mee als de spanning op de pin verandert: daarvoor moet je dan op een later moment de invoer-pin opnieuw uitlezen.
Elektrisch
Spanning
Een spanning van 0V resulteert in een digitale 0; een spanning van 5V resulteert in een digitale 1.
Deze spanningen zijn ruim gedefinieerd: een spanning lager dan 1,5 V wordt gezien als een 0, een spanning hoger dan 3V wordt gezien als een 1.
Deze spanningen zijn niet absoluut, maar gerelateerd aan de voedingsspanning van de Atmega. Voor een voedingsspanning Vcc groter dan 2,4V is de maximale spanning die als 0 gezien wordt, 0,3*Vcc; de minimale spanning die als 1 gezien wordt, 0,6*Vcc (zie ADS 26.2).
Stroom
Een ingangspoort heeft ook altijd een bepaalde stroom nodig om de juiste waarde te kunnen bepalen. Dit is de lekstroom (Input Leakage Current) van de poort. In het geval van de Atmega is de lekstroom voor zowel een laag als een hoog niveau maximaal 1 uA. (ADS 26.2)
Deze lekstroom speelt bijvoorbeeld een rol bij de keuze van de pull-up of pull-down weerstanden. Bij sommige onderdelen is de lekstroom verschillend voor een hoog of een laag niveau: dat kan betekenen dat voor een pull-up weerstand een andere waarde gekozen moet worden dan voor een pull-down. In het geval van de Atmega is de situatie symmetrisch, en is bovendien de lekstroom erg klein.
Zie:
Standaardschakelingen
Schakelaar als input
Het ligt voor de hand om een schakelaar te gebruiken als digitale invoer. In het geval van Arduino's gebruiken we dan meestal een "momentane schakelaar" (momentary switch): een schakelaar die alleen contact maakt zolang we deze ingedrukt houden. Dit is anders dan bijvoorbeeld een lichtschakelaar zoals je die in huis meestal tegenkomt: deze heeft aparte standen voor "aan" en "uit".
We kunnen met een digitale invoerpin alleen maar een spanning lezen, niet de stand van een schakelaar. Dit betekent dat we de stand van de schakelaar moeten omzetten in een spanning. Dit kan met behulp van een pull-down of een pull-up weerstand.
Schakelaar met pull-down weerstand
In het schema zien we een schakelaar met een pull-down weerstand:
- schakelaar open is: de input-pin van de Arduino is via de pull-down weerstand verbonden met GND (0 V): er staat een spanning van 0V op de pin, die gelezen wordt als LOW;
- schakelaar gesloten (ingedrukt): de input-pin van de Arduino is direct verbonden met 5V: deze spanning wordt gelezen als HIGH.
Met andere woorden: een open schakelaar resulteert in de digitale waarde LOW, en een gesloten schakelaar in de waarde HIGH.
Programma
const ledPin = 13;
const switchPin = 2;
void setup () {
pinMode(ledPin, OUTPUT);
pinMode(switchPin, INPUT);
}
void loop () {
int switchValue;
switchValue = digitalInput(switchPin);
digitalWrite(switchValue); // LED on when switch closed
}
Hoe groot kiezen we de pull-down weerstand?
Welke waarde kiezen we voor de pull-down weerstand? Deze moet aan de volgende eisen voldoen:
- bij een gesloten schakelaar moet de stroom door de weerstand beperkt zijn: anders verliezen we teveel energie, wordt de weerstand (en de rest van de schakeling) mogelijk te warm;
- bij een open schakelaar moet de lekstroom van de input-pin het niveau niet boven de 1,5V laten komen - anders lezen we mogelijk de verkeerde waarde.
In de praktijk van de Arduino gebruiken we vaak een weerstand van 10 kOhm (10.000 Ohm of 10^4 Ohm).
- de stroom door deze weerstand bij gesloten schakelaar is I = 5 (V) / 10.000 (Ohm) = 0,5 mA;
- de lekstroom van de Atmega is erg klein: 1 uA (0,000001 A ofwel 10^-6 A). De spanning over de weerstand is dan U = 10^-6 (A) * 10^4 (Ohm) = 0,01 V.
Vraag: hoe groot zouden we de pull-down weerstand mogen kiezen als we de spanning over de weerstand hoogstens 1 V willen laten worden? Controleer dit met een experiment.
En als je de weerstand weg zou laten?
Je kunt op twee manieren de weerstand weglaten:
- de weerstand vervangen door een draad: direct de invoer-pin verbinden met GND. Bij een open schakelaar levert dit de waarde LOW. Maar bij een gesloten schakelaar resulteert dit in kortsluiting: 5V en GND zijn direct verbonden, en er vloeit een zeer grote en destructieve stroom. (Volgens de wet van Murphy gaan dan de duurste onderdelen kapot. Dit experiment kun je dus beter niet uitvoeren.)
- de weerstand gewoon weglaten. Bij een gesloten schakelaar levert dit de waarde HIGH. Maar bij een open schakelaar resulteert dit in een "zwevende" invoerpin: de waarde daarvan is niet gedefinieerd, bij het uitlezen kan dit in alle mogelijke waarden resulteren.
Schakelaar met pull-up weerstand
Een pull-up weerstand werkt precies omgekeerd:
- schakelaar open: de invoerpin van de Arduino is via de weerstand verbonden met 5V;
- schakelaar gesloten: de invoerpin van de Arduino is direct verbonden met 0V.
Met andere woorden: een open schakelaar resulteert in de waarde HIGH, en een gesloten schakelaar in de waarde LOW.
Programma
const ledPin = 13;
const switchPin = 2;
void setup () {
pinMode(ledPin, OUTPUT);
pinMode(switchPin, INPUT);
}
void loop () {
int switchValue;
switchValue = digitalRead(switchPin);
digitalWrite(switchValue); // led on when switch not pressed.
}
Als we willen dat de LED alleen brandt als de schakelaar ingedrukt is, dan kunnen we daarvoor de <const>digitalWrite</const> als volgt aanpassen:
digitalWrite(1 - switchValue);
Opdracht: ga dit na - in een experiment, en beredeneer het resultaat.
Invoer-pin met interne pull-up
De Atmega microcontroller heeft een interne pull-up weerstand voor elke invoer-pin. Je kunt deze inschakelen door als input-mode INPUT_PULLUP
aan te geven:
pinMode(pinNr, INPUT_PULLUP);
Je hebt dan geen externe weerstand nodig: je verbindt een schakelaar direct tussen de input-pin en GND. Merk op dat bij het gebruik van een pull-up, een open schakelaar resulteert in de waarde HIGH, en een gesloten schakelaar in LOW.
Ontdenderen (debouncing)
Sommige schakelaars zijn zo goed dat deze nauwelijks dender geven. Als je dit effect wilt illustreren, dan kun je zelf een "schakelaar" maken door twee draden met de hand te verbinden.
Schakelen van een toestand
We kunnen een momentane schakelaar ook gebruiken om een LED (of een ander apparaat) aan en uit te schakelen. Eén druk op de knoo schakelt de LED dan aan, de volgende schakelt deze uit.
Een andere techniek is dat we de schakelaar via een soort code gebruiken: eenmaal drukken schakelt de lamp aan, tweemaal drukken schakelt deze uit. We kunnen dit bijvoorbeeld ook gebruiken voor een lamp die we kunnen dimmen: we moeten dan onderscheid maken tussen "feller" en "minder fel", bijvoorbeeld eenmaal drukken en tweemaal drukken. Helemaal uit is dan bijvoorbeeld driemaal achtereen drukken.
Opmerkingen
De uitleg van LOW en HIGH in het Arduino-rerferentie-materiaal is verwarrend.
- LOW is altijd 0, HIGH is altijd 1 - in de software
- de betekenis aan de elektrische kant (hardware) verschilt.