3.12. Čitanje analognog signala pomoću ADC-a¶
Do sada je kamera čitala digitalne signale – pin je ili 0 ili 1, prekidač je otvoren ili zatvoren. Većina signala koji dolaze iz senzora u stvarnom svijetu su analogni: kontinuirani napon koji se glatko mijenja unutar nekog raspona. Fotootpornik prolazi kroz svaki napon između napajanja kako se mijenja okolna svjetlina. Izlaz temperaturnog senzora odluta nekoliko milivolta kako se prostorija zagrijava. Izlaz mikrofona raste i pada zajedno sa zvukom oko njega.
Analogno-digitalni pretvarač (ADC) je most. On uzorkuje napon na pinu i vraća cijeli broj koji Python može pročitati kao bilo koju drugu vrijednost.
3.12.1. Kvantizacija¶
Digitalna vrijednost ne može točno predstaviti kontinuirani napon. Zadaća ADC-a je kvantizirati – prikvačiti svaki uzorak na najbliži od fiksnog skupa razina. N-bitni ADC ima 2^N razina; 12-bitni pretvarač ima ih 4096 raspoređenih preko svojeg ulaznog raspona.
Kvantizacija: svaki uzorak analognog signala (puna linija) zaokružuje se na jednu od konačnog skupa digitalnih razina (stepenasta iscrtkana linija).¶
Napon između dvije susjedne razine je veličina koraka ADC-a; sve manje od toga nestaje u zaokruživanju. 12-bitni ADC preko raspona od 3,3 V ima veličinu koraka od oko 3.3 / 4096 ≈ 0.8 mV – dovoljno fino da većina signala u softveru izgleda praktički kontinuirano.
3.12.2. Klasa machine.ADC¶
machine.ADC obuhvaća jedan analogni ulazni kanal. Stvorite je s pinom koji želite čitati, a zatim pozovite read_u16():
from machine import ADC
adc = ADC("P6")
value = adc.read_u16()
print(value)
read_u16() uvijek vraća neoznačeni 16-bitni cijeli broj između 0 i 65535. Nativna razlučivost ADC-a razlikuje se ovisno o ploči (12-bitna na STM32, ovisno o portu drugdje); rezultat je lijevo poravnat u 16 bita tako da hardverski detalj ne procuri u Python – vrijednost 65535 predstavlja puni opseg bez obzira na čip.
Referentni napon – ulaz koji odgovara punom opsegu – ovisi o ploči. Provjerite OpenMV ploče za vrijednost na vašoj kameri. Sve iznad reference očitava se kao puni opseg (i može oštetiti pin ako premaši apsolutno maksimalni ulazni napon).
3.12.2.1. Pretvaranje brojeva u napon¶
Preslikavanje iz brojeva u napon je linearno, pri čemu se brojevi punog opsega točno preslikavaju u Vref:
voltage = counts × Vref / 65535
U kodu:
VREF = 3.3 # cam-dependent; see the quickref
counts = adc.read_u16()
voltage = counts * VREF / 65535
print(voltage, "V")
3.12.3. Naponska razdjelnika¶
Dva otpornika u seriji između naponskog napajanja i mase tvore naponski razdjelnik. Čvor između njih nalazi se na naponu određenom omjerom dvaju otpornika:
Naponski razdjelnik: R1 i R2 u seriji smanjuju Vin na V_out.¶
V_out = Vin × R2 / (R1 + R2)
Jednaki otpornici daju polovicu napona napajanja; R2 mnogo manji od R1 postavlja odvojak blizu mase; R2 mnogo veći postavlja ga blizu napajanja.
Formula pretpostavlja da ništa drugo ne vuče primjetnu struju iz V_out. ADC pin ima visoku impedanciju (megaomi, nanoamperi) i to lako zadovoljava, pa se razdjelnik koji napaja ADC ponaša onako kako formula predviđa.
3.12.4. Potenciometri¶
Potenciometar je jedna fizička komponenta koja je upravo naponski razdjelnik, s kliznim brisačem koji pomiče odvojak između dva kraja. Okretanje gumba mijenja R1 i R2 zajedno, dok njihov zbroj (ukupni otpor potenciometra) ostaje konstantan.
Potenciometar spojen kao ručni izvor napona za ADC: 3,3 V na jednom kraju, masa na drugom, brisač na pin.¶
Potenciometar je kanonski ulazni uređaj za isprobavanje ADC-a. Spojite jedan kraj na 3.3 V, drugi na masu, a brisač na pin koji podržava ADC; okretanje gumba prevodi brisač kroz svaki napon između napajanja.
import time
from machine import ADC
pot = ADC("P6")
VREF = 3.3
while True:
counts = pot.read_u16()
voltage = counts * VREF / 65535
print(voltage, "V")
time.sleep_ms(100)
3.12.5. Čitanje viših napona pomoću razdjelnika¶
Napon iznad Vref zalijepit će ADC na puni opseg i može oštetiti ulaz ako premaši apsolutno maksimalnu vrijednost. Da biste očitali viši izvor – bateriju, izlaz senzora koji prelazi Vref – smanjite ga fiksnim naponskim razdjelnikom prije nego što dođe do pina:
Smanjivanje izvora visokog napona kako bi stao u ADC: R1 i R2 tvore fiksni naponski razdjelnik čiji odvojak napaja ADC pin.¶
Odaberite R1 i R2 tako da podijeljeni napon ostane unutar raspona ADC-a pri najvišem ulaznom naponu koji očekujete:
V_adc = V_in × R2 / (R1 + R2)
Za maksimalni V_in = 12 V i referencu od 3,3 V, omjer R2 / (R1 + R2) mora biti najviše 3.3 / 12 ≈ 0.275. Uobičajen odabir s malo rezerve je R1 = 33 kΩ, R2 = 10 kΩ. Omjer je 10 / 43 ≈ 0.233, pa V_adc doseže najviše oko 12 × 0.233 ≈ 2.79 V – sigurno ispod Vref.
Da biste iz ADC očitanja oporavili izvorni V_in, invertirajte formulu razdjelnika:
V_in = V_adc × (R1 + R2) / R2
U kodu:
from machine import ADC
R1 = 33_000
R2 = 10_000
VREF = 3.3
adc = ADC("P6")
counts = adc.read_u16()
v_adc = counts * VREF / 65535
v_in = v_adc * (R1 + R2) / R2
print(v_in, "V")
Nekoliko praktičnih napomena:
Razdjelnik kontinuirano vuče
V_in / (R1 + R2). UzR1 + R2 = 43 kΩiV_in = 12 V, to je oko 280 µA – obično zanemarivo, ali ako se izvor napaja iz baterije razmotrite veće otpornike (100 kΩ do 1 MΩ) kako biste smanjili potrošnju u mirovanju.Tolerancija otpornika (obično ±1 % ili ±5 %) izravno utječe na točnost mjerenja. Dva otpornika od ±5 % mogu dati oporavljenom
V_inpogrešku u najgorem slučaju od otprilike ±10 %.Izlazna impedancija razdjelnika u kombinaciji s bilo kojom parazitskom kapacitivnošću niskopropusno filtrira ulaz. Za signale koji se brzo mijenjaju to je važno; za provjeru napona baterije nije.