In de eerste voorbeelden leerden we de GPIO-pinnen kennen als uitgangen die we op HIGH zetten om een LED te laten oplichten. Maar GPIO staat voor General Purpose Input/Output. Je kunt de pinnen dus ook als ingangen programmeren. Dan kan worden bepaald of er spanning op de ingang staat (HIGH) of niet (LOW). De Raspberry Pi heeft alleen digitale ingangen (we zullen later een workaround leren kennen voor het meten van analoge spanningen), maar de aangelegde spanning hoeft niet precies 3,3V te zijn om als HOOG herkend te worden en niet 0V om als LAAG herkend te worden. Tot ongeveer 1,4V wordt herkend als LAAG, alles boven 1,9V wordt zeker herkend als HOOG. Alleen het kleine bereik rond ½ van 3,3V en een vrije pin waar niets op is aangesloten zijn problematisch.
We zullen verschillende digitale sensoren leren kennen die een alarm of een bepaalde actie in ons programma moeten triggeren (bijvoorbeeld een bewegingsmelder). De eenvoudigste van deze sensoren is de knop, een verende schakelaar die een circuit sluit wanneer de knop wordt ingedrukt en weer opent wanneer de knop wordt losgelaten.
Als we één contact van de knop verbinden met een GPIO pin en het andere met 3,3V, wordt het signaal HIGH duidelijk gedetecteerd wanneer de knop wordt ingedrukt. Het probleem begint nadat de knop wordt losgelaten. Welke status heeft de GPIO dan? Een ongedefinieerde! Je kunt hier niet mee programmeren. In uitgeschakelde toestand zou de GPIO dus permanent op GND moeten staan. Dit zou echter leiden tot kortsluiting wanneer de knop wordt ingedrukt. Een oplossing is een weerstand die groot genoeg moet zijn zodat er slechts een kleine stroom vloeit. Weerstanden van 4,7 k (=4700 Ohm) of 10 kΩ (=10.000 Ohm) zijn gebruikelijk. Deze weerstanden worden pull-down weerstanden genoemd.
Je kunt de GPIO echter ook zo programmeren dat hij normaal HIGH aangeeft en het indrukken van een toets tegen GND herkent als een verandering naar LOW. Dan wordt de weerstand een pull-up weerstand genoemd. En om het nog verwarrender te maken voor beginners, hebben de Raspberry Pi GPIO's een interne pull-up of pull-down weerstand die in het programma kan worden geactiveerd of gedeactiveerd. Gelukkig maakt dit de eerste schakelingen heel eenvoudig.
Het schakelschema: Drukknop op de Raspberry Pi
De programmacode: Drukknop op de Raspberry Pi
uit gpiozero importeer LED, Knop
uit signaal importeer pauze
led = LED(12)
knop = knop(16)
knop.wanneer_ingedrukt = led.aan
button.when_released = led.off
pauze()
Uit de module gpiozero worden de klassen LED en button geïmporteerd, gescheiden door komma's, waarna de objecten led en button worden geïnstantieerd met de respectievelijke GPIO-nummers.
In plaats van de slaap()-Functie uit de module tijd module, pauze van de module signaal sleep() zou volledige stilstand betekenen, de toetsaanslag zou gedurende die tijd niet worden opgemerkt. Zonder pause() zou het programma stoppen en zou er niets gebeuren.
De instantiëring van de knop was heel eenvoudig omdat we alleen het GPIO-nummer hebben opgegeven en verder de standaardinstellingen hebben gebruikt (zie de class definitie op de volgende regel). Als je hiervan wilt afwijken, moet je verdere parameters invoeren als sleutelwoordargumenten.
klasse gpiozero.Button(pin, *, pull_up=True, active_state=None, bounce_time=None,
hold_time=1, hold_repeat=False, pin_factory=None)
Meer details over gpiozero kunnen worden gevonden hier.
Uitbreiding van de experimentele opstelling: Een stoplichtcyclus moet worden gestart met een Raspberry Pi wanneer er op een knop wordt gedrukt.
De experimentele opstelling is gebaseerd op het eerste voorbeeld. In plaats van een LED wordt het LED stoplicht gebruikt. Deze heeft ingebouwde serieweerstanden. We instantiëren drie LED-objecten en definiëren een functie trafficLight, die wordt aangeroepen wanneer er op een knop wordt gedrukt.
De programmacode: Verkeerslichtcyclus op de Raspberry Pi
van gpiozero importeer LED, Knop
van signaal importeer pauze
uit tijd importeer slaap
roodled = LED(16)
geelled = LED(20)
groenled = LED(21)
knop = knop(12)
def verkeerslicht():
redled.on()
slaap(1)
geelled.aan()
slaap(1)
groenled.aan()
roodled.uit()
geelled.uit()
slaap(1)
geelled.aan()
groenled.uit()
slaap(1)
roodled.aan()
geelled.uit()
slaap(1)
roodled.uit()
knop.wanneer_ingedrukt = verkeerslicht
pauze()
Uitbreiding: Reactiespel met twee knoppen op de Raspberry Pi
Je hebt twee knoppen nodig, een zoemer en een rode en een gele LED. Na het starten van het reactiespel gaat de gele LED als eerste branden. Met tijd = uniform(5, 10) gaat de rode LED branden na een willekeurige tijd tussen vijf en tien seconden. Dan mogen twee spelers elk zo snel mogelijk op hun knop drukken. Als je te snel drukt, word je betrapt op vals spelen en gaat de zoemer een halve seconde af.
De programmacode: Reactiesonde met twee knoppen op de Raspberry Pi
#! /usr/bin/python3
# Reactiespel - druk op knop, wanneer rode LED oplicht
# gebaseerd op gpiozero documentatie, Basis Recepten
# verbeterd om valsspelen te herkennen door Bernd Albrecht
# Rode LED brandt 5 - 10 seconden na de gele LED
uit gpiozero importeer Button, LED, Buzzer
uit tijd importeer slaap
uit random importeer uniform
uit sys importeer exit
led_red = LED(16)
led_geel = LED(20)
zoemer = zoemer(12)
speler_1 = Knop(23)
speler_2 = Knop(18)
led_geel.aan()
tijd = gelijkmatig(5, 10)
slaap(tijd)
als player_1.is_gedrukt:
print("Speler_1 speelt vals!")
zoemer.aan()
slaap(0,5)
zoemer.uit()
led_geel.uit()
afsluiten()
als speler_2.is_ingedrukt:
print("Speler 2 speelt vals!")
zoemer.aan()
slaap(0.5)
zoemer.uit()
led_geel.uit()
afsluiten()
led_rood.aan()
led_geel.uit()
while True:
if player_1.is_pressed:
print("Speler_1 wint!")
break
als player_2.is_gedrukt:
print("Speler 2 wint!")
break
led_red.uit()