3.12. Čtení analogového signálu pomocí ADC¶
Doposud kamera četla digitální signály – pin je buď 0 nebo 1, spínač je rozepnutý nebo sepnutý. Většina signálů přicházejících ze senzorů reálného světa je však analogová: spojité napětí, které se plynule mění v určitém rozsahu. Fotorezistor prochází všemi napětími mezi napájecími úrovněmi podle toho, jak se mění okolní jas. Výstup teplotního senzoru se posune o několik milivoltů, jak se místnost ohřívá. Výstup mikrofonu stoupá a klesá podle zvuku v okolí.
Analogově-digitální převodník (ADC) je mostem mezi nimi. Vzorkuje napětí na pinu a vrací celé číslo, které Python může číst jako jakoukoli jinou hodnotu.
3.12.1. Kvantizace¶
Digitální hodnota nemůže přesně reprezentovat spojité napětí. Úkolem ADC je kvantizovat – přiřadit každý vzorek nejbližší z pevné sady úrovní. N-bitový ADC má 2^N úrovní; 12bitový převodník jich má 4096 rozprostřených přes svůj vstupní rozsah.
Kvantizace: každý vzorek analogového signálu (plná čára) je zaokrouhlen na jednu z konečné sady digitálních úrovní (schodovitá čárkovaná čára).¶
Napětí mezi dvěma sousedními úrovněmi je velikost kroku ADC; cokoli menšího se ztratí v zaokrouhlení. 12bitový ADC v rozsahu 3,3 V má velikost kroku přibližně 3.3 / 4096 ≈ 0.8 mV – dostatečně jemnou na to, aby většina signálů v softwaru vypadala prakticky spojitě.
3.12.2. Třída machine.ADC¶
machine.ADC obaluje jeden analogový vstupní kanál. Zkonstruujte ji s pinem, který chcete číst, a poté zavolejte read_u16():
from machine import ADC
adc = ADC("P6")
value = adc.read_u16()
print(value)
read_u16() vždy vrací 16bitové celé číslo bez znaménka mezi 0 a 65535. Nativní rozlišení ADC se liší podle desky (12bitové na STM32, jinde závisí na portu); výsledek je zarovnán doleva do 16 bitů, takže hardwarové detaily neprosakují do Pythonu – hodnota 65535 znamená plný rozsah bez ohledu na čip.
Referenční napětí – vstup, který odpovídá plnému rozsahu – závisí na desce. Hodnotu pro vaši kameru najdete v Desky OpenMV. Cokoli nad referencí se čte jako plný rozsah (a může poškodit pin, pokud překročí absolutní maximální vstupní napětí).
3.12.2.1. Převod hodnot na napětí¶
Mapování z hodnot na napětí je lineární, přičemž hodnoty plného rozsahu se mapují přesně na Vref:
voltage = counts × Vref / 65535
V kódu:
VREF = 3.3 # cam-dependent; see the quickref
counts = adc.read_u16()
voltage = counts * VREF / 65535
print(voltage, "V")
3.12.3. Napěťové děliče¶
Dva rezistory v sérii mezi napájecí úrovní a zemí tvoří napěťový dělič. Uzel mezi nimi má napětí dané poměrem obou rezistorů:
Napěťový dělič: R1 a R2 v sérii zmenšují Vin na V_out.¶
V_out = Vin × R2 / (R1 + R2)
Stejné rezistory dají polovinu napájecího napětí; R2 mnohem menší než R1 posune odbočku blízko zemi; R2 mnohem větší ji posune blízko napájecí úrovni.
Vzorec předpokládá, že z V_out neodebírá znatelný proud nic dalšího. Pin ADC má vysokou impedanci (megaohmy, nanoampéry) a tuto podmínku snadno splňuje, takže dělič napájející ADC se chová tak, jak vzorec předpovídá.
3.12.4. Potenciometry¶
Potenciometr je jediná fyzická součástka, která je přesně napěťovým děličem, s posuvným jezdcem, který pohybuje odbočkou mezi dvěma konci. Otáčení knoflíku mění R1 a R2 současně, přičemž jejich součet (celkový odpor potenciometru) zůstává konstantní.
Potenciometr zapojený jako ruční zdroj napětí pro ADC: 3,3 V na jednom konci, zem na druhém, jezdec na pin.¶
Potenciometr je typickým vstupním zařízením pro vyzkoušení ADC. Zapojte jeden konec na 3.3 V, druhý na zem a jezdec na pin podporující ADC; otáčení knoflíku posouvá jezdec přes všechna napětí mezi napájecími úrovněmi.
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. Čtení vyšších napětí pomocí děliče¶
Napětí nad Vref přitlačí ADC na plný rozsah a může poškodit vstup, pokud překročí absolutní maximální hodnotu. Chcete-li číst vyšší zdroj – baterii, výstup senzoru přesahující Vref – zmenšete jej pevným napěťovým děličem dříve, než dosáhne pinu:
Zmenšení vysokonapěťového zdroje tak, aby vyhovoval ADC: R1 a R2 tvoří pevný napěťový dělič, jehož odbočka napájí pin ADC.¶
Zvolte R1 a R2 tak, aby dělené napětí zůstalo v rozsahu ADC při nejvyšším vstupním napětí, které očekáváte:
V_adc = V_in × R2 / (R1 + R2)
Pro maximální V_in = 12 V a referenci 3,3 V musí být poměr R2 / (R1 + R2) nejvýše 3.3 / 12 ≈ 0.275. Běžnou volbou s malou rezervou je R1 = 33 kΩ, R2 = 10 kΩ. Poměr je 10 / 43 ≈ 0.233, takže V_adc dosahuje maxima asi 12 × 0.233 ≈ 2.79 V – bezpečně pod Vref.
Chcete-li z hodnoty ADC získat zpět původní V_in, invertujte vzorec děliče:
V_in = V_adc × (R1 + R2) / R2
V kódu:
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ěkolik praktických poznámek:
Dělič nepřetržitě odebírá
V_in / (R1 + R2). PřiR1 + R2 = 43 kΩaV_in = 12 Vje to asi 280 µA – obvykle zanedbatelné, ale pokud je zdroj napájen z baterie, zvažte větší rezistory (100 kΩ až 1 MΩ) pro snížení klidového odběru.Tolerance rezistorů (typicky ±1 % nebo ±5 %) se přímo promítá do přesnosti měření. Dva rezistory ±5 % mohou dát získanému
V_inchybu v nejhorším případě zhruba ±10 %.Zdrojová impedance děliče se kombinuje s případnou parazitní kapacitou a vytváří dolnopropustný filtr vstupu. U rychle se měnících signálů na tom záleží; u kontroly napětí baterie nikoli.