Sommario:

Media corrente per i tuoi progetti di microcontrollori: 6 passaggi
Media corrente per i tuoi progetti di microcontrollori: 6 passaggi

Video: Media corrente per i tuoi progetti di microcontrollori: 6 passaggi

Video: Media corrente per i tuoi progetti di microcontrollori: 6 passaggi
Video: Come progettare un circuito - EasyEDA tutorial 2024, Dicembre
Anonim
Media corrente per i tuoi progetti di microcontrollori
Media corrente per i tuoi progetti di microcontrollori

In questo tutorial spiegherò cos'è una media mobile e perché dovresti preoccupartene, oltre a mostrarti come dovrebbe essere implementata per la massima efficienza computazionale (non preoccuparti della complessità, è molto semplice da capire e lo farò fornire una libreria facile da usare anche per i tuoi progetti arduino:)

La media mobile, comunemente indicata anche come media mobile, media mobile o media mobile, è un termine utilizzato per descrivere il valore medio degli ultimi N valori nelle serie di dati. Può essere calcolato come una media normale oppure puoi usare un trucco per avere un impatto minimo sulle prestazioni del tuo codice.

Passaggio 1: caso d'uso: livellamento delle misurazioni ADC

Caso d'uso: livellamento delle misurazioni ADC
Caso d'uso: livellamento delle misurazioni ADC

Arduino ha un ADC a 10 bit decente con pochissimo rumore. Quando si misura il valore su un sensore come potenziometro, fotoresistenza o altri componenti ad alto rumore, è difficile fidarsi che la misurazione sia corretta.

Una soluzione consiste nell'eseguire più misurazioni ogni volta che si desidera leggere il sensore e calcolarne la media. In alcuni casi questa è una soluzione praticabile ma non sempre. Se volessi leggere l'ADC 1000 volte al secondo, dovresti farlo 10.000 se esegui una media di 10 misurazioni. Un enorme spreco di tempo di calcolo.

La mia soluzione proposta è di eseguire misurazioni 1000 volte al secondo, aggiornare ogni volta la media corrente e utilizzarla come valore corrente. Questo metodo introduce una certa latenza ma riduce la complessità computazionale della tua applicazione, offrendoti molto più tempo per l'elaborazione aggiuntiva.

Nella foto sopra ho usato la media corrente delle ultime 32 misurazioni. Vedrai che questo metodo non è a prova di errore al 100%, ma migliora significativamente la precisione (non è peggio della media di 32 campioni ogni volta). Se volessi calcolare una media di 32 misurazioni ogni volta, ci vorranno più di 0,25 ms su Arduino UNO solo per le misurazioni!

Passaggio 2: caso d'uso: misurazione del componente CC del segnale del microfono

Caso d'uso: misurazione della componente CC del segnale del microfono
Caso d'uso: misurazione della componente CC del segnale del microfono
Caso d'uso: misurazione della componente CC del segnale del microfono
Caso d'uso: misurazione della componente CC del segnale del microfono
Caso d'uso: misurazione della componente CC del segnale del microfono
Caso d'uso: misurazione della componente CC del segnale del microfono

Arduino può misurare tensioni tra 0 e Vcc (normalmente 5 V). Il segnale audio è completamente AC e se vuoi misurarlo su un microcontrollore, devi polarizzarlo di circa 1/2 Vcc. In un progetto Arduino UNO ciò significherebbe circa 2,5 V (DC) + segnale audio (AC). Quando si utilizza l'ADC a 10 bit e l'alimentazione a 5 V, la polarizzazione di 2,5 V dovrebbe essere uguale alla misurazione di 512. Quindi, per ottenere un valore CA del segnale, 512 dovrebbe essere sottratto dalla misurazione ADC e basta, giusto?

In un mondo ideale, sarebbe vero. Sfortunatamente la vita reale è più complicata e la nostra polarizzazione del segnale tende ad andare alla deriva. Molto comune è il rumore a 50 Hz (60 Hz se vivi negli Stati Uniti) dalla rete elettrica. Di solito non è troppo problematico ma è bene sapere che esiste. Più problematico è lo spostamento lineare dovuto al riscaldamento dei componenti. Si imposta con attenzione la correzione dell'offset CC all'inizio e si allontana lentamente mentre l'applicazione è in esecuzione.

