Autor Tema: FILTROS FIR SIN LIBRERIA , todo en c  (Leído 13562 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado latha

  • PIC10
  • *
  • Mensajes: 21
FILTROS FIR SIN LIBRERIA , todo en c
« en: 16 de Septiembre de 2008, 13:50:19 »
ALGUIEN HA INTENTADO HACER LOS FILTROS FIR SIN USAR LAS LIBRERIAS DSP?????

SALUDOS DSD MALAGA.

Desconectado blackcat

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 600
Re: FILTROS FIR SIN LIBRERIA , todo en c
« Respuesta #1 en: 16 de Septiembre de 2008, 19:43:13 »
Yo solo con la libreria y funcionan bien ! ..  :?

Sin embargo, en el libro: Digital Filter Designer's Handbook: Featuring C Routines/Book and Disk vienen rutinas en C sobre filtros FIR
« Última modificación: 16 de Septiembre de 2008, 19:47:42 por blackcat »
Control Automático, DSP & Microcontroladores

Desconectado vtasco

  • PIC12
  • **
  • Mensajes: 72
Re: FILTROS FIR SIN LIBRERIA , todo en c
« Respuesta #2 en: 17 de Septiembre de 2008, 22:58:53 »
creo que el tiempo de ejeecución subirá notoriamente, necesitas usar punto flotante?

Desconectado latha

  • PIC10
  • *
  • Mensajes: 21
Re: FILTROS FIR SIN LIBRERIA , todo en c
« Respuesta #3 en: 18 de Septiembre de 2008, 06:22:44 »
El tiempo de ejecucion y todo, la idea era configurar el direccionamiento circular pero puff,  es usar punteros y se va toda la transmision spi al carajo, lo intentare para probar con un array manual jaja, a ver como va eso.

Por cierto, como le digo a un puntero que me apunte a una direccion fisica, tipo 0xFF00, donde guardo los coef.??

Saludos.

Desconectado blackcat

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 600
Re: FILTROS FIR SIN LIBRERIA , todo en c
« Respuesta #4 en: 19 de Septiembre de 2008, 00:48:24 »
Mucha gente confunde punto flotante con precision ... el punto flotante se diseño para trabajar con rangos numéricos variables .. sin embargo el punto fijo, si tuviera la misma cantidad de bits que punto flotante .. 32bits, ofrecería la misma precisión pero con la desventaja que el rango numérico debe ser fijo .. es decir .. se define que las operaciones y resultados se ubican dentro de un rango ... por ejemplo .. el formato fractional Q15 es de -1 a 0.9999 .. algunas librerias de microchip estan introduciendo el punto fijo con 32 bits .. si no me equivoco, por ahi lo lei  ... otra desventaja es la representación con hexa .. y pues claro .. mucha gente utiliza punto flotante porque es mas bonito ..  :-) .. PERO hay que apoyar la velocidad de procesamiento que ofrece punto fijo respecto a punto flotante .. ademas punto fijo si es bien utilizado da excelentes resultados .. yo trabaje con punto fijo y todo bien .. ahora estoy con unos variadores de frecuencia que usan DSPs en punto fijo y son bastante buenos ..

Disculpa mi ignorancia pero no sé que quieres decir con dirección fisica.

En C todos los punteros se declaran con un asterisco *

Ejemplo:

int una_variable = 5;    // Un dato

int * ptr_una_variable = &una_variable // Puntero a una_variable, el simbolo & significa devolver puntero.

tambien hay punteros a punteros

int ** ptr_ptr_una_variable = &ptr_una_variable  // ptr_ptr_una variable es un puntero a un puntero que apunta a una_variable  :? observa el doble asterisco

Esto es muy util cuando se utilizan structs que tienen punteros ...

Ademas, hay punteros a funciones .. que son de gran ayuda cuando debes seleccionar entre varios algoritmos y evitar el uso de case

 
« Última modificación: 19 de Septiembre de 2008, 00:59:32 por blackcat »
Control Automático, DSP & Microcontroladores

Desconectado latha

  • PIC10
  • *
  • Mensajes: 21
