Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Filtro digitale prima prova

teoria dei segnali, elaborazione, trasformate Z, Fourier, segnali caratterizzati da processi e variabli aleatorie, stimatori, DSP

Moderatori: Foto Utenteg.schgor, Foto Utentedimaios

3
voti

[11] Re: Filtro digitale prima prova

Messaggioda Foto UtenteDirtyDeeds » 17 mar 2013, 19:09

simo85 ha scritto:e una frequenza di campionamento f_s = 2\,f_s


Volevi dire f_s = 2\,f_c ?

Se è così non va bene, devi scegliere f_s > 2f_c.
It's a sin to write sin instead of \sin (Anonimo).
...'cos you know that cos ain't \cos, right?
You won't get a sexy tan if you write tan in lieu of \tan.
Take a log for a fireplace, but don't take log for \logarithm.
Avatar utente
Foto UtenteDirtyDeeds
55,9k 7 11 13
G.Master EY
G.Master EY
 
Messaggi: 7012
Iscritto il: 13 apr 2010, 16:13
Località: Somewhere in nowhere

0
voti

[12] Re: Filtro digitale prima prova

Messaggioda Foto Utentesimo85 » 17 mar 2013, 19:11

Si ho sbagliato a scrivere. :(

Grazie per la precisazione!
Avatar utente
Foto Utentesimo85
30,9k 7 12 13
Disattivato su sua richiesta
 
Messaggi: 9927
Iscritto il: 30 ago 2010, 4:59

2
voti

[13] Re: Filtro digitale prima prova

Messaggioda Foto UtenteDirtyDeeds » 17 mar 2013, 19:20

Tra l'altro c'è qualcosa che non mi quadra nelle equazioni per il calcolo dei coefficienti che hai scritto: perché quelle siano valide direi che dovresti avere:

\omega_c = 2\pi\frac{f_c}{f_s}
It's a sin to write sin instead of \sin (Anonimo).
...'cos you know that cos ain't \cos, right?
You won't get a sexy tan if you write tan in lieu of \tan.
Take a log for a fireplace, but don't take log for \logarithm.
Avatar utente
Foto UtenteDirtyDeeds
55,9k 7 11 13
G.Master EY
G.Master EY
 
Messaggi: 7012
Iscritto il: 13 apr 2010, 16:13
Località: Somewhere in nowhere

10
voti

[14] Re: Filtro digitale prima prova

Messaggioda Foto Utentedimaios » 17 mar 2013, 19:40

Foto Utentesimo85, a parte il problema delle frequenze normalizzate dovrebbe insospettirti il fatto che la risposta impulsiva h(n) che hai ottenuto non è simmetrica.
Ho provato a progettare un FIR di ordine 32 con frequenza normalizzata pari a 0.5 ed il risultato è il seguente.

CoefficientsFIR.jpg
CoefficientsFIR.jpg (20.09 KiB) Osservato 2116 volte


I coefficienti devono essere simmetrici e tutti nella parte n>0 altrimenti il filtro sarebbe anticausale ovvero richiederebbe i campioni futuri.
Questa cosa non è impossibile nel senso che se hai già i tuoi campioni memorizzati da qualche parte e vuoi filtrarli off-line è possibile avere a disposizione i campioni successivi a quello attuale.
Nel tuo caso invece vuoi elaborare il segnale d'ingresso in realtime per cui la risposta impulsiva deve essere causale.

Ad ogni modo una frequenza di campionamento pari a 10 kHz implica che il range di frequenze "filtrabili" digitalmente è tra 0 e 5 kHz.
Se scegli il taglio proprio a 5 kHz vuol dire che ottieni di fatto un passa-tutto.

Siccome il campionamento di un segnale in frequenza si traduce nella ripetizione periodica del suo spettro, il filtro continuo che vuoi discretizzare ( oppure direttamente sintetizzare nel dominio discreto ) potrà essere specificato da 0 e \frac{F_c}{2}.
In pratica la frequenza di taglio F_t del tuo passa-basso dovrà essere compresa tra gli estemi precedentemente citati.
Se F_t=\frac{F_c}{2} ottieni di fatto un filtro passa-tutto.




Per fare l'esercizio imposta F_c=10kHz ed F_t=1kHz.
In questo modo potrai eseguire un test di validazione dando in ingresso al filtro la somma di due sinusoidi, una in banda passante e l'altra al di fuori di essa.

u_{in}(t) = \sin(2\pi f_1 t) +  \sin(2\pi f_2 t)

f_1=100 Hz ed f_2=3kHz.

Se tutto funziona correttamente all'uscita dovresti ottenere un segnale che approssima molto bene il segnale \sin(2\pi f_1 t).
Ingegneria : alternativa intelligente alla droga.
Avatar utente
Foto Utentedimaios
30,2k 7 10 12
G.Master EY
G.Master EY
 
Messaggi: 3381
Iscritto il: 24 ago 2010, 14:12
Località: Behind the scenes

9
voti

[15] Re: Filtro digitale prima prova

Messaggioda Foto Utentedimaios » 17 mar 2013, 19:50

Foto Utentesimo85 ti invito ad impiegare un tool per la sintesi del filtro così prendi mano con i parametri di design e solo successivamente andrai ad indagare le tecniche di progettazione.

Per esempio se usi questo hai in uscita già i coefficienti in double oppure in int ... anzi ... fornisce addirittura il codice già scritto che puoi facilmente studiare. ;-)

Il vantaggio è quello di concentrarsi sull'implementazione ed i relativi problemi.
Poi puoi indagare a fondo sulle tecniche di sintesi.
Ce ne sono moltissime, ognuna delle quali ha pro e contro che devono essere valutati in base all'applicazione.

Anche se non banale la miglior tecnica di progettazione per i filtri FIR è sicuramente quella di Parks McClellan che utilizza l'algoritmo di Remez. :ok:
Ingegneria : alternativa intelligente alla droga.
Avatar utente
Foto Utentedimaios
30,2k 7 10 12
G.Master EY
G.Master EY
 
Messaggi: 3381
Iscritto il: 24 ago 2010, 14:12
Località: Behind the scenes

4
voti

[16] Re: Filtro digitale prima prova

Messaggioda Foto UtenteDirtyDeeds » 17 mar 2013, 20:46

dimaios ha scritto:In pratica la frequenza di taglio F_t del tuo passa-basso dovrà essere compresa tra gli estemi precedentemente citati.
Se F_t=\frac{F_c}{2} ottieni di fatto un filtro passa-tutto.


Infatti. Con le notazioni di Foto Utentesimo85, per f_c = f_s/2, si deve allora avere

h[n] = \begin{cases} 1 &n=0 \\ 0 &n\neq 0\end{cases}

cosa che non viene se si definisce

\omega_c = \frac{f_c}{f_s}

Con la pulsazione

\omega_c = 2\pi\frac{f_c}{f_s}

invece, per f_c = f_s/2, si ha \omega_c = \pi e

h[0] = \frac{\omega_c}{\pi} = 1

e

h[n] = \frac{\sin(\omega_c n)}{\pi n} = h[n] = \frac{\sin(\pi n)}{\pi n} = 0

per n\neq 0.

Per evitare questo tipo di pasticci, e per evitare di avere \pi che gira nei coefficienti, nell'analisi dei segnali preferisco sempre lavorare con le frequenze e non con le pulsazioni.
It's a sin to write sin instead of \sin (Anonimo).
...'cos you know that cos ain't \cos, right?
You won't get a sexy tan if you write tan in lieu of \tan.
Take a log for a fireplace, but don't take log for \logarithm.
Avatar utente
Foto UtenteDirtyDeeds
55,9k 7 11 13
G.Master EY
G.Master EY
 
Messaggi: 7012
Iscritto il: 13 apr 2010, 16:13
Località: Somewhere in nowhere

1
voti

[17] Re: Filtro digitale prima prova

Messaggioda Foto Utentesimo85 » 17 mar 2013, 20:59

