Fórum témák
» Több friss téma |
Üdv,
a következő méréstechnikai problémán gondolokozok már egy ideje és sajnos még nem találtam meg a választ. Egy AVR kontroller A/D átalakítójával mérek egy hőmérséklettel arányos analóg jelet 0-5V -os tartományban. A következő két átlagolási módszer hatékonysága között nem tudok relációt állítani. Ha az A/D kimenetét egy X valószínűségi változóként értelmezem, mely változó a [0,1023] közötti egész számokat veszi fel. A hőmérsékeletet állandónak tekintve, M várható értékkel és S2 szórásnégyzettel. Az első módszer, hogy veszek 100 mintát, majd kiszámolom az átlagát és azt veszem az A/D mérés eredményének. A második módszer, hogy veszek 10 mintát és kiszámolom az átlagukat, majd ezt megismétlem még kilencszer. Ekkor van 10 darab 10 mintás átlag, végül az átlagoknak veszem az átlagát és ez lesz a mérés eredménye. Ha X értékei függetlenek és azonos eloszlásúak, akkor a két módszer ugyanazt a várható értéket és szórásnégyzetet adja elvileg. A valóságban a két módszer várható értéke szerintem ugyan az lesz, de a szórásnégyzetben nem vagyok biztos, mivel nem biztos a minták függetlensége, valamint hogy a korrelációja egyenlő nullával. Ha valakinek van tapasztalata vagy ötlete a felvetéssel kapcsolatban kérem ossza meg velem. Üdvözlettel, nrg
A leírt módszereket még nem alkalmaztam, de kifejezetten hőmérséklet-átlagolásra én a következőt szoktam: adott mondjuk 100 minta, elsőként kidobom a 10 legkisebb, és 10 legnagyobb értéket (gyakorlatilag ez a tranziensek elleni szoftveres védelem), a maradék 80-ból pedig egyszerű átlagot számítok.
Terem- illetve olajhőmérsékletek figyelésénél teljesen bevált, másodpercenként frissül a végeredmény - kérdés persze, hogy neked mi a célod ezzel, egyes területeken az így adódó pontatlanság már kritikus lehet.
Hali!
Csatlakoznék az előttem szólóhoz, érdemes valamilyen módon szanálni a mért értékek közt. Persze ilyenkor érdemes eldönteni, hogy melyikeket kell eldobni. Aztán elég egy egyszerű átlagszámítás a maradék értékekből. Ha részletesebb dolgok kellenek, akkor pedig talán érdemes lenne a mért értékeket valamilyen módon ábrázolni és az átlag vonalat pedig behúzni így látható lenne hol mekkora eltérés van. Persze a kérdés nálam is az: mire szeretnéd ezt alkalmazni.
Köszönöm a válaszokat,
semmi különös, csak egy hőmérőt készítettem 0 - 60 °C közötti tarományra. Csupán elméletileg érdekel a dolog, melyik módszertől várhatok jobb eredményt, illetve hogy van-e egyáltalán különbség a két módszer között.
A száz adat átlaga vagy a 10-szer tíz adat átlagának átlaga matematikailag azonos.
Ez volt a véleményem nekem is, amíg valaki el nem bizonytalanított, azzal hogy a második módszer szórásnégyzete kisebb mint az elsőé.
Sziasztok!
Ezen igen érdekes kérdés lett szerintem. Ha nem tévedek, akkor ez a probléma belefér az ergodikus folyamatok témakörbe. Ugye, ami azt vizsgálja, hogy ha egyetlen realizáció áll rendelkezésünkre, akkor mikor fog az idő szerinti átlag megegyezni a sokaság szerinti átlaggal. Azaz, ha megfelelően sok mintánk van, akkor a távoli minták függetlenek lesznek egymástól. Ebben az esetben a függvényt megfelelő hosszúságú darabokra felvágva, a függvény darabokon végzett átlagolás meg fog egyezni a teljes függvényen végzett átlagolással. A te esetedben, szerintem, lehet, hogy a 10 minta kevés, mert a következő 10 minta nem lesz független teljesen az előzőtől, túl nagy lesz a koreláció a két regisztrátum között. Hát én a tanulmányaimból erre emlékszem.
Szia!
Átlag - Várható érték: Szórás: Ha a 100 mintát 10 darab 10-es csoportból számítod, az átlag és a szórásnégyzet is ugyan az lesz. Az átlagnál a részátlagok közös nevezője 10, 10 darab átlagot adsz össze, még osztadod kell 10-zel, azaz ugyan az, mintha a 100 elemet összeadod és az eredményt osztod 100-zal. Hasonlóan alakul a szórásnál is. Szia
Izgalmas téma! Az ötlet tetszik. Milyen algoritmussal lehet min-maxot válogatni, mondjuk 100 mintából? Egy konkrét C megoldásnak örülnék. Nem gondolom, hogy valamilyen algoritmussal sorba kéne rendezni a tömb elemeit (például buborék rendezés) és abból a 5-5 elemet eldobni, mert akkor a konverzió hosszúra nyúlna. Biztosan létezik valamilyen faék egyszerűségű rutin. :miaz:
Mivel nem tudod mi számít kicsinek és mi nagynak (mire ezt megkeresnéd így is úgy is végig kellene menni az adathalmazon), így sajnos marad a sorba rendezés. Eközben már elkezdheted szummázni is az adathalmazt, ezzel már közel kerül a megoldás, a végén már csak ki kell vonni a szummából amit eldobsz és egy osztás után a kezedben az eredmény.
gyorsan összedobtam egy C függvényt, hogy hogyan gondoltam első körben ezt a kiválogató függvényt. Igaz ez is végigfut párszor a tömbön, de még mindig kevesebbszer mintha sorba kellene rendezni az egészet. A kinullázott értékek nem fognak beleszámítani az átlagolásba, mert 0-kat adunk hozzá az átlaghoz és végül nem 100-al, hanem csak 90-el osztjuk el.
Várom az esetleges ötleteket a kóddal kapcsolatban.
Szerintem nagyon jó az ötleted, sokkal hatékonyabb, kisebb, és gyorsabb, mint a sorbarendezéses megoldás.
Az A/D bemenetről mentett értékeknél szerény véleményem szerint nincs értelme lebegőpontos (azaz 32 bites) számokat alkalmazni. Bőven elég egy sima mezei 2 bájtos integer, a maga 16 bitjével: 65536 egymástól különböző állapot. 16 bites A/D-je talán egy PIC-nek sincs. Így biztosan több hely maradna más műveletekre is, vagy bármi másra...
Ha 100 számos összeadást csinálsz, ott az aktuális mérést (ADC - 16 bit) hozzáadhatod egy unsigned long int-hez(32 bit) + kell még egy osztó(8 bit). De az ADC-t nem kell tárolni, így nem kell a regiszter értékét elmenteni.
Én ilyenre (mért hőmérsékletértékek simítása) egyszerűen digitális aluláteresztő szűrőt alkalmaztam. Egy hőmérsékletváltozás úgysem túl gyors folyamat, tehát eléggé alacsonyra lehet méretezni a szűrő töréspontját. A hőmérsékletszabályozós PIC-es pákámban is ilyen dolgozik.
Ha a mintavétel rendszeres (periodikus), akkor lehet számolni mindenféle paraméterű digitális szűrőket a feladathoz. Ha már úgyis használunk lebegőpontos számokat a programunkban, akkor talán egyszerűbb például egy másodfokú szűrőhöz szükséges 4 értéket eltárolni, mint többtíz vagy többszáz mintával FIFO-zni (ha pl. csúszóátlagot akarunk számolni). Nekem sokkal jobb tapasztalatom volt a mérési eredmények digitális szűrővel történő kisimításával kapcsolatosan, mint amikor 32-64 mintából próbáltam átlagokat számolgatni. Az alábbi oldalon interaktívan lehet digitális szűrőket terveztetni, sőt, még a C forráskódot is legenerálja: mkfilter
A memóriafoglalás az algoritmustól is függ. Ha pl. nem akarsz eldobni (nrg megoldásához hasonlóan) értékeket, akkor az AD konverziók eredményét egyből egy változóhoz hozzáadhatod, és nem kell mindet külön tárolni.... Ha viszont "selejtetzni" is akarsz az értékek közül, akkor jó a meglátásod, nyilván nem mindegy, hogy tizes vagy százas csoportokat dolgozol fel....
Sorbarendezés talán a leggyorsabb:
Ha N a tömb legnagyobb indexe, és 0-val kezdődik, akkor egy lehetséges megoldás: Eztán lehet átlagolni. for(i=0;i<=N-1;i++) for(j=i+1;j<=N;j++) { if(tomb[i]>tomb[j]) csere(i,j); }>
Igen csak megint az Ordoval van a gond...
Szilva megoldása szimpatikus, erősen gondolkodok rajta, hogy ki kéne próbálgatni...
Amit beuírtál az az un. buborék módszer. Ez lehet, hogy egszuerü algoritmus, de a rendezési elvek között a leglassúbb. Jóval gyorsabb az un. minimum kiválasztásos rendezés, de nrg módszere még jobb - mert eléggé feladatspecifikus.
Rendezés szempontjából pedig a qsort a leggyorsabb, és C-ben általában van rá gyári függvény.
Igen erről van szó ő a buborék, a qsort viszont mikrovezérlőknél általában hiányzik, így mindenkinek magának kell írni algoritmust, mivel kevés általában a memória így a legkevésbé memóriaigényest kell használni.
Legegyszerűbb esetben egy rekurzív átlagolással meg lehet oldani.
Rekurzív módon előállított átlag előnye, hogy nem kell az összes mintát tárolni, így memóriát és számítási időt takarítunk meg. Vagy a csúszóablakos átlagolás, ami szintén felírható rekurzív módon.
A fejemben már megvan a képe egy algoritmusnak ami ugyanazt az eredményt adja mint az előző függvény, de nem tárolja el egy 100-as int tömbben a mért eredményeket. Ha lesz egy kis időm akkor megpróbálom lekódolni..
Simán megoldható amit mondasz, elég csak az aktuális 5 legkisebb, és 5 legnagyobb adatot tárolni. Csak shiftelni kell ezeket ha a legkisebbnél kisebb v. a legnagyobbnál nagyobb adat érkezik, persze nem is muszály shiftelni csak eldobni amelyik az 5-ből kiesik, és a helyére tenni az uj értéket....
Azt nem tudtam, hogy nincs kész qsort mikrovezérlőre. Viszont a minimumkiválasztásos rendezés nem bonyolultabb a buboréknál, viszont az is sokkal gyorsabb nála....
Így van, pont ilyen algoritmusra gondoltam én is. Akkor ezekszerint megspóroltam a lekódolását
Sajnos nem érem el azt a gépet, ahol ezek a kódok vannak, de megpróbáltam fejből reprodukálni.
A módszer nem az egy ciklusban összegyűjtött mintákon végez egy nagy, egyszeri válogatást, hanem minden mérés után néhány kisebbet. Az adatok alsó és felső értékeinek címeit tartalmazó tömbök folyamatosan frissülnek, minden konverzió után, így mire a mérési ciklus végén átlagolni kell, már nem lesz szükség a teljes adattömb sorbarendezésére, válogatására. Gyakorlati okokból én 80 mintát szoktam venni egy ciklusban, azokból 8-8 szélsőértéket kidobok, a végén pedig csak 64-el osztva kell átlagot számolnom. Ez (nekem) azért jó, mert osztás helyett hatszor jobbra léptetem az összeget tartalmazó regisztereket, és elkerülhetem a lebegőpontos számítást. Még talán annyit, hogy ha megszakításban megy a konverziós értékek olvasása, tömbfrissítés stb., célszerű a megszakításokat tiltani, amikor mondjuk LCD-re ír az ember valamit, nehogy gond legyen a verem-mérettel, vagy az időzítésekkel. Főbb lefoglalt területek: három tömb, egy a mérési adatoknak, kettő kisebb a szélsőértékeknek data[]: mérési adatok helye, annyi eleme van, amennyit egy ciklusban átlagolni szeretnénk, legyen most 100 max[]: legnagyobb mérési adatok címei, elemeinek száma annyi, amennyit a "nagyok" közül ki akarunk dobni, legyen 10 min[]: legkisebb mérési adatok címei, elemeinek száma annyi, amennyit a "kicsik" közül ki akarunk dobni, legyen 10 Nem deklaráltam változókat és függvényeket, csak az elvet akartam bemutatni. Alkalmazás előtt célszerű legalább a max[] és min[] tömbök inicializálása, nehogy valami végzetes történjen egy rossz címre való írás miatt.
Nagyon köszönöm! Izgalmas, le fogom tesztelni gyakorlatban is. Ha mégis előkerül a link, megköszönném.
|
Bejelentkezés
Hirdetés |