Re: FILTROS FIR SIN LIBRERIA , todo en c
« Respuesta #5 en: 19 de Septiembre de 2008, 06:21:24 »
Direccion fisica es la posicion de memoria donde guardo el dato, el espacio de datos x, y el espacio de datos y, para hacer el filtro fir, logro definir dichos espacios mediante instrucciones del tipo:

fractional _XBSS(128) xbuf[7]; para un fir de 7 coeficientes.
fractional __attribute__((space(ymemory), far, reverse(128))) ybuf[7]; para el buffer de muestras pasadas

Para acceder a estos datos hablamos de un array,, y entonces tengo que indexar, por lo que pierdo la potencia del buffer circular, o eso creo.

Si alguien sabe algo de esto, que me lo comente, lo del tipo de datos pues la libreria dsp usa fractional, yo no la uso, pero sigo con ellos por algo sera que lo usa.

Por cierto tambien configuro el CORCON y XMODSRT , etc pero no se si el espacio de memoria es realmente circular.

Donde podria ver los atributos para reservar memoria pues las lineas anteriores las saque de un ejemplo

Saludos dessde malaga.

Desconectado latha

  • PIC10
  • *
  • Mensajes: 21
Re: FILTROS FIR SIN LIBRERIA , todo en c
« Respuesta #6 en: 21 de Septiembre de 2008, 06:16:11 »
Buenos dias a todos¡, querria saber si alguien me podria dejar algun ejemplo de manejo de un array en el espacio de memoria X o Y con punteros, puesto que.... cuando accedo a esos datos mediate punteros, se me resetea el dspic, y la otra opcion que es acceder a los datos mediante el indexado, pues no se que formato poner, si pongo los coeficientes de modo 0xdf02, segun me los devuelve una aplicacion, al hacer las multiplicaciones del filtro fir, las muestras de salida son todo saturacion, como podria arreglar eso?, que formato deberia usar? y debo configurar el CORCON o algun otro registro?

A este ritmo me paso a ensamblador.

Gracias por leerme

Desconectado latha

  • PIC10
  • *
  • Mensajes: 21
Re: FILTROS FIR SIN LIBRERIA , todo en c
« Respuesta #7 en: 21 de Septiembre de 2008, 13:18:08 »
HOLA SOY BASTANTE PESADO, y cada vez dudas distintas....

tengo el siguiente texto para conseguir un eco pero muy rapido pues el Si3000 que le puse va a 12000Khz y
solo tengo 500 muestras para el buffer por la limitacion del espacio de memoria x.
Porque no me funciona esto, es decir porque no se reproduce nada de audio,si saco la entrada a la salida si se oie
la cancion que pongo de entrada.


extern int muestras[512];
int = 1;

int Programita( int Entrada)
{

int SalidaAnterior,Salida;

SalidaAnterior = muestras;
Salida = (( SalidaAnterior/2) + Entrada);
muestras= Salida;
i++;
if ( i==513)
{
i = 1
}


}

Desconectado learntofly

  • PIC10
  • *
  • Mensajes: 4
Re: FILTROS FIR SIN LIBRERIA , todo en c
« Respuesta #8 en: 25 de Septiembre de 2008, 04:31:23 »
Hola! Yo no se muchisimo sobre lenguaje C, pero los FIR los suelo escribir asi:

//variables ecuacion filtro//
float hn[5]={0.2,0.2,0.2,0.2,0.2}
float xk[5];
void VectorCero(float x[],int n)
{
   int i;
   for(i=0;i<n;i++)
      x=0.0;
}

void VectorDesplaza(float x[],int n)
{
   int i;
   for(i=n-1;i>0;i--)
      x=x[i-1];
}
void _ISR _ADCInterrupt()
{,
.
.
.//Filtro de media//
   desp xk[];
   desp yk[];
   xk[0]=nuevo;
   yk[0]=ProdEsc(xk, hn);
}

Desconectado latha

  • PIC10
  • *
  • Mensajes: 21
Re: FILTROS FIR SIN LIBRERIA , todo en c
« Respuesta #9 en: 25 de Septiembre de 2008, 11:56:29 »
tengo el siguiente codigo para un fir de 5 coeficientes para empezar donde solo uno de ellos es un uno , con lo que se debe oir por la salida la entrada realimentada.