Urca, quindi il libro su cui ho fatto riferimento mi ha dato una cantonata? :(

Menomale che l'ho trovato "in biblioteca" (per così dire)..

Ora sono appena tornato a casa, devo fare un paio di cose in casa, successivamente vedo di aggiustare il tutto secondo i suggerimenti dati..

Vada per la tool offline ovviamente. Dò anche una occhiata al sito linkato, e vedo se riesco a fare il tutto anche con Octave.

Però una cosa la voglio dire. Mi sono fatto 200 pagine di libro studiate di volta in volta in metropolitana la mattina dopo il caffè, e più va avanti questo thread che è appena cominciato, più mi torna in mente l'importanza della pratica assieme alla teoria. Ma questo in tutto.

Siete fantastici, per me è praticamente nuovo l'argomento e passo dopo passo ci metto il mio impegno. Dovevo dirlo..

Vedo di mettermi al lavoro.
Avatar utente
Foto Utentesimo85
30,9k 7 12 13
Disattivato su sua richiesta
 
Messaggi: 9927
Iscritto il: 30 ago 2010, 4:59

4
voti

[18] Re: Filtro digitale prima prova

Messaggioda Foto UtenteDirtyDeeds » 17 mar 2013, 21:23

simo85 ha scritto:Urca, quindi il libro su cui ho fatto riferimento mi ha dato una cantonata?


Gli errori di stumpa sono sempre in agguato ;-) Caveat emptor: prima di usare delle equazioni per un lavoro, da qualunque fonte o autore esse arrivino, se proprio non le si vuole riderivare, fare sempre un controllo su casi semplici per verificare che diano risultati consistenti, di errori ne facciamo tutti :!:

Tieni presente che un segnale discreto non è nient'altro che una successione di numeri, il tempo è sostituito da un indice intero: nel dominio discreto, la frequenza f è una grandezza adimensionata definita nell'intervallo [-1/2,1/2]. Come nel dominio continuo, la pulsazione è data da 2\pi f.

L'analisi di Fourier, continua o discreta, si può fare sia nel dominio delle frequenze che in quello delle pulsazioni, in quest'ultimo caso portandosi dietro (a fatica) un po' di coefficienti \pi. I matematici spesso preferiscono il dominio delle pulsazioni, ma tra gli ingegneri direi che prevale il dominio delle frequenze.
It's a sin to write sin instead of \sin (Anonimo).
...'cos you know that cos ain't \cos, right?
You won't get a sexy tan if you write tan in lieu of \tan.
Take a log for a fireplace, but don't take log for \logarithm.
Avatar utente
Foto UtenteDirtyDeeds
55,9k 7 11 13
G.Master EY
G.Master EY
 
Messaggi: 7012
Iscritto il: 13 apr 2010, 16:13
Località: Somewhere in nowhere

0
voti

[19] Re: Filtro digitale prima prova

Messaggioda Foto Utentesimo85 » 18 mar 2013, 3:10

Eccomi.
Dunque, se

\begin{displaymath} \mathrm{sinc}(x) = \begin{cases} 1&x=0 \\  \frac{\sin(x\pi)}{x\pi}&x \neq 0 \end{cases} \end{displaymath}

e la lunghezza dell'array h (la chiamerò N_h) deve essere la metà di quella dell'array x e y (ma forse non necessariamente - non mi è ancora del tutto chiaro :oops: - ) e

DirtyDeeds ha scritto:nel dominio discreto, la frequenza f è una grandezza adimensionata definita nell'intervallo [-1/2,1/2].


Rappresento la risposta all' impulso h per N = 32 punti ed N_h = N/2.



A seguire ho scritto il programma in C per stampare i coefficienti secondo la risposta d'impulso.
Ho pure corretto la condizione di input del numero all'esecuzione del programma (prima dava Segmentation Fault per pure questioni di endianess ed allocazioni di memoria).
Ho anche fatto in modo che all'esecuzione sia possibile scegliere individualmente la lunghezza di x[] e la lunghezza di h[]

dimaios ha scritto:Per fare l'esercizio imposta F_c=10kHz ed F_t=1kHz.

OK quindi f_c = 1\text{kHz} e f_s = 10\text{kHz}.

