neklidné dolní bity AD převodníku

Se zájmem jsem si přečetl diskuzi o problémech s LSB, neklidné dolní bity AD převodníku.
Ať už je to způsobené šumem nebo nepřesným převodníkem, tak při zobrazení na displeji to působí hodně rušivě. Z vlastní zkušenosti vím, že nepomůže ani průměrování, ani změna rozlišení AD převodníku. To může problém jenom snížit ale ne odstranit. I když bude měřené napětí stabilní, bez šumu ale zrovna na hraně mezi dvěmi digitálními hodnotami, tak se prostě budou střídat. A s jakou četností, to záleží na mnoha faktorech.

Ve svých konstrukcích se mi osvědčil vlastní způsob řešení tohoto problému.
Po každém AD převodu porovnám novou hodnotu se starou hodnotou.
Při porovnávání mohou nastat 4 situace.

  1. Nová hodnota je menší než stará. Výstup bude nová hodnota.
  2. Nová hodnota je větší než stará + 10. Výstup je opět nová hodnota.
  3. Nová hodnota je menší nebo stejná jako stará hodnota + 4. Výstup se nemění, zůstává jako stará hodnota.
  4. Nová hodnota je větší než stará + 4. Výstup je stará hodnota + 1.
    Hodnoty 10 a 4 jsou zvolené po dlouhodobém testování.

Pokud bude nová hodnota menší než stará, výstup je rovnou nová hodnota.
Při prudkém nárůstu (větší než 10) se vezme také nová hodnota.
Při nepatrné změně (do 4) se nic neděje, výstup zůstává stará hodnota. To právě odfiltruje nežádoucí šum (chvění).
A vtip této metody spočívá v tom, že při změně hodnoty v rozmezí 5 až 10 bude výstupní hodnota jenom o 1 větší než stará hodnota. Pokud se bude nová hodnota pomalu zvětšovat, bude výstup pěkně přičítat po jedné.

Nevýhodou tohoto řešení je zmenšení přesnosti. Výsledek převodu může být až o 4 menší než skutečnost.
Tento způsob se dá použít nejen pro AD převodníky ale i pro čtení dat z různých čidel a snímačů.

V assembleru pro PIC to vypadá takto: ;Diference, odstraní chvění na nejnižších bitech. ;VSTUP: A1,2=nová hodnota, B1,2=stará hodnota ;VYSTUP: B1,2=výsledek ;dál se používá C1,2 (x1=LOW byte, x2=HIGH byte) DIF ;A1,2 - B1,2 = C1,2 MOVF B1,W SUBWF A1,W ;A1-B1=W MOVWF C1 ;uložit MOVF B2,W BTFSS STATUS,C ;odečet byl kladný? ADDLW 1 ;NE, B2+1=W SUBWF A2,W ;A2-B2=W MOVWF C2 ;uložit ;C2 = nenulové? (A<B nebo A>B+255) MOVF C2,F BTFSS STATUS,Z ;C2=0? GOTO ADB ;NE, nová hodnota z A ;C1 > 10? (A>B+10) MOVF C1,W SUBLW 10 ;10-C1 BTFSS STATUS,C ;kladné? GOTO ADB ;NE, nová hodnota z A ;C1 <= 4? (A<=B+4) MOVF C1,W SUBLW 4 ;4-C1 BTFSC STATUS,C ;záporné? RETURN ;NE, stará hodnota ;C1 > 4 (A>B+4) INCFSZ B1,F ;stará hodnota B+1 RETURN ; INCF B2,F ; RETURN ADB MOVF A1,W ;přesun nové hodnoty A do staré B MOVWF B1 ; MOVF A2,W ; MOVWF B2 ; RETURN
DIF.jpg

Laik žasne, odborník kroutí hlavou. Proč jsou intervaly nesymetrické? (hranice intrvalů: 0,+4,+10). To způsobí systematické zkreslování výsledků, jakoby růst měřené veličiny měl být něco jiného než pokles. Proč nepoužít např. pravidlo:
abs(Xi+1 - Xi) <= 4 Výstup je stará hodnota.
abs(Xi+1 - Xi) <= 10 a zároveň >4 zvětšení resp. zmenšení o 1 dle znamínka v absolutní hodnotě.
abs(Xi+1 - Xi) > 10 Výstup je nová hodnota.