Illustrerò questo problema con un rilevatore di battito (musicale). Hai impostato la rimozione del bias e i battiti sono chiari (immagine 2). Dopo un po' di tempo, i movimenti e i battiti del bias DC sono appena percettibili per il microcontrollore (immagine 3). L'algoritmo di rilevamento del battito sarà esplorato in profondità in un futuro istruibile in quanto supera lo scopo di questo articolo.

Fortunatamente c'è un modo per continuare a calcolare costantemente l'offset DC dell'audio. Non sorprenderà che la media di corsa, argomento di questo istruibile, fornisca una soluzione.

Sappiamo che il valore medio di qualsiasi segnale AC è 0. Usando questa conoscenza possiamo dedurre che il valore medio del segnale AC+DC è la sua polarizzazione DC. Per rimuoverlo, possiamo prendere una media corrente degli ultimi valori e sottrarla dalla lettura ADC corrente. Si noti che è necessario utilizzare una media mobile sufficientemente lunga. Per l'audio, dovrebbe essere sufficiente un decimo di secondo (il numero di campioni dipende dalla frequenza di campionamento), ma sappi che le medie più lunghe funzionano meglio. Nella prima immagine puoi vedere un esempio di calcolo del bias DC reale con media corrente con 64 elementi a una frequenza di campionamento di 1 kHz (meno di quanto consigliato ma funziona ancora).

Passaggio 3: calcolo

Calcolo
Calcolo

Puoi immaginare la media di corsa come il peso medio delle persone nella sala d'attesa del medico. Il dottore finisce di esaminare un paziente e contemporaneamente uno nuovo entra nella sala d'attesa.

Per scoprire il peso medio di tutti i pazienti in attesa nella sala d'attesa, l'infermiera potrebbe quindi chiedere a ciascun paziente il loro peso, sommare quei numeri e dividere per il numero di pazienti. Ogni volta che il medico accetta un nuovo paziente, l'infermiera ripete l'intero processo.

Potresti pensare: "Non sembra molto efficiente… Deve esserci un modo migliore per farlo". E avresti ragione.

Per ottimizzare questo processo, l'infermiere potrebbe tenere un registro del peso totale dell'attuale gruppo di pazienti. Una volta che il medico chiama il nuovo paziente, l'infermiera gli chiede del suo peso e lo sottrae dal totale del gruppo e lo lascia andare. L'infermiera chiedeva quindi al paziente che era appena entrato nella sala d'attesa il suo peso e lo aggiungeva al totale. Il peso medio dei pazienti dopo ogni turno sarebbe la somma dei pesi divisa per il numero di pazienti (sì, come prima ma ora l'infermiera ha chiesto solo a due persone il loro peso invece di tutti loro). Mi rendo conto che questo paragrafo potrebbe essere stato un po' confuso, quindi per favore guarda l'illustrazione sopra per maggiore chiarezza (o fai domande nei commenti).

Ma anche se non hai trovato l'ultimo paragrafo confuso potresti avere domande come cosa dovrebbe essere nell'accumulatore all'inizio, come faccio a mettere quello che ho appena letto in un vero codice C? Questo verrà affrontato nel passaggio successivo, dove riceverai anche il mio codice sorgente.

Passaggio 4: il codice

Il codice
Il codice

Per calcolare la media corrente, è prima necessario un modo per memorizzare gli ultimi N valori. potresti avere un array con N elementi e spostare l'intero contenuto di una posizione ogni volta che aggiungi un elemento (per favore non farlo), oppure potresti sovrascrivere un vecchio elemento e regolare il puntatore all'elemento successivo da eliminare (per favore fallo:)

