Skip to main content

2.1 Brojač pritisaka tipke

Do sada je pločica samo govorila. U ovom primjeru počinje slušati: čitat ćeš tipku pomoću Soldered NULA MINI pločice i brojati koliko je puta pritisnuta, ispisujući tekući ukupan broj u konzolu.

U ovoj dokumentaciji naučit ćeš:

  • Kako spojiti tipku bez dodatnih komponenti, koristeći otpornik ugrađen u čip
  • Kako konfigurirati pin kao ulaz pomoću Pin.IN i Pin.PULL_UP
  • Kako pročitati taj pin pomoću value()
  • Zašto pritisnuta tipka daje 0, a ne 1

Potreban hardver:

  • 1x Soldered NULA MINI pločica
  • 1x Breadboard
  • 1x Tipka
  • 2x Jumper žice
  • 1x USB-C kabel
ℹ️
Za ovaj primjer nije potreban otpornik. Tipke na ovoj pločici koriste otpornik ugrađen u sam čip, koji se uključuje u kodu. Sve što ti treba je tipka i dvije žice.

Spajanje komponenti

Prati pet koraka ispod. Svaka fotografija snimljena je s istog položaja, pa je možeš usporediti s prethodnom i vidjeti točno što se promijenilo.

1. Umetni NULA MINI pločicu na breadboard

ℹ️
Ovaj korak pretpostavlja da znaš kako je breadboard spojen iznutra i što su njegove naponske vodilice (power rails). Za uvod pogledaj stranicu dokumentacije Osnove breadboarda.

Utisni pločicu u jedan kraj breadboarda tako da njezina dva reda pinova sjednu s obje strane središnjeg kanala, s čipom okrenutim prema dolje. Pritisni je ravnomjerno dok svi pinovi ne sjednu.

NULA MINI pločica postavljena na breadboard
Korak 1: pločica postavljena na breadboard

Odvoji trenutak da nađeš dva pina koja ovaj primjer koristi. Imena pinova ispisana su duž oba ruba pločice, a svaki pin sjedi u svom numeriranom redu. Na fotografiji iznad pločica zauzima redove 25 do 30, što stavlja IO19 u red 27 i GND u red 30.

ℹ️
Tvoja pločica može sjediti u drugim redovima od one na fotografiji. Važno je u koji red sleti koji pin. Čitaj imena ispisana na pločici, a ne prepisuj brojeve.

2. Postavi tipku

Utisni tipku u sredinu breadboarda tako da premosti središnji kanal, nekoliko redova dalje od pločice. Na fotografiji su njezine nožice u redovima 15 i 17.

Tipka postavljena preko središnjeg kanala
Korak 2: tipka premošćuje središnji kanal
⚠️
Tipka ima četiri nožice, ali samo dvije su važne. Dvije nožice na istoj strani tipke trajno su spojene unutar nje. Pritisak tipke spaja jednu stranu s drugom. Zato uvijek koristi jednu nožicu s obje strane središnjeg kanala, jednu u pojasu a–e i jednu u pojasu f–j. Ako uzmeš obje žice s iste strane, te dvije su već spojene i pločica će se ponašati kao da je tipka zauvijek pritisnuta.

3. Spoji GND na tipku

Masa ide u dva skoka, koristeći plavu vodilicu duž ruba breadboarda kao dijeljenu liniju mase.

  • Prva jumper žica: iz reda u kojem je GND (red 30 na fotografiji) do plave vodilice.
  • Druga jumper žica: s te iste plave vodilice natrag u red 15, na f–j strani tipke.
Dvije jumper žice spajaju GND na tipku preko negativne vodilice
Korak 3: GND dolazi do tipke preko plave − vodilice
ℹ️
Obje žice moraju ići u isti stupac vodilice, onaj koji ide uz plavu liniju. Vodilica uz crvenu liniju je zaseban pojas i nije spojena s njom.

4. Spoji IO19 na tipku

Sada signalna žica. Povuci jednu jumper žicu iz reda u kojem je IO19 (red 27 na fotografiji) u red 17, na a–e strani tipke.