Nicméně tato metoda neodstraní spolehlivě šum a tudíž ani přeblikávání hodnot na displeji. Mnohem lepší je použít statistických metod, např vážený průměr, pokud aritmetický nevyhoví. Váhy jednotlivých veličin Xi se stanoví v závisloti na vzálenosti Xi od střední hodnoty. Jinak řečeno, čím více se hodnota Xi odlišuje od středu, tím je její vliv na výsledek menší. Výsledek je dán jako X = SUMA(Ki*Xi), kde Ki jsou váhy jednotlivých měření a platí pro ně SUMA(Ki) = 1.
Je to více matematických operací, ale za to výsledek netrpí “necitlivostí” a nevnáší se do něj systematická chyba. Lze tak očekávat i vyšší přesnost než u samotného převodníku.

Nebudu nikoho přesvědčovat, že to funguje. Stačí si to jen vyzkoušet. A vyzkoušené to už je, několik let na řadě konstrukcí.
Představte si, že VÝSTUP je např. 10 a vstup se pohybuje od 10 do 14. Potom výstup stále drží na hodnotě 10.
Jestliže vstup klesne, vezme se jeho nejnižší hodnota a vstup může vesele kmitat dál.
Pokud vstup vzroste, postupným přičítáním se zase najde jeho nejnižší hodnota.
To ale není žádné přeblikávání nahoru dolu.
Nejde o složité počítání střední hodnoty, jde o jednoduchost protože v paměti mikrokontroléru totiž není místa nazbyt.

Pravdu mate oba, ale zalezi na typu aplikace :wink:
Pokud neni problem mala chyba (~2% - 8 bit prevodnik, 0,4% - 10bit) je prvni zpusob dostacujici, navic oproti vazenemu prumeru spotrebuje mnohem mene pameti a casu procesoru a dokaze reagovat na rychle zmeny signalu…

A přesně tohle se mi na tom nelíbí. Jestliže se vstup pohybuje v intervalu <10,14> potom lze očekávat výslednou hodnotu 12, nikoliv 10. Když je nějaká měřená veličina zatížena šumem, hodnoty by měly fluktuovat symetricky kolem přesné hodnoty. Ve vašem případě se posouvá zcela nepochybně dolů. Se zvyšujícím šumem se výsledek bude snižovat, což je špatně a při jisté výši to stejně způsobí přeblikávání. Proto jsem psal, že by chování vašeho “filtru” mělo být stejné pro růst jako pokles, tedy intervaly by měly být symetrické.
Pokud jde o složitos výpočtu aritmetického průměru, dovolím si tvrdit, že je jednodušší než vaše metoda. Provádí se prostým přičítáním hodnot z ADC do registru a po X vzorcích (např. 256) se suma vydělí, což jak tušíte je jen vzetí vyššího byte ze sumy.
Lze použít i exponenciální průměr, jehož chovní je stejné jako RC článek (dolní propust). Algoritmus není zas o tolik složitější a dává výborné výsledky.

Interval 0-4 je zvolen pro šum 2 bity (+ rezerva). Pokud je šum ještě větší, svědčí to o špatné kondici měřeného signálu. Vzpomínám si na praktické testování aritmetického průměrování 256-ti vzorků, jako by to bylo včera. To je velmi dobrý způsob pro právě příliš velký šum. Výsledek ale stále vykazuje pohyb na LSB. Vezmeme už zmiňovaný vstupní signál 10 až 14. Pozor, šum není nikdy konstantní! Proto výsledky po průměrování budou stále poskakovat kolem 12-ti. Mohl bych zde vypsat 3 série hodnot po 256-ti vzorcích v rozsahu 10 až 14, a všechny 3 průměry budou jiné. Ještě k symetrickému vyhodnocování. Také už jsem to zkoušel. Nepatrně lepší výsledek je vykoupen neúměrně složitějším programem.
Všechny teoretické výpočty a návrhy jsou jenom teorie dokud se to nevyzkouší v praxi.