Este es el codigo :

static float XBUFF[5];
const float COEF[5]={0.0, 1.0 , 0.0, 0.0, 0.0};
static int=0;

fractional CODIGOAUDIO( fractional Entrada)
{

Declaracion variables.

for(i=4;i>0;i--)
{

XBUFF =XBUFF[i-1];
}

EntradaF= (float) Entrada;
XBUFF[0]= EntradaF;

for (i=0;i<=4;i++){
Muestra_filtrada=(Muestra_filtrada + (COEF*XBUFF));
}
Salida =(fractional) Muestra_filtrada;
return Salida;
}

El problema esta en.... que cuando ejecuto esto se me escucha el audio pero muy muy muy bajo y con mala calidad, incluso si el return es de Entrada; pero lo curioso es que si elimino la linea: Muestra_filtrada= ,,,,,,,,,,,,,,,,,,,  y hago return Entrada si se oye perfectamente. Entonces el problema puede ser que llega otra muestra antes que se procesen esas 5 multiplicaciones...????
Si alguien se le ocurre algo, yo he pensado hacer ese for con instrucciones ensamblador, y si puede ser con un DO pero no se si se puede añadir ensamblador aqui.

Saludos y gracias


Desconectado blackcat

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 600
Re: FILTROS FIR SIN LIBRERIA , todo en c
« Respuesta #10 en: 25 de Septiembre de 2008, 23:06:04 »
No entiendo varias cosas ...

1.

Código: [Seleccionar]
for(i=4;i>0;i--)
{
    XBUFF =XBUFF[i-1];
}

Esto daria error en la compilación puesto que es el mismo registro y ademas es un arreglo ...  :?  ... supongo que es un desplazamiento de entradas.

2.
Código: [Seleccionar]
EntradaF= (float) Entrada;
XBUFF[0]= EntradaF;

Porque no simplemente XBUFF[0]= (float) Entrada;


3.

Código: [Seleccionar]
for (i=0;i<=4;i++)
{
   Muestra_filtrada=(Muestra_filtrada + (COEF*XBUFF));
}

Que funcionalidad tiene el FOR ??


4.  ... la pregunta del millon ....

Un filtro FIR no tiene "realimentación" .... esto es:      y[n]=b_0 x[n] + b_1 x[n-1] + ... + b_N x[n-N] ... es decir no utiliza resultados de salidas pasadas para calcular una salida (esto seria un IIR), se podria entender como un sistema a lazo abierto, es por esta razon, que un FIR es 100% estable ante toda entrada ...

Sin embargo, estas haciendo:  Muestra_filtrada=(Muestra_filtrada + (COEF*XBUFF));  haciendo una suposición y una correccion:

Código: [Seleccionar]
for (i=0;i<=4;i++)
{
   Muestra_filtrada=(Muestra_filtrada + (COEFF[i]*XBUFF[i]));
}

Si b[] es COEFF[] y x[] es XBUFF[] lo interpretaria de la siguiente manera:

y[n] = y[n-1] + y[n-2] + ... + y[n-N-1] + b_0 x[n] + b_1 x[n-1] + ... + b_N x[n-N]


Ese tipo de filtro no lo conozco (ni FIR, ni IIR) ... supongo que te equivocaste si pudieras hacer las correcciones ... te podria ayudar ...

Consejos:

1. Podes utiilzar matlab para corroborar tu filtro .. ahi podes ver la respuesta en frecuencia y en el tiempo y luego comparar los resultados ante señales de prueba como escalones e impulsos.

