Praktické využití diferenciálního AD převodu

Nejspíš už jste se dočetli (třeba zde) že AD převodník na Atmelech může mít možnost měřit diferenciálně. Tedy měřit rozdílové napětí mezi dvěma vstupy. Většina Atmelů s takto vybaveným převodníkem obsahuje pro diferenciální měření ještě zesilovače, které jsou výraznou pomůckou při měření malých napětí. Mohlo by se proto zdát, že diferenciální režim bez zesilovačů nemá defakto žádné pořádné využití. A to bych rád vyvrátil následující aplikací.

Hallova sonda

V Číně můžete běžně koupit modul k měření proudu vybavený senzorem ACS712 (čip můžete mimo jiné koupit i samostatně například v TME). Měření proudu je realizováno Hallovým jevem, tedy měří se magnetické pole způsobené průchodem proudu. To přináší jednu obrovskou výhodu. Měřicí obvod není galvanicky spojen s měřeným obvodem. Laicky řečeno můžete ten modul zapojit kamkoli chcete a nemusíte se starat o to na jakém potenciálu je uzel v němž měříte proud. Aby to bylo úplně jasné, můžete to připojit klidně do zásuvky... já to ale většinou připojuji k olověným akumulátorům. Z principu jsou moduly určeny k měření větších proudů (jednotky A). Vyrábí se různé varianty s rozsahem +-5A až +-30A. Z toho plyne že přesnost měření nízkých proudů nebude nejlepší a diferenciální AD převod je něco co ji pomůže zlepšit. Než se ale dostanu k tomu jak na to, musíme se ještě podívat na výstup čidla. Pokud modulem neteče žádný proud mělo by být výstupní napětí přesně polovina napájecího napětí. O tom že to tak je se můžete přesvědčit z malé tabulky.

ACS712 (100mV/A) proud 0A
VccVoutOdchylka od Vcc/2
4.853V2.428V-1.5mV (0.06%)
4.960V2.483V-3mV (0.12%)
5.056V2.530V-2mV (-0.08%)
5.130V2.569V
-4m (0.15%)

Výstupní napětí pak buď roste nebo klesá podle toho jakým směrem proud protéká. Pro čidla s rozsahem +-5A se výstupní napětí mění tempem přibližně 185mV/A, čidla s rozsahem +-20A mají koeficient 100mV/A a čidla s rozsahem +-30A mají 66mV/A. Přirozeně tyto tři parametry trpí jistou chybou. Ta by měla podle datasheetu dosahovat maximálně 1.5%. S jistým úsilím v podobě vícebodové kalibrace ji ale určitě bude možné softwarově snížit na desetiny procenta.


Modul měření proudu ACS712

Špatný postup

Neodpustím si zákeřné rýpnutí do Arduina. Drtivá většina Arduino návodů k tomuto čidlu ve stručnosti říká: "Připojte čidlo k napájení, zavolejte fci analogRead(), vynásobte konstantou a máte proud". Jednoduchá řešení sebou typicky přináší kompromisy. V tomto případě v podobě nepřesnosti a snížené rozlišovací schopnosti. Abych moc nemával rukama pomůžu si troškou matematiky. Arduino používá jako referenční napětí VCC. Dejme tomu, že je to 5V. Rozlišovací schopnost je tedy 5/1024 = 4.9mV. U modulu s rozsahem +-20A jež má rozlišení 100mV/A, dosáhnete v takovém případě teoreticky rozlišení proudu 49mA (nic moc). S minimálním množstvím snahy lze dosáhnout rozlišení skoro pětinásobného. Jak na to si řekneme po malé jedovaté vsuvce (klidně přeskočte).