Jumper žica spaja IO19 na lijevu stranu tipke
Korak 4: IO19 spojen na drugu stranu tipke

Primijeti da dvije žice dolaze do tipke s suprotnih strana: red 15 na f–j strani, red 17 na a–e strani. To je dijagonalni par opisan iznad, i to je ono što tipku čini stvarnim prekidačem.

5. Spoji pločicu na računalo

Priključi USB-C kabel u pločicu. LED-ica napajanja se upali čim pločica dobije struju.

Gotov krug s priključenim USB-C kabelom
Korak 5: gotov krug, napajan preko USB-C

Čitanje ulaza

Izlazni pin je onaj koji pločica pobuđuje; ulazni pin je onaj koji mjeri. U 1.2 Blinkanje LED-ice pin je stvoren s Pin.OUT jer smo u njega pisali. Ovdje želimo obrnuto, pa je pin stvoren s Pin.IN, a value() prijavljuje što nađe, kao 1 (visoko) ili 0 (nisko).

Pin koji nije spojen ni na što je problem: kaže se da lebdi, i skuplja dovoljno električnog šuma iz okoline da sam od sebe skače između visokog i niskog stanja. Pločica bi brojala pritiske koji se nikada nisu dogodili. Pinu treba nešto što ga drži na poznatoj vrijednosti kad tipka ništa ne radi.

Za to služi Pin.PULL_UP. On uključuje otpornik unutar čipa koji nježno veže pin na 3.3 V, pa pin čita 1 dok se ništa drugo ne događa. Posao tipke je samo spojiti taj pin na GND, što nadglasa slabi unutarnji otpornik i povuče pin na 0 V.

btn = Pin(BUTTON_PIN, Pin.IN, Pin.PULL_UP)
ℹ️
Zato pritisnuta tipka daje 0. Pin se drži visoko dok je tipka otpuštena, a čita nisko dok je pritisnuta, obrnuto od onoga što većina ljudi očekuje. Tipka spojena na ovaj način naziva se active low, i to je standardni način spajanja tipke na bilo koji mikrokontroler.
ℹ️
U Arduinu je to posao u dva koraka: ne stvaraš ništa, pa pozoveš pinMode(BUTTON_PIN, INPUT_PULLUP) unutar setup(). MicroPython oboje sklapa u jednu liniju iznad: treći argument funkcije Pin() je ono što uključuje pull-up.

Brojanje pritisaka

Budući da u MicroPythonu nema loop(), pišemo vlastitu beskonačnu petlju i čitamo tipku unutar nje. Kada je vrijednost 0, tipka je pritisnuta, pa brojaču dodajemo jedan i ispisujemo novi ukupan broj.

Operator += je skraćeni zapis za "dodaj onome što je već tu", pa counter += 1 znači isto kao counter = counter + 1.

if reading == 0:
counter += 1
print("Counter:", counter)
ℹ️
Predavanje nekoliko stvari funkciji print() odvojenih zarezima ispisuje ih u jednoj liniji s razmakom između, pa print("Counter:", counter) daje Counter: 4. To te spašava od toga da sam spajaš tekst i broj.

Ostavljeno tako, držanje tipke pritisnutom poslalo bi brojač u vrtoglavi rast, jer bi petlja u svakom prolazu našla tipku još pritisnutu. Zato nakon što izbrojimo pritisak čekamo da se tipka vrati gore prije nego nastavimo:

while btn.value() == 0:
# Čekaj dok se tipka ne otpusti
time.sleep_ms(10)
⚠️
Ta kratka petlja radi više posla nego što izgleda. Metalni kontakti unutar tipke zveckaju dok se zatvaraju, i program koji bi djelovao samo na reading == 0 izbrojao bi jedan pritisak nekoliko puta. Čekanje otpuštanja drži program na mjestu dok se kontakti ne umire i dok tvoj prst ne otiđe s tipke, pa u praksi jedan pritisak daje jedan broj: pet promišljenih pritisaka na pločici korištenoj za ovu stranicu dalo je točno pet linija. Cijena je to što ta petlja blokira: dok je tipka pritisnuta, pločica sjedi u njoj i ne može raditi ništa drugo. 2.2 Debounce tipke je zamjenjuje mjeračem vremena koji nikada ne blokira, a to je ono što programu koji ima još posla stvarno treba.