2.Tambien, utiliza la opcion de INSERTAR CODIGO ( simbolito de #) ... sino lo utilizas es posible que a la hora de publicar tu mensaje este quite algunos caracteres.

saludos!













« Última modificación: 25 de Septiembre de 2008, 23:33:11 por blackcat »
Control Automático, DSP & Microcontroladores

Desconectado latha

  • PIC10
  • *
  • Mensajes: 21
Re: FILTROS FIR SIN LIBRERIA , todo en c
« Respuesta #11 en: 26 de Septiembre de 2008, 06:11:46 »
insertar codigo, que invento, me faltan caracteres por todo el codigo.
El primer for es para desplazar las entradas, falta el indice XBUFF [ i ]=XBUFF[i-1],con lo que consigo en XBUFF[4] la muestra de entrada de hace 5 pasos, y en XBUFF[0], la actual muestra de entrada.
Luego solo multiplico entradas ,puesto que solo guardo entradas en flotante, y el for es para hacer todas las multiplicaciones del filtro en este
caso son 5 pues hay 5 coeficientes, y el resultado se acumula en Muestra_filtrada, y solo es el coeficiente*muestra_entrada correspondiente.

Saludo y gracias

Desconectado jgpeiro06

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 276
Re: FILTROS FIR SIN LIBRERIA , todo en c
« Respuesta #12 en: 13 de Octubre de 2008, 10:57:57 »
Llevo un par de semanas peleandome con los filtros FIR e IIR. Los filtros IIR no se si no los he implementado bien o no son estables por la cuantificacion o yo q se... pero los FIR si parecen funcionar bien.

este es el codigo:

int N = 3;                 // Filter order
int x[3+1];               // input and output signal buffer
const int h[3+1] = {  //FIR filter zeros coefficients
0.25 *32767,
0.25 *32767,
0.25 *32767,
0.25 *32767
};

// y[n] = SUM(h*x[n-i],i,0,N);
int FIR( int value, int *x, const int *h, unsigned char N )
{
   long sum = 0;
   int i;
   
   for( i = N ; i > 0 ; i-- )
      x = x[i-1];

   x[0] = value;

   for( i = 0 ; i <= N ; i++ )
      sum += (long)h * (long)x;

   return sum >> 15;
}

void main()
{
    int in, out;
    while(1)
    {
        in = readADC();
        out = FIR( in, &x[0], &h1[0], N );
        delay();
    }
}



Los coeficientes los genero con el con el FDATOOL del Matlab.
Ahi va el codigo para los IIR Direct Form I (OJO que es posible que no este bien implementado)

//IIR Direct Form 1: y[n] = SUM(a*y[n-i],i,1,N) + SUM(b*x[n-i],i,0,M);
int IIR_DF1( int value, int *x, int *y, const int *a, const int *b, unsigned char N )
{
//   ; N = filter order
//   ; x[N+1],y[N+1] = input and output signal buffer
//   ; a[N+1], b[N+1] = IIR filter poles and zeros coefficients
   long sum = 0;
   int i;

   for( i = N ; i>=0 ; i--)
   {
      x = x[i-1];
      y = y[i-1];
   }
   
   x[0] = value;
   
   for( i = 0 ; i <= N ; i++ )
      sum += (long)b * (long)x;
   for( i = 1 ; i <= N ; i++ )
      sum += (long)a * (long)y;   //¿sum -= (long)a * (long)y;   ?
   
   y[0] = sum >> 15;
   return y[0];
}



Desconectado jgpeiro06

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 276
Re: FILTROS FIR SIN LIBRERIA , todo en c
« Respuesta #13 en: 13 de Octubre de 2008, 11:12:57 »
no se que xq pero el codigo no se ha copiado bien...

Desconectado latha

  • PIC10
  • *
  • Mensajes: 21
Re: FILTROS FIR SIN LIBRERIA , todo en c
« Respuesta #14 en: 14 de Octubre de 2008, 07:54:17 »
Hola a todos, tu filtro fir en numeros enteros esta correcto, pero a mi me gustaria usar el tipo fraccional aunque no se del todo si merece la pena, lo intento hacer en fraccional pero no hay manera, en la simulacion veo como los resultados son en enteros, si alguien ha hecho multiplicacines en fraccional 1.15 no me vendria mal que me enviase el proyecto , esto seguro que parte del fallo es que defino algo mal puesto que al ver el codigo ensamblador correspondiente usa las instrucciones mul y no la instruccion mpy que la cual se puede configurar en entero o fraccional puesto que la instruccion mul que me usa en el codigo ensamblado solo multiplica enteros y ahi esta todo el problema.
Gracias.

Respecto al filtro IIR es probable que no sea estable puesto que en princpio parece correcto el codigo.

Saludos desde Malaga.


 

anything