Abych neztratil úplný přehled o stavu Arduino komunity, zadal jsem do googlu výraz "ACS712 Arduino". Vzal jsem hned první odkaz (na který klikne asi slušné množství lidí) a nestačil se divit co jsem tam našel. Chápu že dnes se na součástky a moduly hledí jako na black-box a nemám proti tomu výhrady, ale když už to dělám tak to přiznám. Řeknu "nevím co je vevnitř, ale navenek se to chová tak a tak", pak se mi totiž nestane že bych čtenáři mylně podsouval nějaké nepravdy. Jako třeba informaci o tom že modulek vytváří své výstupní napětí na základě okolního elektrického pole... to tam opravdu žádnou roli nehraje. Těch kixů, které bych od "prvního odkazu v googlu" nečekal je vícero. PRvní do očí praští "zkrat" skrze diodu na "schématu" z Fritzingu. Další kix, který si zaslouží ocenění je v kódu, napětí se tam počítá jako analog*5/1023. Z logiky věci a dle datasheetu to má být analog*5/1024 (Chudák začátečník, který pak řešení použije jako šablonu pro další projekty). Stejně tak pokus o měření RMS působí vyloženě děsivě. Nejhorší následky v podobě špatných návyků na začátečníka zanechá naprosto nemístné použití typu double a nesmyslné vypisování výsledku na čtyři platné cifry. Je to stejně bláhové jako měřit prst pravítkem a tvrdit že je dlouhý 75.23mm... ale zpět ke konstruktivní debatě.

Lepší postup

Dejme tomu, že máte Atmel jehož AD převodník má možnost diferenciálního měření (z Arduin například Arduino Mega). Pro diferenciální měření budete potřebovat referenční napětí o hodnotě pokud možno co nejbližší výstupnímu napětí nezatíženého čidla. Vzhledem k tomu že výstup čidla (při nulovém proudu) je velmi přesně (0.1%) roven polovině napájecího napětí, stačí najít dva odpory o shodné hodnotě (pod jednu desetinu procenta) a vytvořit z nich jednoduchý dělič. Jestliže po ruce dva stejné odpory nemáte, můžete si vypomoct trimrem a výstup ručně nastavit na příslušnou hodnotu. Výstup čidla i děliče připojte na diferenciální kanály AD převodníku. Díky tomu, že diferenciální měření měří pouze rozdíl obou napětí budete moct pro převodník využívat nižšího referenčního napětí. Pro 20A čidlo bude rozlišovací schopnost s referencí 2.56V rovna 25mA a s referencí 1.1V až 11mA. S využitím zesilovačů pak můžete dojít až k 1mA. A za určitých okolností ještě dále. V takových situacích se ale začnou projevovat další chyby a uděláte nejlépe když sáhnete po čidle s 5A rozsahem.


Obr.2 - Reference ze dvou shodných rezistorů. Odpor R1 a R2 by se neměl lišit o více jak 0.1%


Obr.3 - Doladitelná reference (odlišnost odporů lze doladit trimrem).

Proč by vás ale měla rozlišovací schopnost vůbec zajímat ? Uvažte, že měříte například nabíjení, případně vybíjení akumulátoru a chcete znát třeba zbývající kapacitu. Předveďme si problém na příkladu. Máme akumulátor o kapacitě 10Ah a vybíjíme ho proudem 120mA. Pokud používáme hloupý postup měření a máme rozlišovací schopnost 50mA můžeme vybíjecí proud změřit buď jako 100mA nebo jako 150mA. A z toho určit že se akumulátor vybije za 100h nebo 66h. To je rozptyl doslova jako prase - 1.5 dne ! Když ale využijeme prosté diferenciální měření (bez zesilovačů) s rozlišením 11mA zúží se rozptyl doby vybití na 8h-9h, což je o poznání přijatelnější hodnota.

Praktická ukázka

Aby to vše nebylo jen suché vyprávění, udělal jsem pro vás malou praktickou ukázku. Využil jsem Attiny24/44/84 k měření proudu přes diskutovaný modul (ACS712) abych ověřil jak moc diferenciální měření zlepší rozlišení. Podle datasheetu může být reference AD převodníku pro účely diferenciálního měření v rozsahu od 2V do Vcc-1 (tedy v případě 5V napájení do 4V). Což paradoxně vyřazuje všechny dostupné reference na Attiny84. Z toho důvodu jsem přivedl jednoduchou 2.5V referenci z vnějšku (s pomocí TL431). Abych si zarušil klidné napájecí napětí, připojil jsem obvod za stabilizátor 7805. Celé schema si můžete prohlédnout na obrázku 4. Protože jde o relativně citlivá měření nepřipadá v úvahu použití nepájivého pole, všechny spoje musí být kvalitní a tak je celý bastl spájený (viz fotografie).