Codice: Seleziona tutto
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>

    /* Pi costant*/
    #define PI 3.1415926535897932384626433832795029L

    void zeros(double x[], double h[], double y[], int N, int N_h)
    {
        unsigned int i = 0, tmpN = 0;
       
        if(N > N_h)
        {
            while(i < N)
            {   
                if(i < N_h)
                    h[i] = 0;

                x[i] = y[i] = 0;
           
                i++;
            }
        }     
        else
        {
            while(i < N_h)
            {   
                if(i < N)
                    x[i] = y[i] = 0;
                       
                h[i] = 0;

                i++;
            }
        }
    }

    double set_LP_coefficient(int n_i, double w_c)
    {
        if(n_i == 0)
            return 2 * w_c;
        else
            return sin(2 * PI * w_c * n_i)/(PI * n_i);
    }

    int main(int argc, char *argv[])
    {   
        if(argc < 2)
        {
            printf("usage: %s N(int)  N_h (int)\n\non is the \
    lenght of x array\nN_h is the lenght of array h\n\n", argv[0]);
            return 1  ;
        }
        else
        {
            /*
                i is the index for arrays
                n_i is the n point
                N is the total point number
                N_h is the impulse response lenght
             */
            int i = 0, n_i = 0;   
            int N = atoi(argv[1]), N_h = atoi(argv[2]);

            /*
                x[N] is the input signal array
                h[N_h] is the impulse response coefficient array
                y[N] is the output signal array

            */
            double x[N], h[N_h], y[N];

            /*
                fs Sampling frecuency set to 10kHz
                fc Cutoff frequency set to 1kHz
                w is 2PI(fc / fs)
            */
            double fc = 1000, fs = 10000, w_c = ((2 * PI * fc) / fs);

            zeros(x, h, y, N, N_h);

            /* set n_i to negative and N_h / 2) + 1 */
            n_i = 0 - (N_h / 2);

            /* set index to zero */
            i = 0;

            while(i < N_h)
            {
                h[i] = set_LP_coefficient(n_i, w_c);
                printf("h[%.2d]\t%.10f\n", i, h[i]);
               
                n_i++;
                i++;
            }
           
            return 0;
        }
    }



A seguire l'esecuzione del programma con N = 32 ed N_h = 16

Codice: Seleziona tutto
h[00]   0.0431684235
h[01]   -0.0350947863
h[02]   -0.0273938263
h[03]   0.0795082871
h[04]   -0.0375186924
h[05]   -0.1148614620
h[06]   0.2927940834
h[07]   0.2000000000
h[08]   0.2927940834
h[09]   -0.1148614620
h[10]   -0.0375186924
h[11]   0.0795082871
h[12]   -0.0273938263
h[13]   -0.0350947863
h[14]   0.0431684235
h[15]   -0.0033146847


Ora direi che è simmetrica.

Spero non ci siano errori.

Domani vedo di suddividere il programma in funzioni, e se è tutto OK vedo di procedere alla stesura del codice FIR, ora però vado a nanna che è tardi, ho i neuroni in tilt ed alle sette mi alzo. :cry:

EDIT: in rete ho trovato questo che sembra essere altrettanto interessante.
Avatar utente
Foto Utentesimo85
30,9k 7 12 13
Disattivato su sua richiesta
 
Messaggi: 9927
Iscritto il: 30 ago 2010, 4:59

8
voti

[20] Re: Filtro digitale prima prova

Messaggioda Foto Utentedimaios » 18 mar 2013, 10:19

simo85 ha scritto:e la lunghezza dell'array h (la chiamerò N_h) deve essere la metà di quella dell'array x e y (ma forse non necessariamente - non mi è ancora del tutto chiaro :oops: - ) e


Foto Utentesimo85, la lunghezza della sequenza h(n) non dipende dal numero di campioni in ingresso.

Se per esempio scegli di fare un semplice filtro di media con 2 campioni passati avrai :

y(n) = \frac{x(n) + x(n-1)}{2} = 0.5 \cdot x(n) + 0.5 \cdot x(n-1)

Questo e' un filtro FIR ( infatti la risposta all'impulso e' finita ).
In particolare la risposta impulsiva vale 0.5 negli istanti temporali 0 e 1 mentre risulta nulla altrove.
Come vedi con solo 2 coefficienti hai un filtro FIR che esegue la media di due campioni.

In generale il numero di coefficienti del filtro deriva dalle specifiche in frequenza del medesimo.
Se vuoi ottenere un filtraggio piu' spinto il numero di coefficienti aumentera'.

Prima di lanciare la simulazione in C ti conviene vedere lo spettro del filtro per avere un'idea dell'attenuazione e fare una previsione su cosa aspettarti in uscita ( magari utilizza octave ). ;-)
Ingegneria : alternativa intelligente alla droga.
Avatar utente
Foto Utentedimaios
30,2k 7 10 12
G.Master EY
G.Master EY
 
Messaggi: 3381
Iscritto il: 24 ago 2010, 14:12
Località: Behind the scenes

PrecedenteProssimo

Torna a Elaborazione numerica ed analogica dei segnali

Chi c’è in linea

Visitano il forum: Nessuno e 2 ospiti