L'accumulatore dovrebbe iniziare inizializzato a 0, lo stesso vale per tutti gli elementi nella linea di ritardo. In altri casi la tua media corrente sarà sempre sbagliata. Vedrai che delayLine_init si occupa di inizializzare la linea di ritardo, dovresti occuparti tu stesso dell'accumulatore.

aggiungere un elemento alla linea di ritardo è facile come decrementare l'indice dell'elemento più recente di 1, assicurandosi che non indichi il lato dell'array della linea di ritardo. dopo aver decrementato l'indice quando è 0, verrà eseguito un ciclo intorno a 255 (perché è un intero senza segno a 8 bit). L'operatore Modulo (%) con la dimensione della matrice di linee di ritardo assicurerà che l'indice punti a un elemento valido.

Il calcolo di una media corrente dovrebbe essere facile da capire se hai seguito la mia analogia nel passaggio precedente. Sottrarre l'elemento più vecchio dall'accumulatore, aggiungere il valore più recente all'accumulatore, spingere il valore più recente sulla linea di ritardo, restituire l'accumulatore diviso per il numero di elementi.

Facile, vero?

Sentiti libero di provare a usare il codice allegato per capire meglio come funziona tutto questo. Allo stato attuale, arduino legge il valore analogico sul pin analogico A0 e stampa "[valore ADC], [media corrente]" sulla porta seriale a 115200 baud rate. Se apri il plotter seriale di arduino alla velocità di trasmissione corretta, vedrai due righe: valore ADC (blu) e valore livellato (rosso).

Passaggio 5: extra

Extra
Extra

Ci sono alcune cose che non devi necessariamente sapere per utilizzare la media corrente nel tuo progetto, ma non ti farà male sapere.

ritardo: Inizierò parlando dell'illustrazione di questo passaggio. Noterai che la media di più elementi introduce un ritardo maggiore. Se il tempo di risposta alla modifica del valore è critico, potresti voler utilizzare una media mobile più breve o aumentare la frequenza di campionamento (misurare più spesso).

Andare avanti.

inizializzazione: quando ho parlato di inizializzare accumulatore e elementi di ritardo, ho detto che dovresti inizializzarli tutti a 0. In alternativa puoi inizializzare la linea di ritardo a qualsiasi cosa ti piaccia, ma l'accumulatore dovrebbe iniziare come una somma degli N elementi più recenti nella linea di ritardo (dove N è il numero di elementi nella media corrente). Se l'accumulatore inizia come qualsiasi altro valore, la media calcolata sarà errata, troppo bassa o troppo alta, sempre della stessa quantità (assumendo le stesse condizioni iniziali). Ti suggerisco di provare a capire perché è così usando una "simulazione carta e penna".

dimensione dell'accumulatore: dovresti anche notare che l'accumulatore dovrebbe essere abbastanza grande da memorizzare la somma di tutti gli elementi nella linea di ritardo se sono tutti positivi o negativi max. In pratica ciò significa che l'accumulatore dovrebbe essere un tipo di dati maggiore degli elementi della linea di ritardo e firmato, se gli elementi della linea di ritardo sono firmati.

trucco: lunghe linee di ritardo occupano molta memoria. Questo può diventare rapidamente un problema. Se sei molto limitato dalla memoria e non ti interessa molto la precisione, puoi approssimare la media corrente omettendo completamente il ritardo e facendo invece questo: sottrai 1/N * accumulatore dall'accumulatore e aggiungi un nuovo valore (su un esempio di 8 media di lunga durata: accumulatore = accumulatore * 7/8 + newValue). Questo metodo fornisce risultati errati, ma è un metodo decente per calcolare la media corrente quando si sta esaurendo la memoria.

linguistica: "media/media mobile" viene in genere utilizzata quando si fa riferimento alla media in tempo reale mentre "media/media mobile" di solito significa che l'algoritmo è in esecuzione su un set di dati statici come un foglio di calcolo Excel.

Passaggio 6: conclusione

Spero che questo tutorial sia stato abbastanza facile da capire e che ti aiuterà nei tuoi progetti futuri. Non esitare a postare domande nei commenti qui sotto se c'è qualcosa di poco chiaro.

Consigliato: