3.1 Mjerenje udaljenosti
Cilj ovog primjera je izmjeriti udaljenost ultrazvučnim senzorom iz kita. Senzor odašilje kratak prasak zvuka, sluša odjek koji se odbija od onoga što se nalazi pred njim, i izračuna koliko je taj objekt daleko. Rezultat se ispisuje u konzolu.
Ovo je i prvi primjer koji koristi driver i Qwiic modul, pa je spajanje najlakše u cijelom kitu: jedan kabel i gotov si.
U ovoj dokumentaciji naučit ćeš:
- Kako ultrazvučni senzor mjeri udaljenost mjerenjem vremena odjeka.
- Kako spojiti Qwiic modul jednim kabelom i bez jumper žica.
- Kako postaviti
I2Cvezu i zašto te MicroPython tjera da imenuješ pinove. - Što je driver i kako ga dobiti na pločicu.
- Zašto ovaj senzor treba dva poziva funkcije da bi ti dao jedno mjerenje.
- Kako prepoznati vrijednost koja nije pravo mjerenje.
Potreban hardver:
- 1x Soldered NULA MINI pločica
- 1x Breadboard
- 1x Ultrazvučni senzor udaljenosti (HC-SR04)
- 1x Qwiic kabel
- 1x USB-C kabel
Spajanje komponenti
1. Umetni NULA MINI pločicu na breadboard
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.

2. Utisni Qwiic kabel u pločicu
NULA MINI ima jedan Qwiic konektor, na rubu pločice između tipki USER i RST. To je bijeli konektor označen s qwiic na silkscreenu. Utisni kabel dok ne klikne.

- i +. To je konektor za bateriju, i Qwiic kabel u njega ne ulazi.PWR svjetlo je upaljeno. Nije važno kada ga spojiš. Qwiic module je sigurno utiskivati u bilo kojem redoslijedu i u bilo kojem trenutku.Ako želiš vidjeti točno o kojem se konektoru radi na goloj pločici, ovdje je istaknut:

3. Utisni drugi kraj u senzor
Senzor su dvije pločice spojene poleđinom na poleđinu: plavi ultrazvučni modul koji nosi dva srebrna pretvarača, i ljubičasta Soldered pločica koja nosi elektroniku koja obavlja razgovor. Na ljubičastoj pločici silkscreenom je ispisano ULTRASONIC SENSOR QWIIC, i ona ima dva Qwiic konektora, po jedan na svakom kraju.
Utisni slobodni kraj kabela u bilo koji od njih. Spojeni su međusobno, pa nije važno koji odabereš. Drugi je tu da možeš dalje nalančati još jedan modul.

ON. On postavlja adresu na koju senzor odgovara, a kod očekuje tvorničku postavku. Mijenjao bi je samo ako bi želio staviti dva takva senzora na isti kabel.4. Usmjeri senzor u otvoreni prostor
Okreni senzor tako da dva srebrna pretvarača gledaju u prostoriju, i drži prostor pred njima čistim. To su dijelovi koji odašilju i slušaju zvuk, pa je sve što na njima leži (stol, kabel, tvoja ruka) jedina stvar koju će senzor ikada naći.

Kako senzor mjeri udaljenost
Zvuk kroz zrak putuje poznatom, ravnomjernom brzinom: oko 343 metra u sekundi, što izlazi na 0.0343 centimetra po mikrosekundi. Ta fiksna brzina je cijeli trik. Ako znaš koliko je zvuku trebalo da dođe negdje, znaš koliki je put prešao.
Zato senzor odašilje vrlo kratak cvrkut na oko 40 kHz, previsok da bi ga čovjek čuo, iako šišmiš s njim ne bi imao problema, i pokreće štopericu. Cvrkut otputuje, u nešto udari, i dio njega se odbije natrag. U trenutku kada ga senzor čuje da se vraća, zaustavlja štopericu.

