Skip to main content

2.3 Analogno čitanje fotootpornika

Cilj ovog primjera je pokazati ti kako mjeriti jačinu svjetla pomoću fotootpornika (LDR) spojenog na jedan od analognih ulaznih pinova na NULA MINI pločici. Naučit ćeš kako koristiti klasu ADC za čitanje kontinuiranog raspona vrijednosti umjesto običnih uključeno/isključeno signala. Ovo je tvoj prvi korak u svijet analognog ulaza, nužan za senzore kao što su senzori svjetla, temperature ili zvuka.

U ovoj dokumentaciji naučit ćeš:

  • Kako se analogni ulazi razlikuju od digitalnih.
  • Kako spojiti fotootpornik na NULA MINI pločicu.
  • Kako čitati analogne vrijednosti pomoću ADC i read().
  • Što postavka atten radi i zašto je važna.

Potreban hardver:

  • 1x Soldered NULA MINI pločica
  • 1x Breadboard
  • 1x Fotootpornik (LDR)
  • 1x otpornik od 10 kΩ
  • 4x Jumper žice
  • 1x USB-C kabel
ℹ️
Za razliku od primjera s tipkom, ovome otpornik jest potreban. Onaj od 10 kΩ nije tu da bilo što zaštiti. On je polovica samog mjernog kruga, kako je objašnjeno ispod.

Spajanje komponenti

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

ℹ️
Sve u ovom primjeru živi na f–j strani breadboarda, jer su sva tri pina koja mu trebaju na tom rubu pločice: IO5 u redu 28, 3V3 u redu 29 i GND u redu 30. Pločica prekriva većinu tih redova, pa su krajnje rupice (j28, j29, j30) one do kojih možeš doći.

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.

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

2. Izvedi napajanje i masu

Prvo dvije jumper žice, da krug ima između čega sjediti.

  • Iz j30 (GND) do plave vodilice. Ta vodilica postaje tvoja linija mase.
  • Iz j29 (3V3) gore u red 14.
Žica mase na negativnu vodilicu i 3V3 izveden u red 14
Korak 2: GND na − vodilicu, i 3V3 izveden u red 14

3. Dodaj fotootpornik

LDR premošćuje red 14, u koji sada dolazi 3.3 V, i red 11.

Fotootpornik postavljen između redova 14 i 11
Korak 3: fotootpornik premošćuje redove 14 i 11
ℹ️
Fotootpornik nema polaritet: bilo koja nožica može ići na bilo koju stranu. To je samo otpornik čija se vrijednost mijenja sa svjetlom.

4. Dodaj otpornik od 10 kΩ

Otpornik nastavlja lanac prema dolje: iz reda 11 u red 9.

Otpornik od 10k dodan između redova 11 i 9
Korak 4: otpornik od 10 kΩ premošćuje redove 11 i 9
⚠️
Pobrini se da uzmeš otpornik od 10 kΩ, a ne onaj od 330 Ω koji se koristi s LED-icama. Prstenovi za 10 kΩ su smeđi-crni-narančasti, a za 330 Ω narančasti-narančasti-smeđi. S pogrešnim ćeš i dalje dobivati vrijednosti, ali će se jedva mijenjati kad se svjetlo promijeni.

5. Spoji otpornik na masu

Jedna jumper žica iz reda 9 do plave vodilice, koja je već spojena na GND.

Jumper žica spaja otpornik na negativnu vodilicu
Korak 5: donji kraj otpornika spojen na plavu − vodilicu

Lanac je sada potpun: 3.3 V → LDR → 10 kΩ → GND. Struja teče kroz oba dijela serijski.

6. Zahvati sredinu pomoću IO5

Sada samo mjerenje. Povuci jumper žicu iz j28 (IO5) u red 11, red koji dijele donja nožica LDR-a i gornji izvod otpornika.

IO5 spojen na spoj između LDR-a i otpornika
Korak 6: IO5 zahvaća spoj u redu 11
ℹ️
Red 11 je cijela svrha ovog kruga. On je središnja točka između dva otpora, i njegov se napon mijenja kako se mijenja otpor LDR-a. To je ono što IO5 mjeri.

7. Spoji pločicu na računalo

Gotov krug napajan preko USB-C
Korak 7: gotov krug, napajan preko USB-C
ℹ️
Redovi iznad samo su oni koje fotografije slučajno koriste. Bilo koji slobodni redovi rade, dokle god LDR i otpornik ostanu serijski između 3.3 V i GND, a IO5 zahvaća red u kojem se spajaju.

