Está en la página 1de 9

Instituto Tecnológico de Culiacán

Ingeniería Electrónica

Laboratorio: Electrónica Digital Materia: P.D.S

Practica No: Filtro Fir con Arduino Due Duración (hrs.): 2 hrs.

Profesor:
Título: Procesamiento digital de señales
M.C. Heraclio Heredia
Integrantes: Ureta.
Lee Fonseca Francisco
Rodríguez Cañedo Pedro
Delgado Cañedo José Manuel
Castro Viedas Juan Carlos
Iribe Soto Víctor Alonso
Flores Pérez Héctor Alejandro
Martínez Zavala Jesús Alberto

Materiales: Equipo:
Arduino Due 3 Generadores de señal
Amplificador Operacional LM324 1 Osciloscopio
2 Fuentes triples
Seguridad e Higiene: Seguir las medidas de seguridad e higiene indicadas en el reglamento
interno del Laboratorio.
Introducción

El modelo matemático de los filtros FIR también se fundamenta la ecuación de diferencia,


pero con la particularidad de que todos los coeficientes ak son iguales a cero. Se
tiene entonces que la ecuación que los describe es función del conjunto de coeficientes bk
Y de la secuencia de entrada x(n).

Donde M+1 corresponde a la longitud del filtro. Este sistema considera sólo las ultimas
M+1 muestras de la señal de entrada y las pondera mediante los coeficientes bk.
A este sistema se le denomina FIR, ya que su respuesta al impulso unitario (dada por los
coeficientes bk) es finita.
Su diseño requiere la selección de la secuencia que mejor representa la respuesta al impulso
de un filtro ideal. Los filtros FIR son siempre estables y son capaces de tener una respuesta
lineal en fase. Frente a los filtros IIR presentan la desventaja de requerir un orden mucho
mayor.

Códigos de MatLab para obtener los coeficientes y graficas.-

Para el filtro pasa bajas.-

clc
close all
passband_cutoff=1100;
stopband_cutoff=1500;
rbp=0.01;
rsb=0.01;
frecuencia_de_muestreo=8000;
[n, Wn, beta, typ]=kaiserord( [passband_cutoff stopband_cutoff], [1, 0],
[rbp rsb], frecuencia_de_muestreo )
B=fir1(n, Wn, typ, kaiser(n+1, beta), 'noscale')
Fx=0:0.0005:0.5;
f1=100;
f2=1000;
f3=2000;
n1=0:1:1000;
fm=2*f3;
T=1/fm;
figure(1)
H=freqz(B,1,2*pi.*Fx);
plot(Fx*fm,abs(H))

X= 2+ cos((2*pi*(f1/fm)).*n1) + 0.5.*cos((2*pi*(f2/fm)).*n1)+
0.5.*cos((2*pi*(f3/fm)).*n1);
figure(2)
plot(n1,X)
y=filter(B,1,X);
figure(3)
plot(n1,y)

Para el fltro pasa bandas.-

clc
close all
fcuts = [200 900 1100 1900];
devs = [0.01 0.01 0.01];
frecuencia_de_muestreo=8000;
[n, Wn, beta, typ]=kaiserord(fcuts, [0 1 0], devs, frecuencia_de_muestreo)
B=fir1(n, Wn, typ, kaiser(n+1, beta), 'noscale')
Fx=0:0.0005:0.5;
f1=100;
f2=1000;
f3=2000;
n1=0:1:1000;
fm=2*f3;
T=1/fm;
figure(1)
H=freqz(B,1,2*pi.*Fx);
plot(Fx*fm,abs(H))

X= 2+ cos((2*pi*(f1/fm)).*n1) + 0.5.*cos((2*pi*(f2/fm)).*n1)+
0.5.*cos((2*pi*(f3/fm)).*n1);
figure(2)
plot(n1,X)
y=filter(B,1,X);
figure(3)
plot(n1,y)

Para el filtro pasa altas.-

clc
close all
passband_cutoff=300;
stopband_cutoff=600;
rbp=0.01;
rsb=0.01;
frecuencia_de_muestreo=8000;
[n, Wn, beta, typ]=kaiserord( [passband_cutoff stopband_cutoff], [0, 1],
[rbp rsb], frecuencia_de_muestreo)
B=fir1(n, Wn, typ, kaiser(n+1, beta), 'noscale')
Fx=0:0.0005:0.5;
f1=100;
f2=1000;
f3=2000;
n=0:1:200;
fm=f3*2;
T=1/fm;
H=freqz(B,1,2*pi.*Fx);
figure(1)
plot(Fx*fm,abs(H))
x= 2+ cos((2*pi*(f1/fm)).*n)+ 0.5.*cos((2*pi*(f2/fm)).*n)+
0.5.*cos((2*pi*(f3/fm)).*n);
y= filter(B,1,x);
figure(2)
subplot(211), plot(n.*T,x);
subplot(212), plot(n.*T,y);

Codigo para el arduino due.-