Pretvaranje tog vremena u udaljenost traži jednu malu korekciju:
Udaljenost = (Vrijeme × 0.0343) ÷ 2
Na ovom modulu taj račun nikada ne moraš raditi sam. Ljubičasta prilagodna pločica ima svoj mali mikrokontroler koji vodi štopericu, obavi računanje i drži odgovor pripremljen da ga pokupiš.
Postavljanje I2C veze
Qwiic kabel nije četiri odvojene žice koje vodiš kamo želiš. To je fiksni svežnjić od četiri: 3.3 V, masa i dvije signalne linije sabirnice koja se zove I2C. Na NULA MINI te dvije signalne linije spojene su na IO6 i IO7. Nisu čak ni izvedene na headere, pa nema se što birati.
MicroPython te ipak tjera da to izgovoriš naglas:
i2c = I2C(0, scl=Pin(7), sda=Pin(6))
Čitaj to kao: koristi I2C periferiju 0, s linijom takta na IO7 i linijom podataka na IO6. 0 govori koji od hardverskih I2C blokova unutar čipa koristiti, scl je takt, a sda su podaci.
OSError: [Errno 19] ENODEV, što izgleda kao pokvaren senzor, a samo je pogrešno upisan broj pina. scl=Pin(7), sda=Pin(6), svaki put.Wire.begin() bez argumenata, a pinovi dolaze od pločice koju si odabrao u IDE-u, pa skica koja ne imenuje pinove i dalje radi, dokle god je odabrana prava pločica. MicroPython nema odabir pločice, pa pinovi umjesto toga žive u tvom kodu. Biti izričit je više tipkanja, ali jedna stvar manje koja može tiho poći po zlu.Objekt senzora zatim se stvara s I2C vezom, i bez vlastitih brojeva pinova:
sensor = UltrasonicSensor(i2c)
Ono što driver mora znati je s kojim modulom na kabelu razgovara, jer I2C dopušta da nekoliko modula dijeli jedan par žica. Svaki od njih odgovara na svoj broj, koji se zove adresa, a adresa ovog senzora je 0x30. Driver to već zna, i zato je ne predaješ.
i2c objekta, jer sjede na istim dvjema žicama na različitim adresama.Dobavljanje drivera na pločicu
Driver je kod koji je napisao netko drugi a ti ga posuđuješ. Bez njega bi morao sam mjeriti vrijeme pulsa odjeka i sam raditi računanje; s njim pozoveš getDistance() i dobiješ broj.
Ovom primjeru treba UltrasonicSensor.py, koji živi u lib folderu repozitorija primjera zajedno s Qwiic.py, dijeljenim helperom na kojem je izgrađen. Za razliku od Arduina, gdje Library Manager instalira u IDE na tvom računalu, MicroPython driver mora biti kopiran na samu pločicu. Pločica je ono što izvršava kod, i može uvesti samo ono što nađe u svom /lib folderu.
Ako si prošao Postavljanje MicroPythona, sva četiri drivera već su na mjestu. Ako nisu, najbrži način je pomoću mip:
mpremote mip install github:SolderedElectronics/Soldered-NULA-Beginner-kit-MicroPython-project-examples/lib
ImportError: no module named 'UltrasonicSensor', driver nije na pločici, ili je sletio negdje drugdje osim u /lib. Spajanje i senzor nisu problem. Prekopiraj lib folder i pokreni ponovno.Čitanje senzora ide u dva koraka
Skripta ne traži jednostavno udaljenost. Umjesto toga radi ovo:
sensor.takeMeasure()
time.sleep_ms(MEASURE_WAIT_MS)
distance = sensor.getDistance()
Tri linije gdje si možda očekivao jednu, a razlog je to što mjerenje traži stvarno vrijeme. takeMeasure() govori senzoru da ode i obavi posao: pošalje cvrkut, sluša, vodi štopericu, spremi odgovor. Taj zahtjev se vraća odmah. Pločica je samo poslala uputu, nije čekala rezultat.
Senzoru zatim treba trenutak. Odustaje od slušanja nakon oko 38 milisekundi ako odjek nikada ne dođe, pa mjerenje u najgorem slučaju može toliko trajati. Skripta čeka 50 ms, ugodno dulje, prije nego getDistance() pokupi gotov odgovor.
begin() se poziva jednom prije nego petlja počne. Za Qwiic senzor to otvara razgovor na adresi modula, a senzor bi uvijek trebao biti inicijaliziran prije nego iz njega čitaš.
Nije svaki broj pravo mjerenje
Ovaj senzor radi od oko 2 centimetra do oko 4 metra. Dalje od toga zvuk se vraća preslab da bi ga se prepoznalo, a senzor nema načina da ti to kaže. Nema odgovor "nije nađeno". Jednostavno ti ipak preda broj.
U praksi taj broj izađe vrlo velik, negdje blizu 1000 cm, i pomiče se po nekoliko centimetara od vrijednosti do vrijednosti. Deset metara je daleko izvan svega što ovaj senzor stvarno može čuti, pa vrijednost od nekoliko stotina centimetara ili više tretiraj kao "ništa nije nađeno", a ne kao daleki objekt.
Ista se stvar događa i s objektom dobro unutar dosega, ako je taj objekt slučajno mekan ili strmo zakrenut od senzora. Jastuci, zavjese i džemperi upijaju zvuk; tvrda ravna površina okrenuta pravo prema senzoru odbija ga najbolje.
Skripta također provjerava vrijednost točno 0 i ispisuje No echo received, nothing in range. umjesto udaljenosti. Nula je ono što senzor odgovori kada nije čuo nikakav upotrebljiv odjek, što se događa i kada je nešto bliže od približno 3 cm: odjek dolazi prije nego je izlazni cvrkut završio, pa ga senzor nikada ne prepozna.
Kod
# I2C je način da nekoliko uređaja razgovara s pločicom preko samo dvije žice, i to je ono što Qwiic konektor
# nosi. Treba nam ovdje jer je senzor Qwiic modul.
from machine import I2C, Pin
# Uvoz modula daje nam pristup gotovim funkcijama koje teški posao rade za nas. Ovdje uvozimo
# Soldered driver za ultrazvučni senzor udaljenosti, da ne moramo sami mjeriti vrijeme odjeka.
# Taj driver živi u lib folderu repozitorija primjera. Kopiraj cijeli lib folder na svoju pločicu,
# inače ga MicroPython neće moći naći.
from UltrasonicSensor import UltrasonicSensor
import time
# Ovdje postavljamo I2C vezu. Dva pina fiksirana su pločicom: na NULA MINI, I2C koristi IO6 za
# liniju podataka (SDA) i IO7 za liniju takta (SCL), a to su točno pinovi na koje je Qwiic konektor spojen.
# Uvijek ih sami imenujemo, jer pločica ne pretpostavlja koje pinove konektor koristi.
i2c = I2C(0, scl=Pin(7), sda=Pin(6))
# Ovdje stvaramo naš objekt senzora, koji smo nazvali "sensor", i predajemo mu I2C vezu. Objekt je naš način
# razgovora sa senzorom: svaku funkciju koju na njemu pozovemo, pozivamo preko ovog imena.
# Primijeti da za senzor ne predajemo nikakve brojeve pinova. Svaki Qwiic modul dijeli ista dva I2C pina, i zato
# ih možeš nalančati nekoliko zajedno, a ovaj senzor odgovara na adresi 0x30.
sensor = UltrasonicSensor(i2c)
# Ovoliko čekamo nakon što zatražimo mjerenje, u milisekundama. Senzor odustaje nakon 38
# milisekundi ako odjek ne dođe, pa čekamo malo dulje od toga.
MEASURE_WAIT_MS = 50
# begin() priprema senzor za upotrebu. Senzor bi uvijek trebao biti inicijaliziran prije nego počnemo čitati iz njega.
sensor.begin()
# Ispiši početnu poruku da znamo da se program uspješno pokrenuo.
print("Ultrasonic Measuring Distance Example started!")
print("Move an object in front of the sensor to see the distance change.")
# Petlja while True ponavlja se unedogled, pa se kod unutar nje izvršava dok ne zaustavimo program.
while True:
# Čitanje Qwiic senzora ide u dva koraka. takeMeasure() je prvi: traži od senzora da pošalje
# puls i izmjeri vrijeme odjeka. Senzor taj posao obavi sam i zapamti odgovor, i zato
# onda moramo čekati prije nego ga pokupimo.
sensor.takeMeasure()
time.sleep_ms(MEASURE_WAIT_MS)
# getDistance() je drugi korak: dohvaća odgovor koji je senzor izračunao i spremio, već
# pretvoren u centimetre.
distance = sensor.getDistance()
# Senzor odgovara s 0 kada nije čuo nikakav odjek, što se događa kada ništa nije u dosegu ili kada
# površina pred njim raspršuje zvuk. To nije pravo mjerenje, pa to i kažemo umjesto da
# prijavimo udaljenost od nule, što bi upućivalo na objekt koji dotiče senzor.
if distance == 0:
print("No echo received, nothing in range.")
else:
print("Distance: {} cm".format(distance))
# time.sleep() započinje pauzu u kodu, zadanu u sekundama. Bez ove pauze vrijednosti bi promicale
# daleko prebrzo da bi ih se pročitalo, a ona i pušta odjeke prošlog pulsa da se ugase prije sljedećeg.
time.sleep(0.5)
"Distance: {} cm".format(distance) gradi jedan string iz teksta i broja. {} je rezervirano mjesto, a format() ubacuje vrijednost u njega. To je MicroPython ekvivalent onih nekoliko poziva Serial.print() koje Arduino skica treba da bi sagradila istu liniju.Što bi trebao vidjeti
Pritisni Run. Nakon dvije početne linije dobivaš novu vrijednost dvaput u sekundi.
Usmjeri senzor preko prostorije i mahni rukom pred njim, i brojevi prate ono što je najbliže:
Ultrasonic Measuring Distance Example started!
Move an object in front of the sensor to see the distance change.
Distance: 52 cm
Distance: 52 cm
Distance: 160 cm
Distance: 96 cm
Distance: 39 cm
Prve dvije vrijednosti stoje na 52 cm, a tu je najbliži objekt mirno stajao. Vrijednosti koje skaču (160 cm, 96 cm, 39 cm) su trenuci kada se nešto pomaknulo kroz vidno polje senzora, ili kada je zvuk umjesto toga našao nešto dalje.
Sada usmjeri senzor u prazan prostor, ili pravo gore u strop, i slika se potpuno mijenja. Gotovo svaka linija sada pokazuje negdje između 996 i 1000 cm:
Distance: 997 cm
Distance: 999 cm
Distance: 996 cm
Distance: 1000 cm
To je način na koji ovaj senzor prijavljuje da nije našao ništa, kako je opisano iznad, a ne objekt deset metara daleko. Korisno je prepoznati taj skup vrijednosti, jer ti kaže da pločica i senzor savršeno dobro razgovaraju međusobno, a problem je samo u tome kamo je senzor usmjeren.
OSError: [Errno 19] ENODEV, pločica ne može naći senzor na sabirnici. Provjeri prvo dva broja Pin u liniji I2C(), a zatim je li Qwiic kabel do kraja utisnut u oba svoja konektora.Probaj sam: promijeni time.sleep(0.5) na kraju petlje u time.sleep(0.1) i pokreni ponovno. Vrijednosti sada dolaze oko šest puta u sekundi umjesto dvaput, i praćenje ruke koja se kreće postaje mnogo glađe. Skratiš li ga još mnogo više, svaki novi cvrkut izlazi dok se odjeci prošlog još odbijaju po prostoriji, što brojeve tjera da skaču.
Cijeli primjer
Pogledaj cijeli kod primjera na linku ispod:
3.1_Measuring_Distance.py
Primjer koji čita Qwiic ultrazvučni senzor udaljenosti i ispisuje udaljenost u konzolu.