3.12. Analóg jel olvasása az ADC-vel¶
Eddig a kamera digitális jeleket olvasott – egy láb értéke vagy 0, vagy 1, egy kapcsoló nyitva van vagy zárva. A valós érzékelőkből érkező jelek többsége azonban analóg: folytonos feszültség, amely valamilyen tartományon belül simán változik. Egy fotoellenállás a környezeti fényerő változásával végigfut a tápfeszültségek közötti minden feszültségen. Egy hőmérséklet-érzékelő kimenete néhány millivolttal elcsúszik, ahogy egy szoba felmelegszik. Egy mikrofon kimenete a körülötte lévő hangok hatására emelkedik és süllyed.
Az analóg-digitális átalakító (ADC) jelenti a hidat. Megméri egy láb feszültségét, és olyan egész számot ad vissza, amelyet a Python bármely más értékhez hasonlóan ki tud olvasni.
3.12.1. Kvantálás¶
Egy digitális érték nem tud pontosan ábrázolni egy folytonos feszültséget. Az ADC feladata a kvantálás – minden mintát a rögzített szintkészlet legközelebbi értékéhez igazít. Egy N bites ADC-nek 2^N szintje van; egy 12 bites átalakítónak 4096 szintje, amely a bemeneti tartományán oszlik el.
Kvantálás: az analóg jel (folytonos) minden mintáját a digitális szintek véges készletének egyikéhez kerekítik (lépcsős szaggatott vonal).¶
Két szomszédos szint közötti feszültség az ADC lépésköze; minden ennél kisebb érték elvész a kerekítés során. Egy 12 bites ADC 3,3 V-os tartományon körülbelül 3.3 / 4096 ≈ 0.8 mV lépésközzel rendelkezik – ez elég finom ahhoz, hogy a legtöbb jel szoftverben gyakorlatilag folytonosnak tűnjön.
3.12.2. A machine.ADC osztály¶
A machine.ADC egyetlen analóg bemeneti csatornát fog be. Hozd létre azzal a lábbal, amelyet olvasni szeretnél, majd hívd meg a read_u16() metódust:
from machine import ADC
adc = ADC("P6")
value = adc.read_u16()
print(value)
A read_u16() mindig egy 0 és 65535 közötti előjel nélküli 16 bites egész számot ad vissza. A natív ADC-felbontás kártyánként eltér (STM32-n 12 bit, máshol portfüggő); az eredmény balra igazítva kerül a 16 bitbe, így a hardveres részlet nem szivárog be a Pythonba – a 65535 érték a chiptől függetlenül teljes kitérést jelent.
A referenciafeszültség – az a bemenet, amely a teljes kitéréshez tartozik – a kártyától függ. Ellenőrizd a kamerád értékét a OpenMV kártyák oldalon. A referencia feletti bármilyen érték teljes kitérésként jelenik meg (és károsíthatja a lábat, ha meghaladja az abszolút maximális bemeneti feszültséget).
3.12.2.1. Számértékek átváltása feszültséggé¶
A számértékekről feszültségre való leképezés lineáris, ahol a teljes kitéréshez tartozó számérték pontosan a Vref értékre képeződik le:
voltage = counts × Vref / 65535
Kódban:
VREF = 3.3 # cam-dependent; see the quickref
counts = adc.read_u16()
voltage = counts * VREF / 65535
print(voltage, "V")
3.12.3. Feszültségosztók¶
Egy tápfeszültség és a föld közé sorba kötött két ellenállás feszültségosztót alkot. A köztük lévő csomópont a két ellenállás arányával beállított feszültségen helyezkedik el:
Egy feszültségosztó: az R1 és R2 sorba kötve a Vin értéket V_out értékre csökkenti.¶
V_out = Vin × R2 / (R1 + R2)
Az egyenlő ellenállások a tápfeszültség felét adják; az R1-nél jóval kisebb R2 a leágazást a földhöz közelíti; a jóval nagyobb R2 a tápfeszültséghez közelíti.
A képlet feltételezi, hogy semmi más nem vesz fel számottevő áramot a V_out csomópontból. Egy ADC-láb nagy impedanciájú (megohmok, nanoamperek), és ezt könnyen teljesíti, így egy ADC-t tápláló osztó a képlet által megjósolt módon viselkedik.
3.12.4. Potenciométerek¶
A potenciométer egyetlen fizikai alkatrész, amely pontosan egy feszültségosztó, csúszó kefével, amely a leágazást a két vég között mozgatja. A gomb elforgatása együtt változtatja az R1 és R2 értékét, miközben az összegüket (a potenciométer teljes ellenállását) állandó értéken tartja.
Egy potenciométer az ADC kézi feszültségforrásaként bekötve: 3,3 V az egyik végén, föld a másikon, a kefe a lábra kötve.¶
A potenciométer a kézenfekvő bemeneti eszköz az ADC kipróbálásához. Kösd az egyik végét a 3.3 V-ra, a másikat a földre, a kefét pedig egy ADC-képes lábra; a gomb elforgatása a kefét végigfuttatja a tápfeszültségek közötti minden feszültségen.
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. Nagyobb feszültségek olvasása osztóval¶
A Vref feletti feszültség az ADC-t teljes kitérésre kényszeríti, és károsíthatja a bemenetet, ha meghaladja az abszolút maximális értéket. Egy nagyobb forrás olvasásához – egy akkumulátor, egy érzékelő kimenete, amely a Vref fölé terjed – csökkentsd le egy rögzített feszültségosztóval, mielőtt eléri a lábat:
Egy nagyfeszültségű forrás méretezése az ADC-hez: az R1 és R2 rögzített feszültségosztót alkot, amelynek leágazása az ADC-lábat táplálja.¶
Válaszd meg úgy az R1 és R2 értékét, hogy az osztott feszültség a várt legnagyobb bemeneti feszültségnél is az ADC tartományán belül maradjon:
V_adc = V_in × R2 / (R1 + R2)
Egy V_in = 12 V maximum és egy 3,3 V-os referencia esetén az R2 / (R1 + R2) aránynak legfeljebb 3.3 / 12 ≈ 0.275 értékűnek kell lennie. Egy kis ráhagyással gyakori választás az R1 = 33 kΩ, R2 = 10 kΩ. Az arány 10 / 43 ≈ 0.233, így a V_adc legfeljebb körülbelül 12 × 0.233 ≈ 2.79 V-on tetőzik – biztonságosan a Vref alatt.
Az eredeti V_in visszaszámításához egy ADC-leolvasásból fordítsd meg az osztóképletet:
V_in = V_adc × (R1 + R2) / R2
Kódban:
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")
Néhány gyakorlati megjegyzés:
Az osztó folyamatosan felvesz
V_in / (R1 + R2)áramot.R1 + R2 = 43 kΩésV_in = 12 Vesetén ez körülbelül 280 µA – általában elhanyagolható, de ha a forrás akkumulátorról működik, fontold meg nagyobb ellenállások (100 kΩ-tól 1 MΩ-ig) használatát az üresjárati fogyasztás csökkentésére.Az ellenállás tűrése (jellemzően ±1 % vagy ±5 %) közvetlenül kihat a mérési pontosságra. Két ±5 %-os ellenállás a visszaszámított
V_inértékben legrosszabb esetben nagyjából ±10 %-os hibát okozhat.Az osztó forrásimpedanciája bármilyen szórt kapacitással együtt aluláteresztő szűrőként hat a bemenetre. Gyorsan változó jeleknél ez számít; egy akkumulátorfeszültség-ellenőrzésnél nem.