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.

Glatka analogna krivulja iscrtana u odnosu na vrijeme, preklopljena sa stepenastom digitalnom aproksimacijom. Iscrtkane vodoravne linije označavaju razine kvantizacije; stepenasta krivulja prikvačuje se na onu razinu koja je najbliža analognom signalu u svakoj točki uzorkovanja.

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. Vin na vrhu povezuje se kroz R1 do čvora koji se odvaja kao V_out, a koji se zatim povezuje kroz R2 do mase.

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 između 3,3 V i mase. Brisač se odvaja na ADC pin.

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:

Naponski razdjelnik koji smanjuje visoki V_in na ADC pin. R1 ide od V_in do spojišta, koje se vodoravno odvaja na ADC pin; R2 se nastavlja od spojišta do mase.

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 , R2 = 10 . 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). Uz R1 + R2 = 43 i V_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_in pogreš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.