Les 5
Knoppen en sensoren
Digitale ingangen uitlezen: een knop met een interne pull-up, contactdender opvangen en een digitale sensor zoals een PIR-bewegingsmelder gebruiken.
๐ฏ Na deze les kun je
- een pin als ingang instellen en uitlezen
- uitleggen waarom een ingang een pull-up of pull-down nodig heeft
- contactdender herkennen en opvangen
- een digitale sensor (PIR-bewegingsmelder) uitlezen
Een LED aansturen is uitvoer. Nu de andere kant op: de chip laten meten of er iets gebeurt. De eenvoudigste ingang is een drukknop; daarna een bewegingsmelder die precies hetzelfde signaal geeft: hoog of laag.
Een pin als ingang
from machine import Pin
knop = Pin(14, Pin.IN, Pin.PULL_UP)
print(knop.value()) # 1 = niet ingedrukt, 0 = ingedrukt
Waarom een pull-up?
Een ingang zonder iets erop aangesloten "zweeft": hij vangt storing op en leest willekeurig 0 of 1. Daarom trek je hem met een weerstand naar een vaste waarde:
3,3 V
โ
[pull-up, intern ~50 kฮฉ]
โ
GP14 โโโโโโโ
โ knop
GND โโโโโโโโ
- Knop los: de pull-up trekt de pin naar 3,3 V โ
1. - Knop ingedrukt: de pin is direct met GND verbonden โ
0.
Dat "ingedrukt = 0" heet actief laag. Het voelt omgekeerd, maar het is de meest gebruikte schakeling, omdat de knop alleen naar GND hoeft en de interne pull-up gratis is. Pin.PULL_DOWN bestaat ook (knop naar 3,3 V, ingedrukt = 1), maar de ESP32 heeft op sommige pinnen geen interne pull-down, en pinnen 34โ39 van de ESP32 hebben helemaal geen interne weerstanden.
Om de rest van je code leesbaar te houden:
def ingedrukt():
return knop.value() == 0
Knop schakelt LED
from machine import Pin
import time
knop = Pin(14, Pin.IN, Pin.PULL_UP)
led = Pin(15, Pin.OUT)
while True:
led.value(knop.value() == 0) # LED aan zolang de knop ingedrukt is
time.sleep_ms(10)
Contactdender
Nu wil je dat elke druk de LED omschakelt. Een eerste poging: kijk of de knop net is ingedrukt (hij was 1 en is nu 0).
vorige = 1
while True:
nu = knop.value()
if vorige == 1 and nu == 0:
led.toggle()
vorige = nu
Probeer het: soms schakelt de LED twee of drie keer per druk. Oorzaak: contactdender (bounce). De metalen contacten in de knop stuiteren een paar milliseconden, en de chip is zo snel dat hij elke stuiter als een aparte druk ziet:
ingedrukt: 1 1 1 0 1 0 0 1 0 0 0 0 0 0 0
โ 1โ10 ms dender โ
De eenvoudigste oplossing: na een gedetecteerde verandering even wachten, en dan pas weer kijken.
from machine import Pin
import time
knop = Pin(14, Pin.IN, Pin.PULL_UP)
led = Pin(15, Pin.OUT)
vorige = 1
while True:
nu = knop.value()
if vorige == 1 and nu == 0:
led.toggle()
time.sleep_ms(30) # dender laten uitsterven
vorige = nu
time.sleep_ms(5)
Een nettere manier zonder blokkerend wachten zie je in les 8 en 14.
Een digitale sensor: PIR
Een PIR-sensor (bijvoorbeeld de HC-SR501) meet infraroodstraling van warme lichamen en geeft een digitaal signaal: hoog zolang er beweging is gezien. Gebruik een versie die 3,3 V als uitgang geeft (de HC-SR501 doet dat, ook al voed je hem met 5 V; controleer het voor jouw module).
from machine import Pin
import time
pir = Pin(16, Pin.IN) # de sensor stuurt zelf actief hoog of laag
led = Pin(15, Pin.OUT)
while True:
if pir.value():
led.on()
print("beweging!")
else:
led.off()
time.sleep_ms(200)
Geen pull-up nodig: de sensor maakt de pin zelf hoog of laag. Een PIR heeft na het aanzetten zo'n 30 tot 60 seconden nodig om te stabiliseren; in die tijd geeft hij soms valse meldingen.
Andere sensoren met een digitaal aan/uit-signaal: een reed-contact (magneet bij een deur), een kantelschakelaar, een vochtigheidssensor met drempelmodule.
Typische fouten
- Ingang zonder pull-up en een knop naar GND: willekeurige waardes als de knop los is.
- Verwachten dat ingedrukt 1 is bij een pull-up-schakeling.
- Knop dubbel geteld door dender.
- Een 5V-sensoruitgang rechtstreeks op de pin (les 4).
Oefeningen
- Waarom leest een pin met pull-up
1als de knop niet is ingedrukt? - Schrijf een programma dat telt hoe vaak de knop is ingedrukt en de teller print.
- Laat de LED na een bewegingsmelding nog 5 seconden aan blijven, ook als de PIR alweer laag is.
Modelantwoord
- De pull-up-weerstand verbindt de pin met 3,3 V. Zolang de knop open is, loopt er (vrijwel) geen stroom en staat er dus 3,3 V op de pin.
-
teller = 0 vorige = 1 while True: nu = knop.value() if vorige == 1 and nu == 0: teller += 1 print(teller) time.sleep_ms(30) vorige = nu time.sleep_ms(5) -
laatste = None while True: if pir.value(): laatste = time.ticks_ms() aan = laatste is not None and time.ticks_diff(time.ticks_ms(), laatste) < 5000 led.value(aan) time.sleep_ms(100)time.ticks_ms()enticks_diffzijn de juiste manier om tijd te meten op MicroPython; ze gaan goed om met het overlopen van de teller.
Lab: knop schakelt LED en bewegingsmelder
- Elke druk op de knop (GP14, naar GND) schakelt de LED op GP15 om, zonder dubbeltellingen.
- Een PIR op GP16 zet een tweede LED (GP17) aan, die nog 3 seconden na de laatste beweging blijft branden.
beetje check micropython-les05simuleert knopdrukken met dender en bewegingen.
Samenvatting
Pin(n, Pin.IN, Pin.PULL_UP): ingang met interne pull-up; ingedrukt = 0.- Een zwevende ingang geeft willekeurige waarden.
- Contactdender: een knop stuitert enkele milliseconden; wacht even na een verandering.
- Digitale sensoren geven zelf hoog/laag; meet tijd met
ticks_msenticks_diff.
Volgende les: sensoren die geen 0 of 1 geven, maar een waarde ertussen.
Lab
Knop schakelt LED en bewegingsmelder
๐ป Dit lab doe je op je eigen computer met Docker. Start de lab-container met (geeft de opdracht een eigen startcommando, gebruik dan dat):
$ docker run -it --rm registry.wizg.it/webhosting/beetje-labs:micropython-les5
Klaar? Controleer je werk met:
$ beetje check micropython-les5
๐ Quiz: knoppen en sensoren
Dit was de laatste gratis les
Je hebt les 1โ5 van Een beetje MicroPython gratis gevolgd. Wil je verder? Met รฉรฉn aankoop (€ 24,00, eenmalig) krijg je de overige 15 lessen, de live labs en het certificaat. Geen abonnement.