Kako radi djelitelj napona

Pločica ne može mjeriti otpor. Može mjeriti samo napon. Fotootpornik mijenja svoj otpor sa svjetlom, pa sam za sebe pločici ne daje ništa za čitanje.

Spajanje s fiksnim otpornikom to rješava. Ta dva otpornika u seriji tvore djelitelj napona, a napon u točki između njih ovisi o odnosu dva otpora:

  • Na jakom svjetlu otpor LDR-a pada, pa zadržava manje od 3.3 V za sebe i napon na IO5 raste.
  • U tami otpor LDR-a raste, zadržava veći dio napona, a vrijednost na IO5 pada.

Zato je fiksni otpornik važan koliko i senzor: bez njega nema središnje točke koja bi se mogla mjeriti.


Razumijevanje analognog ulaza

Za razliku od digitalnih pinova koji čitaju samo 1 (visoko) ili 0 (nisko), analogni pinovi mogu mjeriti kontinuirani raspon napona između 0 V i 3.3 V. ADC (Analog-to-Digital Converter) unutar NULA MINI pretvara te napone u brojeve između 0 i 4095, jer koristi 12-bitni ADC.

Ovo je ono što je pločica s fotografija stvarno izmjerila, u običnom uredu pri danjem svjetlu:

Uvjeti osvjetljenjaVrijednost
Svjetlo mobitela prislonjeno na senzor2200–2530
Normalno svjetlo u prostoriji1000–1070
Prekriveno rukom85–150
ℹ️
Ne uzimaj te brojeve kao ciljeve. Oni ovise o svjetlu u tvojoj prostoriji, o tome kako je senzor nagnut i o samom fotootporniku. Druga pločica u drugoj prostoriji čitat će drugačije i pritom raditi savršeno. Primijeti i da je vrh raspona stvarno teško dosegnuti: čak i svjetlo mobitela pritisnuto na senzor stiglo je samo do oko dvije trećine puta do 4095, pa vrijednost blizu 4095 traži direktno sunčevo svjetlo.

U MicroPythonu je pretvarač vlastita klasa, koja se uvozi uz Pin:

from machine import Pin, ADC

Pin koji želiš mjeriti zatim omotaš u ADC objekt i čitaš ga pomoću read():

ldr = ADC(Pin(LDR_PIN), atten=ADC.ATTN_11DB)
light_value = ldr.read()
ℹ️
Gdje Arduino skica poziva analogReadResolution(12) u setup() a zatim analogRead(LDR_PIN), MicroPython postavljanje odrađuje pri stvaranju objekta. 12-bitni raspon je ono što ti read() daje na ovom čipu, pa za to nema se što konfigurirati.

Postavka atten odabire koliko velik napon pretvarač može mjeriti. ADC.ATTN_11DB je najširi od njih, onaj koji pokriva cijeli hod od 0 V do 3.3 V, i to je ono što ovaj primjer želi, jer se od fotootpornika očekuje da se kreće po cijelom rasponu.

ℹ️
Napiši atten iako bi ga ovaj firmware odabrao za tebe. Na MicroPython buildu s kojim su ove stranice testirane (v1.29.0, ESP32_GENERIC_C6), ADC(Pin(5)) bez atten argumenta ponaša se točno kao ADC.ATTN_11DB: pri istom svjetlu u prostoriji oba čitaju oko 1050. Druge pločice i stariji buildovi umjesto toga po zadanom uzimaju najužu postavku, pa je izričito pisanje ono što primjer čini prenosivim. Nije to linija na koju se možeš osloniti da je nepotrebna.
⚠️
Pogrešan atten je ono što fotootpornik čini da izgleda pokvareno. Zamijeni ADC.ATTN_11DB s ADC.ATTN_0DB i pretvarač mjeri samo do oko 1 V, pa ga obično svjetlo u prostoriji već potiskuje blizu vrha: isti senzor koji čita 1050 na ATTN_11DB čita 3930 na ATTN_0DB, i priljubljuje se uz 4095 u trenutku kad se svjetlo popravi. Vrijednost zaglavljena visoko koja se ne želi pomaknuti daleko je češće ovo nego greška u spajanju.

Kod

# ADC je skraćeno od Analog to Digital Converter. Gdje nam Pin može reći samo visoko ili nisko, ADC mjeri stvarni
# napon na pinu i daje nam broj za njega, a to nam i treba da izmjerimo cijeli raspon razina svjetla.
from machine import Pin, ADC
import time