#define FILTERTAPS 31 // El número de coeficientes
// Se declara la formación de valores
float values[FILTERTAPS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0};
float input = 1;
float output = 0;
// Contador de nuestras aplicaciones de la vida real no necesitará esta
byte n = 0;
int interrupcion = 0;
void setup()
{
startTimer(TC1, 0, TC3_IRQn, 4000); //TC1 channel 0, the IRQ for that channel and the
desired frequency
// 20,000 seems to give 100uS/div signal, which is equivalent to 10,000Hz or 10Khz
// put your setup code here, to run once:
analogReadResolution(12);
analogWriteResolution(12);
}
void loop()
{
if (interrupcion == 1) {
// put your main code here, to run repeatedly:
analogWrite(DAC0,fir((float)analogRead(A0)));
//analogWrite(DAC0,analogRead(A0));
interrupcion = 0;
}
}
float fir(float in){
static byte k; // k almacena un puntero para crear una memoria circular a través de la
matriz. Esta variable sigue siendo su valor la próxima vez que llame a la rutina de abeto (de
ahí «estática»)
byte i = 0; //i es un contador con el paso a través de los coeficientes del filtro y los
valores almacenados
float out = 0; // salida es la variable de retorno. Se pone a 0 cada vez que se llama al
filtro!
values[k] = in; // Almacena la entrada de la rutina (contenido de la 'en' variable) en la
matriz en la posición actual del puntero
// Declarar variables para los coeficientes
// Estos se debe calcular a mano, o utilizando una herramienta
// En el caso de un filtro de fase lineal se requiere, los coeficientes son
simétricas
// Para la optimización del tiempo parece mejor para introducir valores
simétricos como a continuación
//pas altas
//float coef[FILTERTAPS] = { -0.0022, -0.0015, 0.0011, 0.0054, 0.0109, 0.0181,
0.0152, 0.0051, -0.0130, -0.0383, -0.0683,
// -0.0990, -0.1255, -0.1436, 0.8500, -0.1436, -0.1255, -0.0990,
-0.0683, -0.0383, -0.0130,
// 0.0051, 0.0152, 0.0181, 0.0159, 0.0109, 0.0054, 0.0011,
-0.0015, -0.0022,
//};
//pasa bajas
float coef[FILTERTAPS] = { 0.0000, -0.0017, 0.0001, 0.0031,
0.0039, 0.0002, -0.0056, -0.0074, -0.0011, 0.0090, 0.0127,
0.0031, -0.0137, -0.0211, -0.0070, 0.0206, 0.0354,
0.0150, -0.0329, -0.0663, -0.0368,
0.0695, 0.2107, 0.3108, 0.3108, 0.2107, 0.0695, -0.0368,
-0.0663, -0.0329, 0.0150,
};
//pasa bandas
//float coef[FILTERTAPS] = { -0.0000, -0.0094, -0.0000, 0.0057, -0.0000, 0.0224,
0.0000, -0.0493, -0.0000, 0.0131,
// 0.0000, 0.1162, 0.0000, -0.2765, 0, 0.3500, 0,
-0.2765, 0.0000, 0.1162,
// 0.0000, 0.0131, -0.0000, -0.0493, 0.0000, 0.0224, -0.0000,
0.0057, -0.0000, -0.0094,
//-0.0000};
// declara coeficiente de ganancia para escalar la salida de vuelta a la
normalidad
float gain = 1; // se pone a 1 y la unidad de entrada.
for (i=0; i<FILTERTAPS; i++) {
out += coef[i] * values[(i + k) % FILTERTAPS]; //(i + k) % FILTERTAPS creates a
cyclic way of getting through the array
}
out /= gain; // Tenemos que escalar la salida (a menos que los coeficientes de
proporcionar ganancia unitaria en la banda de paso)
k = (k+1) % FILTERTAPS; // K se incrementa y se envuelve alrededor de los
FILTERTAPS, así que la próxima vez que se sobreponen a la muestra más antigua guardada
en la matriz
return out; // Enviamos el valor de salida de nuevo a quien llama a la rutina
}
//TC1 ch 0
void TC3_Handler()
{
TC_GetStatus(TC1, 0);
interrupcion = 1;
}

void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) {


pmc_set_writeprotect(false);
pmc_enable_periph_clk((uint32_t)irq);
TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC |
TC_CMR_TCCLKS_TIMER_CLOCK4);
uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected
TIMER_CLOCK4 above
TC_SetRA(tc, channel, rc/2); //50% high, 50% low
TC_SetRC(tc, channel, rc);
TC_Start(tc, channel);
tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
NVIC_EnableIRQ(irq);
}

Diagrama de conexión.-

Señales generadas:
1.- 100 Hz (1 Vpp)
2.- 1000 Hz (0.5 Vpp)
3.- 2000 Hz (0.25 Vpp)
4.- -2V

Resultados.-
Señal de salida del OpAmp. (contiene las tres frecuencias)

Imagen del filtro pasa bajas.-


Imagen del filtro pasa bandas.-

Imagen del filtro pasa altas.-

Conclusiones.-
Se logro implementar los tres principales filtros (pasa bajas, pasa bandas y pasa altas) en un
arduino, con el apoyo de software como el matlab se determinaron los coeficientes para cada
filtro, cabe aclarar que el arduino due tiene integrado adc y dac por lo que es mucho más
fácil la implementación de los filtros.

EVIDENCIAS DE LA REALIZACIÓN DE LA PRÁCTICA (FOTOS DEL


CIRCUITO Y DE LOS INSTRUMENTOS DE MEDICIÓN)

También podría gustarte