Primer 7 - FIR filter - detektovanje prisutnosti signala
Koristeći FIR filter proveriti da li u signalu iz primera broj 6 postoji sinusoida od 500Hz. Za projektovanje FIR filtera koristiti alate poput:
Rezultat projektovanja FIR filtera
Rešenje
#include <math.h>
#include <stdlib.h>
#define N 43
int h[N] = {
-16, -58, -116, -142, -78,
85, 265, 322, 201, 30,
63, 436, 915, 929, -20,
-1815, -3525, -3869, -2119, 1199,
4430, 5766, 4430, 1199, -2119,
-3869, -3525, -1815, -20, 929,
915, 436, 63, 30, 201,
322, 265, 85, -78, -142,
-116, -58, -16
};
#define DUZINA 500
int signal[DUZINA];
int filtriran[DUZINA];
void FIR(int in[], int h[], int out[], int len) {
int i, j, hi, xi = 0;
long y, x[N];
for (j=0; j<N; j++) x[j]=0;
for (j=0; j<len; j++) {
y = 0;
x[xi] = in[j];
hi = N - xi - 1;
for (i=0; i < N; i++) {
y += h[hi] * x[i];
if (++hi == N) hi=0;
}
if (++xi == N) xi=0;
out[j] = (int)(y >> 16);
}
}
// Obratiti paznju na razliku ove funkcije i iste funkcije iz prethodnog zadatka
void generisi_signal(int s[], int n, int f1, int f2, int f3, int fs, int offset, int ampl ) {
int i;
for (i=0; i<n; i++) {
s[i] = offset + (ampl/3)*sin((6.28*f1*i)/fs) + (ampl/3)*sin((6.28*f2*i)/fs) + (ampl/3)*sin((6.28*f3*i)/fs);
}
}
int ima_signala(int s[], int len, int treshold) {
int i;
for (i=0; i<len; i++) {
if (s[i]>treshold) {
return 1;
}
}
return 0;
}
int main(void) {
// u bafer koji se zove "signal" i duzine je "DUZINA"
// smestiti odbirke zbira sinusnih signala frekvencija 50Hz, 500Hz i 1500Hz
// frekvencija odabiranja je 6kHz
// posto se trazi da signal bude unipolaran, njegov ofset je 32767
// i amplituda je 32767
generisi_signal(signal, DUZINA, 50, 500, 1500, 6000, 0, 32767);
// Filtriraj signal tako da ostane samo 500Hz (bandpass)
FIR (signal, h, filtriran, DUZINA);
// proveri da li ima signala od 500Hz
int ima;
// Ako se pojavi odbirak koji ima amplitudu vecu od 40000 znaci da signala ima
ima = ima_signala(filtriran, DUZINA, 40000);
while(1); // mrtva petlja
}