# Ovo je varijabla kojoj dodjeljujemo broj pina na koji smo spojili izlaz fotootpornika.
# U ovom primjeru koristit ćemo IO5, koji podržava analogni ulaz.
#
# Ovom primjeru također treba otpornik od 10k. Fotootpornik mijenja svoj otpor sa svjetlom, ali pločica može
# mjeriti samo napon, pa ta dva spajamo u ono što se naziva djelitelj napona.
LDR_PIN = 5

# Ovdje stvaramo naš ADC objekt, koji smo nazvali "ldr". Predajemo mu Pin, i od tada razinu svjetla čitamo
# preko ovog imena. Postavka atten odabire koliko velik napon pretvarač može mjeriti. ADC.ATTN_11DB je
# najšira postavka, koja nam dopušta korištenje cijelog raspona fotootpornika od potpune tame do jakog svjetla.
ldr = ADC(Pin(LDR_PIN), atten=ADC.ATTN_11DB)

# Ispiši početnu poruku da potvrdimo da program radi.
print("Cover or shine light on the sensor to see value changes...")

while True:

# read() čita napon na zadanom analognom pinu i pretvara ga u broj. Budući da NULA pločica koristi
# 12-bitni ADC, vraćena vrijednost bit će u rasponu od 0 do 4095.
# Što je jačina svjetla veća, to je otpor fotootpornika manji, a izmjereni napon veći.
light_value = ldr.read()

# Ispiši izmjerenu vrijednost u konzolu.
print("Light level:", light_value)

# time.sleep() započinje pauzu u kodu, zadanu u sekundama. Pola sekunde čini vrijednosti lakima za praćenje
# očima. Slobodno eksperimentiraj s ovom vrijednošću.
time.sleep(0.5)

Što bi trebao vidjeti

Pritisni Run. Pojavljuje se početna poruka, a zatim nova vrijednost dolazi u Shell dvaput u sekundi. Ostavi senzor na miru na trenutak i broj se jedva miče, samo nekoliko jedinica podrhtavanja s obje strane onoga što ti daje svjetlo u prostoriji:

Cover or shine light on the sensor to see value changes...
Light level: 1057
Light level: 1058
Light level: 1058
Light level: 1055
Light level: 1057
Light level: 1058

Sada stavi ruku preko senzora i gledaj kako brojevi padaju.

Ruka zasjenjuje fotootpornik
Zasjenjivanje senzora rukom dovoljno je da se vrijednost pomakne

Ovo je pravi ispis iz Shella od zasjenjivanja senzora rukom, odmicanja ruke, a zatim držanja svjetla mobitela na njemu:

Light level: 426
Light level: 147
Light level: 372
Light level: 106
Light level: 111
Light level: 107
Light level: 101
Light level: 97
Light level: 86
Light level: 266
Light level: 113
Light level: 1036
Light level: 1057
Light level: 1051
Light level: 1063
Light level: 1066
Light level: 1052
Light level: 1182
Light level: 1571
Light level: 2121
Light level: 2502
Light level: 2526
Light level: 2465
Light level: 2325
Light level: 2378
ℹ️
Skakutave vrijednosti nisu greška. Pogledaj 147 nakon kojeg slijedi 372, ili 86 nakon kojeg slijedi 266: senzor je dovoljno brz da vidi ruku koja se još kreće, pa se svako kolebanje i svaki razmak između prstiju pojavljuje kao vlastita vrijednost. Broj se umiri samo kad se umiri i tvoja ruka. Primijeti i da mu treba dvije ili tri vrijednosti da se uzdigne od svjetla u prostoriji do svjetla mobitela. To je pauza time.sleep() od pola sekunde, a ne senzor koji je spor.
ℹ️
Tvoji brojevi neće se točno poklapati s ovima. Ovise o svjetlu u tvojoj prostoriji i o samom fotootporniku. Važno je da se vrijednost miče kada se svjetlo mijenja. Ako stoji na fiksnom broju bez obzira što radiš, provjeri da IO5 stvarno zahvaća red spoja, a ne jedan od vanjskih redova.
ℹ️
Vrijednost prikovana blizu 4095 koja se nikada ne pomiče upućuje na postavku atten, a ne na neispravan senzor. Provjeri da linija piše ADC.ATTN_11DB, a ne ADC.ATTN_0DB.

Cijeli primjer

Pogledaj cijeli kod primjera na linku ispod:

2.3_Photoresistor_Analog_Read.py

Primjer koji pokazuje kako čitati analogne vrijednosti s fotootpornika i ispisivati razine svjetla u konzolu.