Neúměrně složitý algortmus je přičtení 2 před použitím Vašeho algoritmu, aby se z něj stal symetrický. :smiley:
Ta poslední věta na mě působí jeko červený hadr na býka. Většinou něco takového pronese ten, kdo matematice nerozumí, nebo s ní nechce mít nic společného, protože ho nebaví. Mnoho věcí v elektronice a nejen v ní, vychází z teorií, které se matematicky popíšou a ověří se jejích správnost. Teprve pak se přistupuje k nějakým praktickým pokusům, které mají teorii ověřit. Co se týče zpracování signálu, není třeba už dělat žádnou vědu, ono je to už dávno všechno spočítano a milionkrát v praxi ověřeno. Stačí to jen nastudovat.
Pokud to po průměrování přeblikává, může být chyba v samoném algoritmu, nebo signál není zašuměn, ale je rušen nějakou frekvencí, která způsobuje aliasing. Mimochodem přeblikávání nemusí být chyba, je to přirozená odezva na měnící se signál.

Nevím už, jak bych to srozumitelněji vysvětlil.
Vezměte si nekonečnou řadu náhodných vzorků v rozsahu 10 až 14. Každých 256 vzorků sečtěte a vydělte 256-ti.
Nelze přeci očekávat, že výsledné hodnoty budou stále 12. Nepotřebuji střední hodnotu, potřebuji odstranit právě toto chvění aby nejnižší řád na displeji neposkakoval. V tomto případě bude výstup filtru držet hodnotu 10. Způsobená chyba je pro běžné aplikace zanedbatelná. Regulátory teploty, tlaku, vlhkosti a pod. Pokud je to nutné, může se s chybou počítat v následných výpočtech.

Omlouvám se všem odborníkům i laikům, jako jsem já.
V úvodním článku mám napsáno:
Po každém AD převodu porovnám novou hodnotu se starou hodnotou z minulého převodu.
Má tam být:
Po každém AD převodu porovnám novou hodnotu se starou hodnotou (s minulým výstupem).
Děkuji za pochopení.

Máš možnost editovat své předchozí příspěvky, takže si to klidně oprav.

To je stejné jako když házítke kostkou. Pravděpodobnost, že padne 6 je 1/6. Stejná pravděpodobnost je i pro ostatní čísla. Tedy pokud jde o náhodný hod, nikoliv nějaký našvindlováný.
A stejné je s tou řadou náhodných čísel. Pravděpodobnost hodnoty 10 je stejná jako 14, takže v sumě bude stejný počet 10 a 14. Ty lze spárovat a jejich průměr je 12. Stejné je to i s 11 a 13. Obě čísla mají též stejnou pravděpodobnost. Podotýkám, že jde o nekonečné množství dat. Pro 256 hodnot už nemusí být počet 10 stejný jako 14, proto v sumě nevyjde 12,000 , ale třeba 12,056. Číslo je třeba zaokrouhlit na nejbližší celou hodnotu, což je 12, aby výsledek odpovídal rozlišení ADC.

A ještě jedna věc tu hraje důležitou roli. Rychlost vzorkování a doba. Podle Nyquistova kritéria můsí být maximální frekvence na vstupu ADC poloviční než je rychlost vzorkování. To platí i pro šum. Takže na vstupu musí být nějaký analogový filtr. Nelze to suplovat nějakým digitálním filterm! Druhá věc je doba, po kterou se sbírájí vzorky pro výpočet. Mají-li se potlačit rušivé frekvence (např. 50Hz), musí se data sbírat alespoň po dobu jedné periody nejnižší rušivé frekvence. Takže když se to vše zohlení, tak těch 256 vzorků možná ani nebude stačit.

Na příkladu náhodných čísel (v rozsahu 10 až 14) jsem chtěl ukázat, jaký maximální šum (rozkmit), je filtr schopen zachytit. Vstupní signál nemusí mít tak velký rozkmit. A navíc, nevíme minimální ani maximální hodnotu. Takže se to nedá srovnávat s házením kostkou.
Nyquistova kritéria jsou důležitá například při digitalizaci zvuku nebo pro AD převodník v osciloskopu. Pro takové případy je samozřejmě filtr nevhodný.