Sto cercando di calcolare la media mobile di un segnale. Il valore del segnale (una doppia) viene aggiornato in momenti casuali. Sto cercando un modo efficace per calcolare la media ponderata nel tempo su una finestra di tempo, in tempo reale. Ho potuto fare la mia auto, ma è più difficile di quanto pensassi. La maggior parte delle risorse Ive ha trovato su internet sta calcolando la media del segnale periodico in movimento, ma il mio aggiornamenti in tempo casuale. Qualcuno sa buone risorse per che il trucco è la seguente: È possibile ottenere aggiornamenti a volte casuali tramite aggiornamento void (tempo int, float valore). Tuttavia anche è necessario tenere traccia anche quando un aggiornamento cade la finestra di tempo, in modo da impostare un allarme che chiama in fase di N che rimuove il precedente aggiornamento venga mai preso in considerazione di nuovo nel calcolo. Se questo accade in tempo reale è possibile richiedere il sistema operativo per effettuare una chiamata a un dropoffoldestupdate metodo void (tempo int) per essere chiamato al momento N Se si tratta di una simulazione, non è possibile ottenere aiuto da parte del sistema operativo ed è necessario farlo manualmente. In una simulazione che chiamereste metodi con il tempo fornito come argomento (che non correlano con il tempo reale). Tuttavia, un'ipotesi ragionevole è che le chiamate sono garantiti per essere tale che gli argomenti tempo sono in aumento. In questo caso è necessario mantenere un elenco ordinato dei valori di tempo di allarme, e per ogni aggiornamento e leggere chiamate di verificare se l'argomento di tempo è maggiore del capo della lista degli allarmi. Anche se è più grande si fa l'elaborazione relative allarme (drop off l'aggiornamento più antica), togliere la testa e controllare di nuovo fino a quando tutti gli allarmi prima del tempo dato vengono elaborati. Poi fare la chiamata di aggiornamento. Ho finora assunto è ovvio quello che si potrebbe fare per il calcolo effettivo, ma mi dilungherò per ogni evenienza. Suppongo di avere un metodo float leggere (tempo int) che consente di leggere i valori. L'obiettivo è quello di rendere questa chiamata il più efficiente possibile. Quindi non si calcola la media mobile ogni volta che il metodo di lettura viene chiamato. Invece si Precompute il valore dell'ultimo aggiornamento o l'ultimo allarme, e ottimizzare il valore di un paio di operazioni in virgola mobile per tenere conto del passaggio del tempo dall'ultimo aggiornamento. (I. E. Un numero costante di operazioni eccetto forse l'elaborazione di un elenco di allarmi accatastati). Speriamo che questo sia chiaro - questo dovrebbe essere abbastanza semplice algoritmo e abbastanza efficiente. Un'ulteriore ottimizzazione. uno dei problemi rimanenti è se un gran numero di aggiornamenti avviene entro la finestra di tempo, allora vi è un tempo per la quale non sono né legge né aggiornamenti e quindi di lettura o aggiornamento arriva. In questo caso, l'algoritmo precedente sarà inefficiente nel incrementalmente aggiornando il valore per ciascuno degli aggiornamenti che è cadere. Questo non è necessario perché ci interessa solo l'ultimo aggiornamento al di là della finestra di tempo, quindi se c'è un modo per eliminare in modo efficiente via tutti gli aggiornamenti più anziani, sarebbe utile. Per fare questo, siamo in grado di modificare l'algoritmo per fare una ricerca binaria di aggiornamenti per trovare l'ultimo aggiornamento prima che la finestra di tempo. Se ci sono relativamente pochi gli aggiornamenti che deve essere lasciato cadere, allora si può incrementale aggiornare il valore per ogni caduto aggiornamento. Ma se ci sono molti aggiornamenti che devono essere lasciato cadere, allora si può ricalcolare il valore da zero dopo aver lasciato fuori i vecchi aggiornamenti. Appendice sul incrementale Computation: Ho dovrebbe chiarire cosa intendo per il calcolo incrementale sopra nella frase modificare questo valore da un paio di operazioni in virgola mobile per tenere conto del passaggio del tempo dall'ultimo aggiornamento. Iniziale di calcolo non incrementale: poi iterare su relevantupdates in ordine crescente di tempo: media mobile (somma lastUpdate timesincelastupdate) windowlength. Ora, se esattamente un aggiornamento cade dalla finestra, ma non nuovi aggiornamenti arrivano, regolare sum come: (notare che è priorupdate che ha modificato la sua data e ora di inizio della ultima finestra di iniziare). E se esattamente un aggiornamento entra dalla finestra, ma non nuovi aggiornamenti cadere, regolare somma come: Come dovrebbe essere evidente, si tratta di uno schizzo, ma si spera che mostra come è possibile mantenere la media in modo che sia (1) O al update su base ammortizzato. Ma nota ulteriore ottimizzazione nel paragrafo precedente. Si noti inoltre problemi di stabilità alluso in una risposta più vecchio, il che significa che gli errori di virgola mobile possono accumularsi su un gran numero di tali operazioni elementari tale che vi è una divergenza dal risultato della piena calcolo, che è significativo per l'applicazione. Se un approssimazione è OK e c'è un tempo minimo tra i campioni, si potrebbe provare super-campione. Avere una matrice che rappresenta intervalli di tempo equidistanti che sono più corti rispetto al minimo, e in ogni periodo di tempo l'ultimo negozio di esempio che è stato ricevuto. Più breve è l'intervallo, più il media sarà al vero valore. Il periodo dovrebbe essere non superiore alla metà del minimo o c'è la possibilità di perdere un campione. risposto 15 dicembre 11 alle 18:12 risposto 15 dicembre 11 alle 22:38 Grazie per la risposta. Un miglioramento che sarebbe necessaria per quotcachequot effettivamente il valore della media totale quindi abbiamo don39t ciclo tutto il tempo. Inoltre, può essere un piccolo punto, ma non sarebbe più efficace utilizzare un deque o un elenco per memorizzare il valore, dal momento che si assume che l'aggiornamento arriverà nel giusto ordine. Inserimento sarebbe più veloce nella mappa. ndash Arthur 16 dicembre 11 alle 8:55 Sì, si può memorizzare nella cache il valore della somma. Sottrarre i valori dei campioni che cancellare, aggiungere i valori dei campioni si inserisce. Inoltre, sì, un dequeltpairltSample, Dategtgt potrebbe essere più efficiente. Ho scelto mappa per migliorare la leggibilità e la facilità di invocare mappa :: limite superiore. Come sempre, scrivere codice corretto, poi il profilo e misurare le variazioni incrementali. ndash Rob 16 dicembre 11 alle 15:00 Nota: A quanto pare questo non è il modo per avvicinarsi a questo. Lasciando qui per riferimento su ciò che è sbagliato in questo approccio. Controllare i commenti. AGGIORNATO - sulla base di Olis commento. Non sono sicuro circa l'instabilità che sta parlando però. Utilizza una mappa ordinata di tempi di arrivo rispetto ai valori. All'arrivo di un valore di aggiungere l'orario di arrivo alla mappa ordinata insieme al suo valore e aggiornare la media mobile. Avvertimento Questa è pseudo-codice: Ci. Non pienamente concretizzati, ma si ottiene l'idea. Le cose da notare. Come ho detto sopra è pseudo codice. Youll bisogno di scegliere una mappa adeguata. Dont rimuovere le coppie come eseguire iterazioni come si invalidare l'iteratore e dovrà ricominciare da capo. Vedere Olis commento qui sotto anche. risposto 15 dicembre 11 alle 12:22 Questo lavoro doesn39t: si doesn39t prendere in considerazione quale parte della finestra di lunghezza esiste ogni valore per. Inoltre, questo approccio di aggiunta e sottraendo è stabile solo per i tipi interi, non galleggianti. ndash Oliver Charlesworth 15 dicembre 11 a 00:29 OliCharlesworth - scusate ho perso alcuni punti chiave nella descrizione (doppio e ponderata nel tempo). Vi aggiornerò. Grazie. ndash Dennis 15 dic 11 in 12:33 Il tempo di ponderazione è ancora un altro problema. Ma non that39s cosa I39m parlando. Mi riferivo al fatto che quando un nuovo valore entra per la prima volta la finestra, il suo contributo alla media è minima. Il suo contributo continua ad aumentare finché un nuovo valore entra. ndash Oliver Charlesworth 15 dicembre 11 alle 12: 35I che questo è realizzabile con boost secondo: Ma mi piacerebbe davvero evitare l'uso di spinta. Googled e non trovato alcun esempio adatto o leggibili. Fondamentalmente voglio monitorare la media mobile di un flusso continuo di un flusso di numeri in virgola che utilizzano le più recenti 1000 numeri come un campione di dati galleggiante. Qual è il modo più semplice per raggiungere questo obiettivo ho sperimentato con l'utilizzo di un array circolare, media mobile esponenziale e una più semplice media mobile e ha scoperto che i risultati dalla matrice circolare adatta alle mie esigenze. chiesto 12 giugno 12 a 4:38 Se le vostre esigenze sono semplici, si potrebbe anche provare a utilizzare una media mobile esponenziale. In parole povere, si effettua una variabile di accumulatori, e come il codice sia in ogni campione, il codice aggiorna l'accumulatore con il nuovo valore. Si sceglie un alpha costante che è compreso tra 0 e 1, e calcolare questo: Hai solo bisogno di trovare un valore di alfa in cui l'effetto di un determinato campione dura solo per circa 1000 campioni. Hmm, Im non realmente sicuro che questo è adatto per voi, ora che Ive ha messo qui. Il problema è che 1000 è un piuttosto lunga finestra per una media mobile esponenziale Im non sicuro che ci sia un alfa che diffondere la media degli ultimi 1000 numeri, senza underflow nel calcolo in virgola mobile. Ma se si voleva una media più piccolo, come 30 numeri o giù di lì, questo è un modo molto semplice e veloce per farlo. rispose Jun 12 12 alle 4:44 1 sul tuo post. La media mobile esponenziale può permettere l'alfa di essere variabile. Quindi, questo permette di essere utilizzato per calcolare le medie base dei tempi (ad esempio byte al secondo). Se il tempo dall'ultimo aggiornamento accumulatore è più di 1 secondo, si lascia alfa essere 1.0. In caso contrario, si può lasciare alfa essere (usecs dall'ultima update1000000). ndash JXH 12 giugno 12 alle 06:21 Fondamentalmente voglio monitorare la media mobile di un flusso continuo di un flusso di numeri in virgola che utilizzano le più recenti 1000 numeri come un campione di dati galleggiante. Si noti che il sotto aggiorna totale come elementi come addedreplaced, evitando i costi di O (N) attraversamento per calcolare la somma - necessario per la media - su richiesta. Total è fatto un parametro diverso da T a sostenere ad esempio con un lungo lungo quando per un totale di 1000 s lunga, un int per char s, o un doppio al totale galleggiante s. Questo è un po 'viziata in quel numsamples potrebbe andare oltre INTMAX - se vi interessa si potrebbe usare un unsigned long long. o utilizzare un membro di dati in più bool a registrare quando il contenitore viene prima riempita mentre numsamples ciclabili intorno l'array (migliore poi rinominato qualcosa di innocuo come pos). risposto 12 giugno 12 a 5:19 si parte dal presupposto che l'operatore quotvoid (campione T) quot è in realtà operatorltlt quotvoid (campione T) quot. ndash oPless 8 Giugno 14 a 11:52 oPless ahhh. ben individuato. in realtà volevo dire per essere operatore void) (campione T) (ma naturalmente si potrebbe usare qualsiasi notazione ti è piaciuto. Sarà risolvere, grazie. ndash Tony D 8 giugno 14 a 14: 27As altri hanno detto, si dovrebbe considerare un IIR (risposta all'impulso infinita) filtro piuttosto che la FIR (risposta all'impulso finita) filtro che si sta utilizzando ora. C'è di più ad esso, ma a prima vista filtri FIR sono implementate come circonvoluzioni espliciti e IIR filtri con le equazioni. La particolare filtro IIR io uso molto in microcontrollori è un filtro passa basso unipolare. Questo è l'equivalente digitale di un semplice filtro analogico R-C. Per la maggior parte delle applicazioni, questi avranno caratteristiche migliori rispetto al filtro di dialogo che si sta utilizzando. La maggior parte usi di un filtro scatola che ho incontrato sono il risultato di qualcuno non prestare attenzione in classe elaborazione del segnale digitale, non come risultato di dover loro caratteristiche particolari. Se si desidera solo per attenuare le alte frequenze che si sa essere il rumore, un filtro passa basso unipolare è meglio. Il modo migliore per attuare una digitalmente in un microcontrollore è di solito: FILT lt-- FILT FF (NUOVO - FILT) FILT è un pezzo di stato persistente. Questa è l'unica variabile persistente è necessario calcolare questo filtro. NEW è il nuovo valore che il filtro viene aggiornato con questa iterazione. FF è la frazione filtro. che regola la pesantezza del filtro. Guardate questo algoritmo e vedere che per FF 0 il filtro è infinitamente pesante dal momento che l'uscita non cambia mai. Per 1 FF, la sua realtà nessun filtro del tutto poiché l'uscita segue solo l'ingresso. I valori utili sono in mezzo. Su piccoli sistemi si sceglie FF per essere 12 N in modo che il moltiplicare per FF può essere realizzato come uno spostamento a destra di n bit. Ad esempio, potrebbe essere FF 116 e moltiplicare per FF pertanto uno shift verso destra di 4 bit. In caso contrario, questo filtro necessita di un solo sottrarre e uno aggiuntivo, anche se i numeri di solito bisogno di essere più ampio rispetto al valore di ingresso (più precisione numerica in una sezione separata di seguito). Di solito prendo letture AD significativamente più veloce di quanto non sono necessari e applicare due di questi filtri in cascata. Questo è l'equivalente digitale di due filtri R-C in serie, e attenua del 12 dBoctave sopra la frequenza rolloff. Tuttavia, per AD letture elencate relativo solitamente più pertinenti a guardare il filtro nel dominio del tempo, considerando la sua risposta al gradino. Questo ti dice quanto velocemente il sistema vedrà un cambiamento quando la cosa si sta misurando i cambiamenti. Per facilitare la progettazione di questi filtri (il che significa che solo la raccolta di FF e decidere come molti di loro a cascata), io uso il mio FILTBITS programma. Si specifica il numero di bit per ogni turno FF nella serie cascata di filtri, e si calcola la risposta al gradino e altri valori. A dire il vero io di solito eseguire questo tramite il mio script wrapper PLOTFILT. Questo viene eseguito FILTBITS, il che rende un file CSV, quindi traccia il file CSV. Ad esempio, qui è il risultato di PLOTFILT 4 4: I due parametri PLOTFILT significa che ci saranno due filtri in cascata del tipo sopra descritto. I valori di 4 indicano il numero di bit di spostamento per realizzare il moltiplicare per FF. I due valori FF sono quindi 116 in questo caso. La traccia rossa è la risposta al gradino unità, ed è la cosa più importante da guardare. Ad esempio, questo indica che se l'ingresso cambia istantaneamente, l'uscita del filtro combinato si depositerà a 90 del nuovo valore in 60 iterazioni. Se avete a cuore il 95 tempo di assestamento, allora si deve attendere circa 73 iterazioni, e per il 50 tempo di assestamento solo 26 iterazioni. La traccia verde mostra l'output da un unico picco di massima ampiezza. Questo vi dà un'idea della soppressione del rumore casuale. Sembra che nessun singolo campione causerà più di un cambiamento di 2,5 in uscita. La traccia blu è quello di dare una sensazione soggettiva di ciò che questo filtro fa con rumore bianco. Questo non è un test severo, in quanto non vi è alcuna garanzia che cosa esattamente il contenuto era dei numeri casuali raccolti come ingresso rumore bianco per questa esecuzione di PLOTFILT. Il suo solo per dare una sensazione di massima di quanto verrà schiacciata e come liscia che è. PLOTFILT, forse FILTBITS, e un sacco di altra roba utile, in particolare per lo sviluppo del firmware PIC è disponibile nella versione software Strumenti di sviluppo PIC alla mia pagina di download del software. Aggiunta di informazioni di precisione numerica Vedo dai commenti e ora una nuova risposta che non vi è interesse a discutere il numero di bit necessari per implementare questo filtro. Si noti che il moltiplicare per FF creerà Log 2 (FF) nuovi bit al di sotto del punto di binario. Su piccoli sistemi, FF è generalmente scelto per essere 12 N in modo che questo si moltiplicano sia effettivamente realizzato da uno shift verso destra di N bits. FILT è quindi di solito un intero punto fisso. Si noti che questo doesnt cambia i matematica dal punto di vista processori. Ad esempio, se si sta filtrando 10 letture AD bit e N 4 (116 FF), allora avete bisogno di 4 bit di frazione sotto le letture intero AD 10 bit. Un maggior parte dei processori, youd essere facendo 16 operazioni po interi a causa delle letture AD 10 bit. In questo caso, si può ancora fare esattamente le stesse 16 opertions bit integer, ma iniziare con le letture AD sinistra spostato da 4 bit. Il processore non sa la differenza e non ha bisogno di. Facendo due conti su interi numeri interi a 16 bit funziona se si considera che siano 12,4 punto fisso o veri e propri 16 numeri interi bit (16.0 punto fisso). In generale, è necessario aggiungere N bit ciascuno dei poli filtro se non volete aggiungere rumore dovuto alla rappresentazione numerica. Nell'esempio precedente, il secondo filtro di due dovrebbe avere 1044 18 bit per non perdere informazioni. In pratica su un computer a 8 bit che significa valori bit uso 24 youd. Tecnicamente solo il secondo polo di due avrebbe bisogno il valore più ampio, ma per semplicità firmware solito utilizzare la stessa rappresentazione, e quindi lo stesso codice, per tutti i poli di un filtro. Di solito scrivo una subroutine o una macro per eseguire una sola operazione pole filtro, quindi applicare che per ogni polo. Se una subroutine o una macro dipende dal fatto che i cicli o memoria di programma sono più importanti in quel particolare progetto. Ad ogni modo, io uso uno stato zero per passare di nuovo nel subroutinemacro, che aggiorna FILT, ma anche carica che nello stesso stato zero NUOVO era in. Ciò lo rende facile da applicare poli multipli in quanto la FILT aggiornata di un polo è il nuovo di quello successivo. Quando una subroutine, il suo utile avere un punto puntatore FILT sul modo in, che viene aggiornato solo dopo FILT sull'uscita. In questo modo la subroutine funziona automaticamente su filtri consecutivi in memoria se chiamato più volte. Con una macro non avete bisogno di un puntatore da quando si passa l'indirizzo di operare su ogni iterazione. Esempi di codice Ecco un esempio di una macro come descritto sopra per un PIC 18: E qui è una macro simile per un PIC 24 o dsPIC 30 o 33: Entrambi questi esempi sono implementate come macro utilizzando il mio PIC assemblatore preprocessore. che è più capace di una delle strutture macro incorporati. clabacchio: Un altro problema Avrei detto è l'attuazione del firmware. È possibile scrivere un unico polo passa-basso filtro subroutine una volta, poi applicarlo più volte. Infatti solito scrivere un tale subroutine per prendere un puntatore nella memoria allo stato del filtro, quindi l'ho avanzare il puntatore in modo che possa essere chiamato in successione facilmente realizzare filtri multipolari. ndash Olin Lathrop 20 aprile 12 al 15:03 1. Grazie mille per le vostre risposte - tutti loro. Ho deciso di usare questo filtro IIR, ma questo filtro non viene utilizzato come un filtro standard LowPass, dal momento che ho bisogno di valori medi del contatore e confrontarli per rilevare i cambiamenti in un certo intervallo. Poiché questi valori van essere di dimensioni molto diverse a seconda dell'hardware ho voluto prendere una media in modo da essere in grado di reagire a questi cambiamenti specifici hardware automaticamente. ndash sensslen 21 12 maggio alle 12:06 Se si può vivere con la restrizione di una potenza di due serie di elementi di media (cioè 2,4,8,16,32, ecc), allora il divario può facilmente ed efficacemente essere fatto su una bassa micro prestazioni senza divide dedicato perché può essere fatto come un bit di scorrimento. Ogni spostamento è giusta potenza di due ad esempio: Il PO pensava di avere due problemi, che divide in un PIC16 e memoria per il suo buffer circolare. Questa risposta dimostra che la divisione non è difficile. Bisogna ammettere che non affronta il problema di memoria, ma il sistema SE permette risposte parziali, e gli utenti possono prendere qualcosa da ogni risposta per se stessi, o anche modificare e combinare le risposte other39s. Poiché alcune delle altre risposte richiedono un'operazione di divisione, sono analogamente incomplete poiché non mostrano come ottenere in modo efficiente questo su un PIC16. ndash Martin Apr 20 12 alle 13:01 C'è una risposta per un vero e proprio filtro a media mobile (aka filtro Boxcar) con requisiti di memoria meno, se non vi dispiace downsampling. La sua chiamata un filtro in cascata integratore-pettine (CIC). L'idea è che si dispone di un integratore che si prende le differenze di un periodo di tempo, e il dispositivo di memoria di risparmio chiave è che da downsampling, non dovete memorizzare ogni valore dell'integratore. Può essere implementato utilizzando il seguente pseudocodice: La lunghezza effettiva media mobile è decimationFactorstatesize ma avete solo bisogno di mantenere intorno campioni statesize. Ovviamente è possibile ottenere prestazioni migliori se il statesize e decimationFactor sono potenze di 2, in modo che gli operatori di divisione e resto vengono sostituiti da spostamenti e la maschera-ands. Poscritto: Sono d'accordo con Olin che si dovrebbe sempre prendere in considerazione semplici filtri IIR prima di un filtro a media mobile. Se non avete bisogno le frequenze-null di un filtro vagone, un 1-palo o filtro passa-basso a 2 poli probabilmente funzionerà bene. D'altra parte, se si sta filtrando ai fini della decimazione (prendendo un ingresso ad alta frequenza di campionamento e una media per l'utilizzo da parte di un processo a bassa frequenza), poi un filtro CIC può essere solo quello che stai cercando. (Soprattutto se è possibile utilizzare statesize1 ed evitare il ringbuffer tutto con un singolo valore integratore precedente) Theres alcune analisi approfondita della matematica dietro utilizzando il filtro IIR del primo ordine che Olin Lathrop ha già descritto sopra sullo scambio pila Digital Signal Processing (comprende un sacco di belle immagini.) l'equazione per questo filtro IIR è: Ciò può essere implementato usando solo numeri interi e nessuna divisione utilizzando il seguente codice (potrebbe essere necessario un po 'di debugging come stavo scrivendo a memoria.) questo filtro si avvicina una media mobile di gli ultimi campioni K impostando il valore di alfa a 1K. Fate questo in codice precedente da definire BITS ing a LOG2 (K), vale a dire per K 16 bit impostati a 4, per K 4 bit impostati a 2, etc. (Ill verificare il codice elencato qui, non appena ho un cambiamento e modificare questa risposta, se necessario.) ha risposto 23 giugno 12 a 4:04 Heres un filtro passa-basso unipolare (media mobile, con cutoff CutoffFrequency frequenza). Molto semplice, molto veloce, grandi opere, e quasi nessun overhead di memoria. Nota: Tutte le variabili hanno portata al di là della funzione di filtro, ad eccezione del passato in newInput Nota: Si tratta di un unico filtro palco. stadi multipli possono essere collegati in cascata insieme per aumentare la nitidezza del filtro. Se si utilizza più di una fase, youll hanno per regolare DecayFactor (come si riferisce al taglio-Frequency) per compensare. E, ovviamente, tutto ciò che serve è quelle due righe posizionati ovunque, Non hanno bisogno la propria funzione. Questo filtro ha un tempo di accelerazione prima della media mobile rappresenta quella del segnale di ingresso. Se avete bisogno di ignorare che il tempo di ramp-up, si può solo inizializzare media mobile per il primo valore di newInput invece di 0, e la speranza il primo newInput è neanche un outlier. (CutoffFrequencySampleRate) ha una gamma compresa tra 0 e 0,5. DecayFactor è un valore compreso tra 0 e 1, di solito vicino a 1. carri singola precisione sono abbastanza buono per la maggior parte delle cose, ho appena preferisco doppie. Se avete bisogno di attaccare con numeri interi, è possibile convertire DecayFactor e ampiezza Factor in numeri interi frazionari, in cui il numeratore viene memorizzato come il numero intero, e il denominatore è una potenza intera di 2 (in modo da poter bit-shift a destra come la denominatore piuttosto che dover dividere durante il loop filtro). Per esempio, se DecayFactor 0.99, e si desidera utilizzare gli interi, è possibile impostare DecayFactor 0,99 65536 64881. E poi ogni volta che si moltiplica per DecayFactor nel loop filtro, semplicemente spostare il risultato 16. Per ulteriori informazioni su questo, questo è un ottimo libro on-line, il capitolo 19 sui filtri ricorsivi: dspguidech19.htm PS Per la movimentazione di paradigma media, un approccio diverso per impostazione DecayFactor e AmplitudeFactor che può essere più rilevante per le vostre esigenze, permette di dire si desidera che i precedenti, circa 6 articoli in media insieme, facendo in modo discreto, youd aggiungere 6 articoli e dividere per 6, in modo da è possibile impostare il AmplitudeFactor a 16, e DecayFactor di (1,0 - AmplitudeFactor). risposto 14 maggio 12 in 22:55 tutti gli altri hanno commentato a fondo l'utilità di IIR contro FIR, e sulla divisione di potere-di-due. Id proprio come a dare alcuni dettagli di implementazione. Il sotto funziona bene su piccoli microcontrollori senza FPU. Theres nessuna moltiplicazione, e se si mantiene N una potenza di due, tutta la divisione è a ciclo unico bit-shifting. tampone base anello FIR: tenere un tampone di corsa degli ultimi valori di N, e una somma parziale di tutti i valori nel buffer. Ogni volta che un nuovo campione entra, sottrarre il valore più vecchio nel buffer da SUM, sostituirlo con il nuovo campione, aggiungere il nuovo campione di SUM, e SUMN uscita. Modificato buffer circolare IIR: mantenere una somma parziale degli ultimi N valori. Ogni volta che un nuovo campione entra, SUM - SUMN, aggiungere il nuovo campione, e SUMN uscita. risposto 28 ago 13 ad 13:45 Se I39m voi leggendo a destra, you39re descrivendo un primo ordine IIR filtro del valore you39re sottraendo isn39t il valore più vecchio che sta cadendo fuori, ma è invece la media dei valori precedenti. Primo ordine filtri IIR può certamente essere utile, ma non è sicuro I39m cosa si intende quando si suggerisce che l'uscita è la stessa per tutti i segnali periodici. Ad una frequenza di campionamento 10KHz, alimentando un'onda quadra a 100Hz in una scatola filtro 20 stadi produrrà un segnale che aumenta uniformemente per 20 campioni, si trova in alto per 30 gocce uniformemente per 20 campioni, e si siede basso per 30. Un primo ordine filtro IIR. ndash Supercat 28 ago 13 ad 15:31 produrrà un'onda che inizia forte aumento e gradualmente i livelli in prossimità di (ma non a) la massima di ingresso, poi inizia a cadere bruscamente e gradualmente i livelli in prossimità di (ma non a) il minimo di ingresso. comportamento molto diverso. ndash Supercat 28 13 agosto a 15:32 Un problema è che una media mobile semplice può o non può essere utile. Con un filtro IIR, è possibile ottenere un bel filtro con relativamente pochi calcs. La FIR si descrive può solo dare un rettangolo nel tempo - un sinc in freq - e si can39t gestire i lobi laterali. Essa può essere valsa la pena di gettare in un paio di moltiplica interi per rendere un bel FIR sintonizzabile simmetrica se si può risparmiare l'orologio zecche. ndash Scott Seidman 29 agosto 13 alle 13:50 ScottSeidman: Non c'è bisogno di moltiplica se uno ha semplicemente ogni fase della FIR sia uscita la media dell'ingresso a quella fase e il suo valore memorizzato precedente, e quindi memorizzare l'ingresso (se uno ha l'intervallo numerico, si potrebbe utilizzare la somma invece di media). Sia that39s meglio di un filtro box dipende dalla applicazione (la risposta di un filtro scatola con un ritardo totale di 1 ms, per esempio, avrà un picco d2dt entrata quando il cambiamento di ingresso, e di nuovo 1ms tardi, ma avrà la minima possibile ddt per un filtro con un totale di ritardo 1 ms). ndash Supercat 29 ago 13 ad 15:25 Come ha detto mikeselectricstuff, se si ha realmente bisogno di ridurre le esigenze di memoria, e non vi dispiace la vostra risposta all'impulso essere un esponenziale (invece di un impulso rettangolare), vorrei andare per un filtro di media mobile esponenziale . Li uso estensivo. Con questo tipo di filtro, non avete bisogno di alcun tampone. Non dovete memorizzare i campioni N passato. Solo uno. Quindi, i tuoi requisiti di memoria vengono abbattuti di un fattore di N. Inoltre, non avete bisogno di alcuna divisione per questo. Solo moltiplicazioni. Se si ha accesso a virgola mobile, utilizzare moltiplicazioni in virgola mobile. In caso contrario, fare moltiplicazioni interi e turni a destra. Tuttavia, siamo nel 2012, e vi consigliamo di usare compilatori (e MCU) che permettono di lavorare con numeri in virgola mobile. Oltre ad essere più efficiente della memoria e più veloce (non dovete aggiornare gli elementi in ogni buffer circolare), direi che è anche più naturale. perché una risposta impulsiva esponenziale corrisponde meglio come natura comporta, nella maggior parte dei casi. risposto 20 Apr 12 in 09:59 Un problema con il filtro IIR come quasi toccato da Olin e Supercat ma apparentemente ignorato da altri è che l'arrotondamento per difetto presenta alcune imprecisioni (e potenzialmente biastruncation). supponendo che N è una potenza di due, e solo l'aritmetica intera è utilizzata, il passaggio diritto non elimina sistematicamente i bit LSB del nuovo campione. Ciò significa che per quanto tempo la serie potrebbe mai essere, la media non potrà mai prendere quelli in considerazione. Ad esempio, supponiamo che una serie lentamente diminuendo (8,8,8. 8,7,7,7. 7,6,6,) e assumere la media è infatti 8 all'inizio. Il campione pugno 7 porterà la media di 7, qualunque sia la forza del filtro. Solo per un campione. Stessa storia per 6, ecc Ora pensare il contrario. la serie va in su. La media rimarrà il 7 per sempre, fino a quando il campione è abbastanza grande per farlo cambiare. Naturalmente, è possibile correggere la distorsione con l'aggiunta di 12N2, ma che in realtà abituato a risolvere il problema di precisione. in tal caso la serie decrescente rimarrà sempre a 8 finché il campione è 8-12 (N2). Per N4 per esempio, qualsiasi campione sopra lo zero manterrà il invariata media. Credo che una soluzione per questo implicherebbe tenere un accumulatore di LSB persi. Ma non ho rendere quanto basta per avere il codice pronto, e io non sono sicuro che non sarebbe danneggiare la potenza IIR in alcuni altri casi di serie (ad esempio se 7,9,7,9 sarebbe in media di 8 poi). Olin, il vostro cascata a due stadi anche avrebbe bisogno di qualche spiegazione. Vuoi dire che regge due valori medi con il risultato del primo alimentato nella seconda in ogni iterazione. Che cosa è il vantaggio di questo
No comments:
Post a Comment