Obr.4 - Zapojení ukázky

Než vás seznámím s výsledky, tak jen ve stručnosti okomentuji zdrojový kód. Při inicializaci AD převodníku nejprve nastavím referenci (pokud by byla použita interní musel bych na její inicializaci ještě 1ms počkat), nastavím clock do pásma 50-200kHz a zvolím bipolární měření a zarovnání dat vlevo pro snažší pozdější zpracování. Nezapomenu také vypnout vstupní buffery na pinech kde plánuji přivést analogové signály. Samotný převod pak provádí funkce get_ADC() a probíhá ve dvou fázích. Nejprve kanál nakonfiguruji k měření offsetu. Jinak řečeno nastavím že chci měřit rozdílové napětí mezi kanálem ADC3 a ADC3 ;). Výsledkem tohoto převodu bude offset, který budu potom od výsledku měření odečítat. Poté rekonfiguruji vstup ADC na měření rozdílu ADC3-ADC2 (což je náš užitečný signál). Protože výsledky převodu celkem "šumí" provedu toto měření několikrát a průměruji. Pro jistotu vracím nejen výsledek měření ale také hodnotu offsetu. Za určitých okolností může být offset velký (50-300) a naznačuje tím že je měření chybné. Například špatně zvolená reference mimo již zmiňovaný rozsah 2-4V k něčemu takovému vede. Například při měření s pomocí reference AVCC (5V) se od určité měřené hodnoty začne offset prudce zvyšovat a takové výsledky je potřeba vyřadit. Ale to bychom zabíhali do zbytečných detailů, pojďme se podívat na výsledky.

Zdrojový kód ke stažení.

Skrze modulek jsem pustil testovací proud 1A a měřil jsem jak moc výsledek měření "šumí", tedy jak moc se na něj lze spolehnout. 1A by teoreticky měla odpovídat změně napětí zhruba o 100mV na výstupu ze senzoru. Tomu odpovídá hodnota ADC=100mV/Vref*512. Což je pro Vref=5V zhruba 205 a pro Vref=2.5V přibližně 410. Tyto výsledky je potřeba brát s rezervou (konstanta 100mV/A má své tolerance (96-104mV/A) a stejně tak reference má své tolerance. To ale nevadí protože přesnou převodní konstantu mezi výsledkem ADC a proudem lze získat jednoduchou kalibrací. Faktorem který měření limituje je "šum" o jehož míře vás informuje následující tabulka.

Proud Reference Zisk průměrování výsledek šum relativní šum
1A AVCC (5V) 20x 64 203 +-2.2 +-1.1%
1A AVCC (5V) 20x 32 203 +-2.1 +-1%
1A AVCC (5V) 20x 16 204 +-3 +-1.5%
1A TL431 (2.5V) 20x 32 428 +-6.8 +-1.6%
1A TL431 (2.5V) 1x 32 4 +-1.2 +-30%

Z ní je patrné že ať už měříte nelegálně s referencí AVCC (5V) nebo legálně s 2.5V je rozlišovací schopnost výsledku nakonec stejná. Menší reference sice znamená vyšší hodnoty, ale spolu s nimi i vyšší šum, který dosahuje relativních hodnot 1.5%. To znamená že spolehlivě můžete rozlišovat proud s krokem 10mA. Do tabulky jsem zahrnul i jedno měření bez zesilovače, které přirozeně při tak malém proudu "prohrává". Jeho chvíle nastane jakmile proud přesáhne přibližně 2A. Což je hodnota kdy výstup zesilovačů překročí referenční napětí a nebude je tedy možné použít.
Přeji příjemné měření... ;)


Fotografie zapojení na kterém se testovalo

Home
V1.03 1.9.2017
By Michal Dudka (m.dudka@seznam.cz)