Kod

# Modul machine sadrži sve što razgovara s hardverom, a Pin upravlja pojedinim pinom.
from machine import Pin
import time

# Ovo je varijabla kojoj predajemo broj pina na koji smo spojili TIPKU.
# NULA pločica ima logiku imenovanja pinova ovako: IO19, gdje je 19 broj koji dajemo varijabli.
BUTTON_PIN = 19

# Ovdje stvaramo naš Pin objekt, koji smo nazvali "btn". Pin.IN govori pločici da ovaj pin treba čitati vrijednost
# umjesto da je piše. Pin.PULL_UP uključuje otpornik unutar čipa koji nježno veže pin na 3.3V,
# pa tipka mora samo spojiti pin na GND i nikakvi dodatni dijelovi na breadboardu nisu potrebni.
btn = Pin(BUTTON_PIN, Pin.IN, Pin.PULL_UP)

# Ova varijabla drži vrijednost našeg brojača.
counter = 0

# Ispiši početnu poruku da znamo da se program uspješno pokrenuo.
print("Button Counter Example started!")
print("Press the button to increase the counter...")

# Petlja while True ponavlja se unedogled, pa se kod unutar nje izvršava dok ne zaustavimo program.
while True:

# value() je funkcija koja čita vrijednost s našeg pina, ili 1 (visoko) ili 0 (nisko).
# Pull-up otpornik drži pin na 3.3V dok je tipka otpuštena, pa čitamo 1, a pritisak tipke
# spaja pin na GND pa čitamo 0. Tipka spojena na ovaj način naziva se active low.
reading = btn.value()

# Ako je tipka pritisnuta, povećaj brojač za jedan i ispiši ga u konzolu.
# Budući da ova verzija ne uključuje debounce, za jedan pritisak može se pojaviti više brojeva.
if reading == 0:
counter += 1
print("Counter:", counter)

# Čekaj da se tipka otpusti prije nego dopustimo novo brojanje.
while btn.value() == 0:
# Čekaj dok se tipka ne otpusti
time.sleep_ms(10)

# time.sleep_ms() pauzira program za zadani broj milisekundi. Vrlo kratka pauza ovdje ostavlja
# procesoru trenutak da obavi svoj posao u pozadini umjesto da svaki ciklus troši na provjeru tipke.
time.sleep_ms(10)
ℹ️
time.sleep_ms(10) čeka deset milisekundi. To je druga funkcija od time.sleep() koju si koristio za blinkanje LED-ice, a koja mjeri u sekundama. time.sleep_ms(10) i time.sleep(0.01) su ista pauza zapisana na dva načina.

Što bi trebao vidjeti

Pritisni Run. Dvije početne poruke pojavljuju se u Shellu odmah, a svaki pritisak dodaje liniju:

Button Counter Example started!
Press the button to increase the counter...
Counter: 1
Counter: 2
Counter: 3
Counter: 4
ℹ️
Svaki pritisak trebao bi dodati točno jednu liniju: pet brojeva iznad došlo je od pet pritisaka. Ako pritiskaš vrlo brzo i brojač skoči za dva, to je odskakivanje kontakta opisano iznad koje se provuklo, a 2.2 Debounce tipke je mjesto gdje se to rješava kako treba.
ℹ️
U Shellu nema ničega? Provjeri je li pločica stvarno spojena i odabrana kao interpreter, pa ponovno pritisni Run. Skripta koja je ostala pokrenuta iz ranijeg primjera drži pločicu zaposlenom dok je ne zaustaviš.

Cijeli primjer

Pogledaj cijeli kod primjera na linku ispod:

2.1_Button_Counter.py

Primjer koji broji koliko je puta tipka pritisnuta i ispisuje ukupan broj u konzolu.