Monday 20 November 2017

Moving Average Circular Buffer


Ek het 'n vektor van strukture wat 'n stroom van waardes wat kom by verskillende intervalle stoor. Die struktuur bestaan ​​uit twee elemente. een vir die waarde en die ander rekords van die tyd wanneer die waarde aangekom. Kom ons sê dat in 'n ander draad wil ek die bewegende gemiddelde van die waardes wat aangekom het in die laaste 10 (sê) sekondes te bereken. So in 'n draad die vektor word bevolk en in 'n ander wil ek die bewegende gemiddelde te bereken. Sou 'n paar help gevra 14 Mei 15 waardeer om 9:00 As jy reeds besluit het dat 'n mens draad altyd sal vul en 'n ander draad sal doen bewegende gemiddelde. Jy kan dit dan doen: Hou 'n struktuur met twee elemente RunningSum en geen items in vektor. Skryf 'n lus wat elemente wat ouer as 10 sek is en hul waardes af te trek van RunningSum verwyder. Alle elemenst in vektor gesorteer op timeofArrival, so jy hoef nie Itereer die hele vektor. Voeg by die waarde van nuwe elemnts wat nog nie bygevoeg som. Jy moet 'n manier om items wat bygevoeg deffrentiate (wat in som) en die een wat nog nie opgesom. Jy kan 'n Boole gebruik vir hierdie of sit dit in 'n nuwe dataStructure (interne om jou klas). Hou telling van verskeie elemente en bereken die average. The Scientist en Ingenieurs Guide to Digital Signal Processing Deur Steven W. Smith, Ph. D. Hoofstuk 28: Digitale Seinverwerkers Digitale Seinverwerkers is ontwerp om vinnig uit te voer FIR filters en soortgelyke tegnieke. Om die hardeware te verstaan. Ons moet eers verstaan ​​die algoritmes. In hierdie afdeling sal ons 'n gedetailleerde lys van die stappe wat nodig is om 'n FIR filter implementeer. In die volgende afdeling sal ons kyk hoe ADV is ontwerp om te werk so doeltreffend as moontlik uit te voer. Om mee te begin, moet ons onderskei tussen off-line verwerking en real-time verwerking. In off-line verwerking, die hele insetsein woonagtig is in die rekenaar op dieselfde tyd. Byvoorbeeld, kan 'n geofisikus n seismometer gebruik om die grond beweging aan te teken tydens 'n aardbewing. Na afloop van die skudding is verby, kan die inligting gelees in 'n rekenaar en een of ander manier ontleed. Nog 'n voorbeeld van off-line verwerking is mediese beeldvorming, soos rekenaar tomografie en MRI. Die datastel verkry terwyl die pasiënt is binne-in die masjien, maar die beeld rekonstruksie kan vertraag word tot 'n later tyd. Die belangrike punt is dat al die inligting is gelyktydig beskikbaar vir die verwerking program. Dit is algemeen in wetenskaplike navorsing en ingenieurswese, maar nie in die verbruikers produkte. Off-line verwerking is die koninkryk van persoonlike rekenaars en hooframe. In real-time verwerking, is die uitset sein geproduseer terselfdertyd dat die insetsein word verkry. Byvoorbeeld, is dit nodig om in telefoon kommunikasie, gehoortoestelle, en radar. Hierdie aansoeke moet die inligting onmiddellik beskikbaar, hoewel dit kan uitgestel word deur 'n kort bedrag. Byvoorbeeld, kan 'n 10 millisekonde vertraging in 'n telefoonoproep nie opgespoor word deur die spreker of luisteraar. Net so, dit maak geen verskil as 'n radar sein vertraag deur 'n paar sekondes voordat dit vertoon word om die operateur. Real-time aansoeke insette 'n monster, voer die algoritme, en uitset 'n monster, oor-en-oor. Alternatiewelik kan hulle insette 'n groep van monsters, voer die algoritme, en uitset 'n groep van monsters. Dit is die wêreld van digitale seinverwerkers. Nou kyk terug op Fig. 28-2 en dink dat dit 'n FIR filter in real-time geïmplementeer. Om die uitset monster te bereken, moet ons toegang tot 'n sekere aantal van die mees onlangse voorbeelde van die insette het. Byvoorbeeld, veronderstel ons gebruik agt koëffisiënte in hierdie filter, 'n 0. 'n 1. hellip n 7. Dit beteken ons moet die waarde van die agt mees onlangse monsters van die insetsein, x n, x n -1, hellip x N -7 weet. Hierdie agt monsters moet gestoor word in die geheue en voortdurend bygewerk word as nuwe monsters verkry. Wat is die beste manier om hierdie gestoor monsters Die antwoord is omsendbrief buffer bestuur. Figuur 28-3 illustreer 'n agt monster omsendbrief buffer. Ons het hierdie omsendbrief buffer geplaas in agt agtereenvolgende geheue plekke, 20041 om 20048. Figuur (a) toon hoe die agt monsters van die insette kan gestoor word op 'n bepaalde tydstip, terwyl (b) die veranderinge toon na die volgende voorbeeld is verkry. Die idee van omsendbrief buffer is dat die einde van hierdie lineêre skikking verbind om sy begin geheue plek 20.041 beskou as langs 20048, net soos 20044 is langs 20045. Jy hou van die skikking deur 'n wyser ( 'n veranderlike waarvan waarde is 'n adres) wat aandui waar die mees onlangse voorbeeld woon. Byvoorbeeld, in (a) die wyser bevat die adres 20044, terwyl dit in (b) dit bevat 20045. Wanneer 'n nuwe monster verkry word, is dit die plek van die oudste voorbeeld in die skikking, en die wyser een adres vorentoe beweeg. Omsendbrief buffers is doeltreffende, want net een waarde verander moet word wanneer 'n nuwe monster verkry word. Vier parameters is nodig om 'n omsendbrief buffer bestuur. In die eerste plek moet daar 'n wyser wat die begin van die omsendbrief buffer in die geheue (in hierdie voorbeeld, 20041) dui wees. In die tweede plek moet daar 'n wyser wat die einde van die skikking (bv 20048), of 'n veranderlike wat sy lengte hou nie (bv 8). Derde, moet die stap grootte van die geheue aanspreek gespesifiseer word. In Fig. 28-3 die stap grootte is een. byvoorbeeld: aanspreek 20043 bevat 'n monster, spreek 20044 bevat die volgende voorbeeld, en so aan. Dit is dikwels nie die geval nie. Byvoorbeeld, kan die aanspreek verwys na grepe, en elke monster kan twee of vier grepe benodig om die waarde daarvan te hou. In hierdie gevalle, sal die stap grootte moet twee of vier, onderskeidelik te wees. Hierdie drie waardes definieer die grootte en opset van die omsendbrief buffer, en sal nie verander gedurende die program operasie. Die vierde waarde, die wyser na die mees onlangse voorbeeld, moet verander word soos elke nuwe monster verkry word. Met ander woorde, moet daar program logika wat beheer hoe dit vierde waarde is opgedateer op grond van die waarde van die eerste drie waardes wees. Terwyl hierdie logika is eenvoudig, moet dit baie vinnig wees. Dit is die hele punt van hierdie gesprek ADV moet geoptimaliseer word by die bestuur van omsendbrief buffers om die hoogste moontlike spoed uitvoering te bereik. As 'n eenkant, omsendbrief buffer is ook nuttig in off-line verwerking. Dink aan 'n program waar beide die inset en die uitset seine heeltemal vervat in die geheue. Omsendbrief buffer isnt wat nodig is vir 'n konvolusie berekening, want elke monster onmiddellik kan verkry. Daar is egter baie algoritmes geïmplementeer word in fases. met 'n intermediêre sein geskep tussen elke fase. Byvoorbeeld, 'n rekursiewe filter uitgevoer as 'n reeks van biquads bedryf op hierdie manier. Die brute krag metode is om die hele lengte van elke intermediêre sein in die geheue stoor. Omsendbrief buffer bied 'n ander opsie: winkel net die intermediêre monsters benodig vir die berekening byderhand. Dit verminder die vereiste bedrag van die geheue, ten koste van 'n meer ingewikkelde algoritme. Die belangrikste idee is dat omsendbrief buffers is nuttig vir off-line verwerking, maar van kritieke belang vir real-time programme. Nou kan ons kyk na die stappe wat nodig is om 'n FIR filter met behulp van omsendbrief buffers vir beide die insetsein en die koëffisiënte te implementeer. Hierdie lys mag triviaal lyk en overexamined - dit is nie die doeltreffende hantering van hierdie individuele take is wat skei 'n DSP van 'n tradisionele mikroverwerker. Vir elke nuwe monster, moet al die volgende stappe wat geneem moet word: Die doel is om te maak hierdie stappe uit te voer vinnig. Sedert stappe 6-12 baie keer sal herhaal word (een keer vir elke koëffisiënt in die filter), moet spesiale aandag gegee word aan hierdie bedrywighede. Tradisionele mikroverwerkers moet oor die algemeen uit te voer hierdie 14 stappe in serie (een na die ander), terwyl ADV is ontwerp om hulle uit te voer in parallel. In sommige gevalle, kan al die bedrywighede binne die lus (stappe 6-12) in 'n enkele kloksiklus voltooi. Kom ons kyk na die interne argitektuur wat dit moontlik maak hierdie pragtige performance. I weet dit is haalbaar met hupstoot volgens: Maar ek wil graag om te verhoed dat die gebruik van hupstoot. Ek het googled en nie gevind nie enige geskikte of leesbare voorbeelde. Eintlik wil ek die bewegende gemiddelde van 'n deurlopende stroom van 'n stroom van drywende punt getalle met behulp van die mees onlangse 1000 getalle as 'n data monster op te spoor. Wat is die maklikste manier om dit wat ek eksperimenteer met die gebruik van 'n omsendbrief skikking, eksponensiële bewegende gemiddelde en 'n meer eenvoudige bewegende gemiddelde en bevind dat die resultate van die omsendbrief array geskik my behoeftes beste te bereik. gevra 12 Junie 12 aan 04:38 As jou behoeftes is eenvoudig, kan jy net probeer om met behulp van 'n eksponensiële bewegende gemiddelde. Eenvoudig gestel, jy maak 'n akkumulator veranderlike, en as jou kode kyk na elke monster, die kode updates die akkumulator met die nuwe waarde. Jy kies 'n konstante alfa wat tussen 0 en 1, en bereken die volgende: Jy hoef net 'n waarde van alfa vind waar die effek van 'n gegewe voorbeeld net duur vir ongeveer 1000 monsters. Hmm, Ek is nie eintlik seker dit is geskik vir jou, noudat Ive het dit hier. Die probleem is dat 1000 is 'n mooi lang venster vir 'n eksponensiële bewegende gemiddelde Ek is nie seker daar is 'n alfa dat die gemiddelde van die afgelope 1000 getalle sou versprei, sonder onderloop in die drywende punt berekening. Maar as jy 'n kleiner gemiddelde, wou soos 30 nommers of so, dit is 'n baie maklike en vinnige manier om dit te doen. antwoord 12 Junie 12 by 04:44 1 op jou post. Die eksponensiële bewegende gemiddelde kan nie toelaat dat die alfa tot wisselvallig wees. So dit kan dit gebruik word om tyd basis gemiddeldes bereken (bv grepe per sekonde). As die tyd sedert die laaste akkumulator update is meer as 1 sekonde, jy laat Alpha wees 1.0. Anders, kan jy laat Alpha wees (usecs sedert verlede update / 1000000). â € jxh 12 Junie 12 aan 06:21 Eintlik wil ek die bewegende gemiddelde van 'n deurlopende stroom van 'n stroom van drywende punt getalle met behulp van die mees onlangse 1000 getalle as 'n data monster op te spoor. Let daarop dat die onderstaande updates die totale soos elemente soos bygevoeg / vervang, vermy duur O (N) traversal om die som te bereken - wat nodig is vir die gemiddelde - op aanvraag. Totaal gemaak 'n ander parameter van T te ondersteun bv met behulp van 'n lang lang wanneer altesaam 1000 lank s, 'n int vir char s, of 'n dubbel totale float s. Dit is 'n bietjie gebrekkig deurdat numsamples kon verby INTMAX - as jy omgee wat jy kan gebruik om 'n unsigned long lank. of gebruik 'n ekstra Bool data lid aan te teken wanneer die houer eerste gevul terwyl fietsry numsamples rondom die skikking (beste herdoop dan iets onskuldig soos POS). antwoord 12 Junie 12 aan 05:19 aanvaar word dat quotvoid operateur (T monster) quot is eintlik quotvoid operatorltlt (T monster) quot. â € oPless 8 Junie 14 by 11:52 oPless ahhh. goed raakgesien. eintlik het ek bedoel dat dit nietig operateur () (T monster), maar natuurlik jy kan gebruik wat ook al notasie jy graag. Sal los, te danke. â € Tony D 8 Junie 14 by 14: 27Intro Een van die belangrikste programme vir die Arduino raad is om te lees en aan te meld van sensor data. Byvoorbeeld een monitors druk elke sekonde van die dag. So hoog monster pryse genereer dikwels spykers in die grafieke een wil ook 'n gemiddeld van die metings het. As die afmetings is nie staties in die tyd wat ons dikwels nodig is 'n lopende gemiddelde. Dit is die gemiddeld van 'n sekere tydperk en baie waardevol wanneer jy tendens analise. Eenvoudigste vorm van 'n lopende gemiddelde kan gedoen word deur kode wat voortbou op die vorige hardloop gemiddelde: As 'n mens nie die geval is wil gebruik drywende punt wiskunde - want dit neem geheue en verminder spoed - 'n mens kan dieselfde heeltemal te doen in die heelgetal domein. Die afdeling deur 256 in die voorbeeld kode is 'n verskuiwing regs 8, wat is vinniger as sê afdeling deur bv 100. Dit is waar vir elke krag van 2 as deler en een net sorg die som van die weigths is gelyk aan die krag van 2. En natuurlik moet 'n mens versigtig wees daar geen intermediêre oorloop (oorweeg die gebruik van unsigned long) As jy moet neem 'n meer akkurate loop gemiddeld in concreto van die laaste 10 metings, 'n skikking (of gekoppel lys) om hulle te hou nodig. Dit verskeidenheid dien as 'n omsendbrief buffer en met elke nuwe meting die oudste een is verwyder. Die lopende gemiddeld word bereken as die som van al die elemente verdeel deur die aantal elemente in die skikking. Die kode vir die lopende gemiddeld sal so iets wees: nadeel van hierdie kode is dat die skikking te alle waardes hou nogal groot kan word. As jy 'n meting per sekonde en jy wil 'n lopende gemiddelde per minuut jy 'n verskeidenheid van 60 moet 'n gemiddelde per uur sou 'n verskeidenheid van 3600. Dit kon nie op hierdie manier op 'n Arduino gedoen want dit het net 2K RAM nodig. Maar met die bou van 'n 2 stadium gemiddelde dit kan baie goed benader word (disclaimer: nie vir alle metings). In psuedo kode: As 'n nuwe interne statiese skikking is wat nodig is vir elke runningAverage funksie, hierdie skree as 'n klas te implementeer. RunningAverage biblioteek Die runningAverage biblioteek maak 'n klas van die funksie hierbo sodat dit meer as een keer gebruik kan word in 'n skets. Dit ontkoppelt dié byvoeging () en die gemiddelde () funksie gee om 'n bietjie meer buigsaam bv wees 'n mens kan die gemiddelde verskeie kere bel sonder toevoeging van 'n ding. Let asseblief daarop dat elke geval van die klas voeg sy eie reeks om metings te hou, en dat dit bydra tot die geheue gebruik. Die koppelvlak van die klas is so klein as moontlik gehou word. Let wel: met weergawe 0.2 die name van die metodes is almal gemaak meer beskrywende. Gebruik 'n klein skets toon hoe dit gebruik kan word. 'N ewekansige kragopwekker gebruik word om 'n sensor naboots. In die opstel van () die Myra is skoongemaak sodat ons kan begin toevoeging van nuwe data. In lus () eers 'n ewekansige getal gegenereer en omgeskakel word na 'n float toe te voeg aan Myra. Toe die runningAverage gedruk om die reeksnommer poort. 'N Mens kan ook vertoon dit op 'n paar LCD of stuur oor Ethernet ens Wanneer 300 items bygevoeg Myra is skoongemaak weer begin. Aantekeninge by die biblioteek te gebruik, maak 'n gids in jou SKETCHBOOKPATHlibaries met die naam RunningAverage en sit die. H en Cpp daar. Opsioneel 'n voorbeelde subgids om die monster app te plaas. Geskiedenis 2011/01/30: aanvanklike weergawe 2011/02/28: Vaste ontbreek destructor in. H lêer 2011/02/28: verwyder verstek konstruktor 2012--. trimValue () Yuval Naveh bygevoeg trimValue (gevind op web) 2012/11/21: refactored 2012/12/30: gevoeg fillValue () refactored vir die publikasie van 2014/07/03: gevoeg geheue beskerming kode - as interne skikking nie kan toegeken word grootte word 0. Dit is om probleem hier beskryf los - forum. arduino. cc/indextopic50473.msg1790086msg1790086 - Todo toets op groot skaal. Sjabloon klas RunningAverage. H RunningAverage. cppAs ander genoem het, moet jy 'n IIR (oneindige impulsrespons) filter eerder as die FIR (eindige impulsrespons) filter jy is nou met behulp oorweeg. Daar is meer as dit, maar met die eerste oogopslag FIR filters word toegepas as eksplisiete konvolusie en IIR filters met vergelykings. Die besondere IIR filter Ek gebruik 'n baie in mikrobeheerders is 'n enkele paal laaglaatfilter. Dit is die digitale ekwivalent van 'n eenvoudige R-C analoog filter. Vir die meeste aansoeke, sal hierdie beter eienskappe as die boks filter wat jy gebruik het. Die meeste gebruike van 'n boks filter wat ek teëgekom het is 'n gevolg van iemand nie aandag in digitale seinverwerking klas, nie as gevolg van die behoefte van hul besondere eienskappe. As jy net wil 'n hoë frekwensies dat jy weet is geraas te verminder, 'n enkele paal laaglaatfilter is beter. Die beste manier om 'n digitaal te implementeer in 'n mikrobeheerder is gewoonlik: filt lt-- filt VF (NEW - filt) filt is 'n stukkie van die aanhoudende staat. Dit is die enigste aanhoudende veranderlike wat jy nodig het om hierdie filter te bereken. NUWE is die nuwe waarde wat die filter word opgedateer met hierdie iterasie. VF is die filter fraksie. wat pas 'n bekommernis vir die filter. Kyk na hierdie algoritme en sien dat vir 0 VF die filter is oneindig swaar sedert die uitset verander nooit. Vir 1 VF, sy werklik geen filter glad sedert die uitset volg net die insette. Nuttige waardes van die twee. Op klein stelsels haal jy VF om 1/2 N wees sodat die vermenigvuldig met VF bereik kan word as 'n reg verskuiwing deur N stukkies. Byvoorbeeld, kan VF wees 16/1 en die vermenigvuldig met VF dus 'n reg verskuiwing van 4 stukkies. Andersins hierdie filter moet net een aftrek en een byvoeging, hoewel die getalle gewoonlik nodig om wyer as die invoerwaarde (meer op numeriese presisie in 'n aparte afdeling hieronder) wees. Ek neem gewoonlik A / D lesings aansienlik vinniger as dit nodig is en pas twee van hierdie filters kaskade. Dit is die digitale ekwivalent van twee R-C filters in reeks, en verswak met 12 dB / oktaaf ​​bokant die rolloff frekwensie. Maar vir A / D lesings sy gewoonlik meer relevant om te kyk na die filter in die tydgebied deur die oorweging van sy stap reaksie. Dit vertel jou hoe vinnig jou stelsel 'n verandering sal sien wanneer die ding is wat jy meet veranderinge. Om die ontwerp van hierdie filters (wat net beteken pluk VF en besluit hoeveel van hulle waterval) te fasiliteer, ek gebruik my program FILTBITS. Jy gee die aantal verskuiwing stukkies vir elke VF in die kaskade reeks filters, en dit bere die stap reaksie en ander waardes. Eintlik het ek gewoonlik loop dit via my wrapper script PLOTFILT. Dit loop FILTBITS, wat 'n CSV-lêer maak, dan plotte die CSV. Byvoorbeeld, hier is die resultaat van PLOTFILT 4 4: Die twee parameters om PLOTFILT beteken daar twee filters kaskade van die hierbo beskryf tipe. Die waardes van 4 dui die aantal verskuiwing stukkies om die vermenigvuldig met VF besef. Die twee VF waardes is dus 1/16 in hierdie geval. Die rooi spoor is die eenheid stap reaksie, en is die belangrikste ding om te kyk na. Byvoorbeeld, hierdie vir jou vertel dat as die insette onmiddellik verander, die opbrengs van die gekombineerde filter sal vestig tot 90 van die nuwe waarde in 60 iterasies. As jy omgee vir 95 wegsterftyd dan moet jy wag sowat 73 iterasies, en vir 50 wegsterftyd slegs 26 iterasies. Die groen spoor wys jou die uitset van 'n enkele volle amplitude piek. Dit gee jou 'n idee van die ewekansige geraas onderdrukking. Dit lyk soos geen enkele voorbeeld meer as 'n 2.5 verandering in die uitset sal veroorsaak. Die blou spoor is 'n subjektiewe gevoel van wat hierdie filter doen met 'n wit geraas te gee. Dit is nie 'n streng toets, want daar is geen waarborg wat presies die inhoud was van die ewekansige getalle opgetel as die wit geraas insette vir hierdie lopie van PLOTFILT. Sy net om jou 'n rowwe gevoel van hoeveel dit sal platgedruk en hoe glad dit is. PLOTFILT, miskien FILTBITS, en baie van die ander nuttige dinge, veral vir PIC firmware ontwikkeling is beskikbaar in die PIC Ontwikkeling tools sagteware vrylating op my bladsy sagteware afgelaai. Bygevoeg oor numeriese presisie Ek sien uit die kommentaar en nou 'n nuwe antwoord dat daar belangstelling in die bespreking van die aantal bisse wat nodig is om hierdie filter te implementeer. Let daarop dat die vermenigvuldig met VF log 2 (VF) sal skep nuwe stukkies onder die binêre punt. Op klein stelsels, is VF gewoonlik gekies om 1/2 N wees sodat dit vermeerder eintlik besef deur 'n regte verskuiwing van N stukkies. Filt is dus gewoonlik 'n vaste punt heelgetal. Let daarop dat hierdie een van die wiskunde nie die geval te verander van die verwerkers oogpunt. Byvoorbeeld, as jy die filter 10 bis A / D lesings en N 4 (1/16 VF), dan moet jy 4 fraksie stukkies onder die 10 bis integriteit A / D lesings. Een meeste verwerkers, youd doen 16 bis integriteit bedrywighede weens die 10 bis A / D lesings. In hierdie geval is, kan jy nog doen presies dieselfde 16 bis integriteit opertions, maar begin met die A / D lesings links verskuif deur 4 stukkies. Die verwerker nie die geval is die verskil en nie die geval is weet moet. Doen die wiskunde op hele 16 bit heelgetalle werk of jy dit as '12.4 vaste punt of ware 16 bit heelgetalle (16.0 vaste punt) wees. In die algemeen, moet jy N stukkies elke filter paal voeg as jy dit nie wil geraas voeg as gevolg van die numeriese verteenwoordiging. In die voorbeeld hierbo, sal die tweede filter van twee moet 1044 18 stukkies inligting nie verloor het. In die praktyk op 'n 8 bit masjien wat youd gebruik 24 bit waardes beteken. Tegnies slegs die tweede paal van twee sou die wyer waarde nodig nie, maar vir firmware eenvoud Ek gebruik gewoonlik dieselfde verteenwoordiging, en sodoende dieselfde kode, vir alle pole van 'n filter. Gewoonlik skryf ek 'n subroutine of makro een filter paal aksie uit te voer, dan aansoek doen dat elke paal. Of 'n subroutine of makro hang af of siklusse of program geheue is belangriker in daardie spesifieke projek. In ieder geval, ek gebruik 'n paar kras staat om nuwe pas in die subroutine / makro wat filt updates, maar ook belastings wat in dieselfde kras staat NUWE in. Dit maak dit maklik om verskeie pale toe te pas, aangesien die opgedateer filt van een pool is die NUWE van die volgende een. Wanneer 'n subroutine, sy nuttig om 'n wyser punt om filt op die manier, wat net ná filt op die pad uit is opgedateer. Op dié manier die subroutine bedryf outomaties op agtereenvolgende filters in die geheue as meer as een keer genoem. Met 'n makro hoef jy nodig het 'n wyser omdat jy slaag in die adres te werk op elke iterasie. Kode Voorbeelde Hier is 'n voorbeeld van 'n makro soos hierbo beskryf vir 'n PIC 18: En hier is 'n soortgelyke makro vir 'n PIC 24 of dsPIC 30 of 33: Beide hierdie voorbeelde is geïmplementeer as makros met behulp van my PIC assembler voorverwerker. wat is meer in staat is as een van die ingeboude makro fasiliteite. clabacchio: Nog 'n probleem wat ek moes genoem is implementering firmware. Jy kan 'n enkele paal laaglaatfilter subroutine keer skryf, dan pas dit meer as een keer. Om die waarheid te gewoonlik skryf ek so 'n subroutine om 'n wyser te neem in die geheue om die filter staat, dan is dit bevorder die wyser sodat dit kan genoem word in die reeks maklik om 'n multi-paal filters te realiseer. â € Olin Lathrop 20 April 12 by 15:03 1. Baie dankie vir jou antwoorde - almal van hulle. Ek het besluit om hierdie IIR Filter gebruik, maar dit Filter is nie gebruik word as 'n Standard laagdeurlaatfilter, want ek moet Counter Waardes gemiddeld en vergelyk kan word om veranderinge in 'n sekere omvang te spoor. aangesien hierdie waardes van baie verskillende dimensies afhangende van Hardware wees Ek wou 'n gemiddelde te neem ten einde in staat te wees om outomaties te reageer op hierdie Hardware spesifieke veranderinge. â € sensslen 21 12 Mei om 12:06 As jy kan lewe met die beperking van 'n bevoegdheid van twee aantal items te Gemiddeld (dws 2,4,8,16,32 ens) dan is die kloof kan maklik en doeltreffend gedoen word op 'n lae prestasie mikro sonder toegewyde verdeel, want dit kan gedoen word as 'n bietjie skuif. Elke skof reg is 'n krag van twee bv: Die OP het gedink hy het twee probleme, verdeel in 'n PIC16 en geheue vir sy ring buffer. Hierdie antwoord dui daarop dat die skeidslyn is nie moeilik. Toegegee dit spreek nie die geheue probleem, maar die SE stelsel kan gedeeltelike antwoorde, en gebruikers kan iets uit elke antwoord neem vir hulself, of selfs wysig en kombineer other39s antwoorde. Aangesien sommige van die ander antwoorde vereis dat 'n kloof werking, hulle is soortgelyk onvolledig omdat hulle nie wys hoe om doeltreffend hierdie op 'n PIC16 bereik. â € Martin 20 April 12 by 13:01 Daar is 'n antwoord vir 'n ware bewegende gemiddelde filter (aka wagon filter) met minder geheue vereistes, as jy verstand downsampling hoef. Die sogenaamde kaskade integreerder-kam filter (CIC). Die idee is dat jy 'n integreerder wat jy verskille oor 'n tydperk, en die sleutel-geheue te bespaar, is dat deur downsampling, dont jy elke waarde van die integreerder stoor. Dit kan toegepas word met behulp van die volgende pseudokode: Jou effektiewe bewegende gemiddelde lengte is decimationFactorstatesize maar jy moet net om statesize monsters te hou. Dit is duidelik dat jy kan 'n beter prestasie kry as jou statesize en decimationFactor magte van 2 is, sodat die afdeling en restant operateurs kry vervang deur skofte en masker-ands. Naskrif: Ek stem saam met Olin dat jy altyd in ag moet neem eenvoudig IIR filters voor 'n bewegende gemiddelde filter. As jy dit nie nodig het die frekwensie-nulls van 'n wagon filter, sal 'n 1-paal of 2-paal laaglaatfilter waarskynlik werk boete. Aan die ander kant, as jy die filter vir die doeleindes van uitkap (neem 'n hoë-monster-koers insette en gemiddeld dit vir gebruik deur 'n lae-koers proses) dan 'n CIC filter kan wees net wat jy soek. (Veral as jy statesize1 kan gebruik en heeltemal te vermy die ringbuffer met net 'n enkele vorige integreerder waarde) Daar is 'n paar in-diepte analise van die wiskunde agter die gebruik van die eerste orde IIR filter wat Olin Lathrop reeds oor beskryf op die Digitale Seinverwerking stapel ruil (sluit baie mooi foto's.) die vergelyking vir hierdie IIR filter is: dit kan toegepas word met behulp van slegs heelgetalle en geen verdeeldheid onder die volgende kode (dalk 'n debugging nodig as ek tik uit die geheue.) hierdie filter by benadering 'n bewegende gemiddelde van die laaste K monsters deur die oprigting van die waarde van alfa tot 1 / K. Doen dit in die voorafgaande kode deur te definieer ing BITS om log2 (K), dit wil sê vir K 16 stel BITS tot 4, vir K 4 stel BITS tot 2, ens (Ill verifieer die kode hier gelys word sodra ek 'n verandering te kry en hierdie antwoord wysig indien nodig.) antwoord 23 Junie 12 aan 04:04 Hier is 'n enkel-paal laaglaatfilter (bewegende gemiddelde, met afsnyfrekwensie CutoffFrequency). Baie eenvoudig, baie vinnig, werk baie goed, en byna geen geheue oorhoofse. Let wel: Alle veranderlikes omvang buite die filter funksie, behalwe die geslaag in newInput Nota: Hierdie is 'n enkele stadium filter. Veelvuldige fases kan saam kaskade die skerpte van die filter te verhoog. As jy meer as een stadium gebruik, sal jy moet DecayFactor pas (soos verwys na die afsny-Frequency) te vergoed. En natuurlik al wat jy nodig het, is die twee lyne oral geplaas, hulle dont hul eie funksie het. Hierdie filter het wel 'n oprit-up tyd voor die bewegende gemiddelde verteenwoordig dié van die insetsein. As jy nodig het om dit oprit-up tyd omseil, kan jy net inisialiseer MovingAverage om die eerste waarde van newInput in plaas van 0, en hoop dat die eerste newInput isnt 'n uitskieter. (CutoffFrequency / SampleRate) het 'n reeks van tussen 0 en 0,5. DecayFactor is nie 'n waarde tussen 0 en 1, gewoonlik naby aan 1. Enkellopend-presisie dryf is goed genoeg vir die meeste dinge, ek verkies net dubbelspel. As jy nodig het om te hou met heelgetalle, kan jy sit DecayFactor en Amplitude Factor in fraksionele heelgetalle, waarin die teller gestoor as die heelgetal, en die deler is 'n heelgetal krag van 2 (sodat jy kan bietjie-verskuiwing na regs as die deler eerder as om te verdeel in die filter lus). Byvoorbeeld, as DecayFactor 0.99, en jy wil om heelgetalle gebruik, jy kan stel DecayFactor 0.99 65536 64881. En dan wanneer jy vermenigvuldig met DecayFactor in jou filter lus, net skuif die gevolg 16. Vir meer inligting oor hierdie, 'n uitstekende boek dis aanlyn, hoofstuk 19 op rekursiewe filters: www. dspguide / ch19.htm PS Vir die bewegende gemiddelde paradigma, 'n ander benadering tot die opstel van DecayFactor en AmplitudeFactor wat meer relevant is vir jou behoeftes kan wees, kan sê wat jy wil die vorige, sowat 6 items saam gemiddeld, doen dit strategies, youd 6 items en deel te voeg met 6, sodat jy kan die AmplitudeFactor stel om 1/6, en DecayFactor om (1.0 - AmplitudeFactor). antwoord 14 Mei 12 aan 22:55 Almal het deeglik kommentaar op die nut van IIR teen FIR, en op krag-van-twee-afdeling. ID net graag 'n paar implementering besonderhede gee. Die onderstaande werk goed op klein mikrobeheerders met geen FPU. Theres geen vermenigvuldiging, en as jy N hou 'n krag van twee, al die afdeling is enkel-siklus bietjie-verskuiwing. Basiese FIR ring buffer: hou 'n lopende buffer van die laaste N waardes, en 'n lopende som van al die waardes in die buffer. Elke keer as 'n nuwe monster kom in, trek die oudste waarde in die buffer van som, vervang dit met die nuwe monster, voeg die nuwe monster te som, en uitset som / N. Gewysig IIR ring buffer: hou 'n lopende totaal van die laaste N waardes. Elke keer as 'n nuwe monster kom in, som - som / N, voeg in die nuwe monster, en uitset som / N. antwoord 28 Augustus 13 aan 13:45 As I39m jy lees reg, you39re beskrywing van 'n eerste-orde IIR filtreer die waarde you39re trek isn39t die oudste waarde wat uitval, maar is in plaas van die gemiddelde van die vorige waardes. Eerste-orde IIR filters kan beslis nuttig wees, maar I39m nie seker wat jy bedoel wanneer jy suggereer dat die uitset is dieselfde vir alle periodiese seine. Op 'n 10kHz sample rate, voer 'n 100Hz vierkante golf in 'n 20-stadium boks filter sal 'n teken dat eenvormig styg vir 20 monsters oplewer, sit hoog vir 30, daal eenvormig vir 20 monsters, en sit laag vir 30. 'n eerste-orde IIR filter. â € supercat 28 Augustus 13 aan 15:31 sal 'n golf wat skerp begin oplewer stygende en geleidelik afplat naby (maar nie by) die maksimum insette, dan skerp begin val en geleidelik afplat naby (maar nie by) die insette minimum. Baie verskillende gedrag. â € supercat 28 Augustus 13 by 15:32 Een probleem is dat 'n eenvoudige bewegende gemiddelde mag of nie mag nuttig wees. Met 'n IIR filter, kan jy 'n lekker filter met relatief min calcs kry. Die FIR jy beskryf kan net gee jou 'n reghoek in die tyd - 'n sed in freq - en jy can39t die kant lobbe te bestuur. Dit kan die moeite werd om te gooi in 'n paar heelgetal vermeerder sodat dit 'n mooi simmetriese verstelbare FIR as jy kan spaar die klok bosluise wees. uitvoering maak Scott Seidman 29 Augustus 13 by 13:50 ScottSeidman: Nie nodig vir vermeerder as 'n mens het net elke stadium van die FIR óf uitset die gemiddelde van die insette op daardie stadium en sy vorige gestoor waarde, en dan slaan die insette (indien 'n mens die numeriese reeks, kan 'n mens die som eerder as die gemiddelde gebruik). Of that39s beter as 'n boks filter hang af van die aansoek (die stap reaksie van 'n boks filter met 'n totale vertraging van 1ms, byvoorbeeld, sal 'n nare d2 het / dt piek wanneer die insette verander, en weer 1ms later, maar sal moet die minimum moontlike d / dt vir 'n filter met 'n totale 1ms vertraging). â € supercat 29 Augustus 13 aan 15:25 Soos mikeselectricstuff gesê, as jy regtig nodig het om jou geheue behoeftes te verminder, en jy dit nie omgee jou impulsrespons om 'n eksponensiële (in plaas van 'n vierkantige pols), sou ek gaan vir 'n eksponensiële bewegende gemiddelde filter . Ek gebruik dit op groot skaal. Met hierdie tipe filter, hoef jy geen buffer nodig het. Jy hoef nie te N afgelope monsters te stoor. Slegs een. So, kry jou geheue vereistes kap met 'n faktor van N. Ook, moenie jy nodig het 'n afdeling vir daardie. Slegs vermenigvuldiging. As jy toegang tot swaai-punt rekenkundige het, gebruik swaai-punt vermenigvuldiging. Anders, doen heelgetal vermenigvuldiging en skuif na regs. Ons is egter in 2012, en ek sal u aanbeveel om opstellers (en MCUs) wat u toelaat om te werk met swaai-punt getalle gebruik. Behalwe dat meer geheue doeltreffend en vinniger (jy hoef nie te items in enige omsendbrief buffer werk), sou ek sê dit is ook meer natuurlike. omdat 'n eksponensiële impulsrespons wedstryde beter soos die natuur optree, in die meeste gevalle. antwoord 20 April 12 aan 09:59 Een probleem met die IIR filter as byna aangeraak deur Olin en supercat maar blykbaar geïgnoreer deur ander is dat die afronding af stel sommige onakkuraatheid (en potensieel vooroordeel / afkorting). veronderstelling dat N is 'n krag van twee, en net heelgetal rekenkunde gebruik word, die verskuiwing reg nie stelselmatig uit te skakel die LSBs van die nuwe monster. Dit beteken dat hoe lank die reeks ooit kon wees, die gemiddelde sal nooit neem diegene in ag neem. Byvoorbeeld, veronderstel 'n stadig afneem reeks (8,8,8. 8,7,7,7. 7,6,6,) en neem die gemiddelde is inderdaad 8 aan die begin. Die vuis 7 monster sal die gemiddelde bring tot 7, ongeag die filter sterkte. Net vir 'n monster. Dieselfde storie vir 6, ens Nou dink aan die teenoorgestelde. die reeks styg. Die gemiddelde sal bly op 7 ewig, totdat die monster is groot genoeg om dit te verander. Natuurlik, kan jy reg vir die vooroordeel deur die byvoeging van 1 / 2N / 2, maar dit sal nie regtig los die akkuraatheid probleem. In daardie geval die dalende reeks sal vir ewig bly, 8 tot en met die monster is 8-1 / 2 (N / 2). Vir N4 byvoorbeeld 'n monster bo nul sal die gemiddelde onveranderd te hou. Ek glo dat 'n oplossing vir dit sou impliseer 'n akkumulator van die verlore LSBs hou. Maar ek didnt maak dit ver genoeg om kode gereed te hê, en ek is nie seker of dit sal nie skade aan die IIR krag in sommige ander gevalle van 'n reeks (byvoorbeeld of 7,9,7,9 sal gemiddeld tot 8 dan). Olin, jou twee-stadium waterval ook sou 'n verduideliking nodig. Bedoel jy hou twee gemiddelde waardes met die uitslag van die eerste gevoer in die tweede plek in elke iterasie. Wat is die voordeel van hierdie

No comments:

Post a Comment