Autor Tema: FFT Codigo alternativo  (Leído 3317 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Rango

  • PIC10
  • *
  • Mensajes: 6
FFT Codigo alternativo
« en: 07 de Septiembre de 2013, 14:34:22 »
Alguien puede decirme cual es el código alternativo en CCS a esta línea?

                tr = FIX_MPY(wr,fr[j]) - FIX_MPY(wi,fi[j]);
                ti = FIX_MPY(wr,fi[j]) + FIX_MPY(wi,fr[j]);


Esto es parte de la función fix_fft, bastante popular y que está por todas partes.

He encontrado lo siguiente:

            c = ((long int)wr * (long int)fr[j]);
            c = c >> 14;
            b = c & 0x01;
            tr = (c >> 1) + b;

Pero esto solo funciona correctamente con el Hi-TECH, con el CCS falla.

Esto equivale a:          tr = FIX_MPY(wr,fr[j])


El problema es que creo que concretamente la línea     c = ((long int)wr * (long int)fr[j]); falla en el CCS, he probado todas las combinaciones posibles en cuanto a los tipos de datos y no obtengo los resultados esperados.
Lo ideal es que esta linea que indico pudiera programarse de alguna forma en el CCS, pero desconozco la solución que puedo darle. No se que alternativa puedo dar en CCs a c = ((long int)wr * (long int)fr[j]); que como he indicado funciona correctamente con el HI-TECH

Si alguien puede echarme una mano...

Desconectado reiniertl

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1187
Re: FFT Codigo alternativo
« Respuesta #1 en: 09 de Septiembre de 2013, 18:44:30 »
Si estás tratando de utilizar FFT es porque algo de PDS estás haciendo y me imagino que utilizas un dsPIC así que creo que puedes hacer dos cosas o utlizas código en ASm para esa parte o cambias de compilador.

De otro modo dudo mucho que puedas sacar provecho del DSP-engine del dsPIC. Si no usas dsPIC entonces también te recomiendo cambiar de micro. La FFT es bastante pesada sin un módulo de procesamiento de datos, no por gusto existen los procesadores digitales de señal.

Un saludo
Reinier

Desconectado Rango

  • PIC10
  • *
  • Mensajes: 6
Re: FFT Codigo alternativo
« Respuesta #2 en: 10 de Septiembre de 2013, 18:10:29 »
Ya se que lo ideal son los dspic, pero quiero empezar por algo menos potente como por ejemplo el PIC18F4550 e ir adaptando en función de los requerimientos a micros mas potente, pero quiero empezar desde este nivel y tener algo en claro y funcionando aunque sea para empezar con una LCD de 16x2.

Tampoco quiero meterme con el asm, aunque el código estaría evidentemente muy optimizado, pero de momento no es ese el objetivo, solo pretendo tener algo funcional, compilable con el CCS, aunque ya sabemos que el CCS no es lo mejor, pero he de utilizarlo en este caso.

Si alguien necesita el código completo, puedo subirlo, aunque solo es compilable con el HiTech. Es facilmente localizable en internet. Lo que estoy intentando es migrarlo al CCS, y me encuentro con el problema que indico mas arriba. Ya sabemos que el HiTech es mucho mas completo, optimizado, profesional, etc, etc...


Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: FFT Codigo alternativo
« Respuesta #3 en: 10 de Septiembre de 2013, 18:16:43 »
Como bien te dice Reiner, CCS ya incluye librerias y ejemplos de filtros FFT y FIR, pero estan diseñados para los DSPIC...
Te queda traducirlos a otro PIC menor...
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado reiniertl

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1187
Re: FFT Codigo alternativo
« Respuesta #4 en: 10 de Septiembre de 2013, 18:47:23 »
También puedes utilizar un algoritmo genérico y meterlo dentro del PIC. Por ejemplo el libro de Di Jasio  Programming 32 Microcontrollers in C. Exploring the PIC32 tiene un ejemplo de código para FFT que puedes mover para el PIC18. Sin embargo debes saber que con un algoritmo así lo más rápido que podrás muestrear y procesar debe andar por 100 s/s (muetras por segundo) lo que te limita a señales de muy baja frecuencia (30 Hz).

Un saludo
Reinier

Desconectado Rango

  • PIC10
  • *
  • Mensajes: 6
Re: FFT Codigo alternativo
« Respuesta #5 en: 10 de Septiembre de 2013, 19:04:08 »
Agradezco todas las orientaciones que me vais dando, que por supuesto seguro que superan la solución que he rescatado de la web, que por cierto es esta:

http://www.waitingforfriday.com/index.php/Real-Time_Audio_Spectrum_Analyser


Y que prácticamente ya tengo el código migrado, a falta de algunos detalles, como por ejemplo este que comento.

¿Tan complicado es implementar estas líneas de código en el CCS y ponerlo todo a funcionar? y a partir de ahí tener una referencia para implementar códigos mas completos y eficientes en micros mas potente?

Luego la pregunta es: ¿es tan difícil implementar estas dos líneas como para tener que cambiar ahora a otro código, micros, etc, etc...? en realidad solo necesito eso, ya que de momento el proyecto que aparece en esta web me interesa.

Me reitero nuevamente en las gracias por las aportaciones hechas.

Desconectado reiniertl

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1187
Re: FFT Codigo alternativo
« Respuesta #6 en: 11 de Septiembre de 2013, 11:26:30 »
Como te comenta MGLSOFT el problema es que esas funciones de CCS están diseñadas para trabajar con el dsPIC, y no es por gusto que se llaman dsPIC. A diferencia de los PICs normales los dsPIC tienen un conjunto de elementos de hardware dedicados solamente a la aritmética para procesamiento digital de señales. Por ejemplo tienen un multiplicador de 16x16 bits que puede multiplicar enteros y fraccionales Q15. Acumuladores de 40 bits para guaradr esos resultados con pérdida mínima de precisión en las operaciones, unidades de generación de dirección que pueden hacer direccionamiento modular para "circular buffering" o bit reversed para hacer FFT, un desplazador de barril para hacer redondeos y desplazamientos sobre los acumuladores de 40 bits.

Así que la arquitectura de un dsPIC es distinta del resto e los PICs en muchos aspectos y es por ello que esas funciones no funcionan sino es con un dsPIC. Tampoco eso es por gusto, un filtro FIR de 128 etapas implementado en un PIC normal  a40MIPS puede demorar varios milisegundos en calcular el resultado, mientras que un dsPIC utilizando su DSP engine puede hacer lo mismo en algunos microsegundos. La diferencia puede ser tan abismal como que el dsPIC puede hacer trabajos de procesamiento de señales hasta cientos de veces más rápido que un PIC normal.

Por ejemplo para procesar audio y obtener su espectro tendrás que muestrear a 44ksps es decir que tienes que tomar 44 000 muestras cada segundo y para cada muestra hacer  la FFT, que es por cierto un algoritmo muy matemático y muy intensivo. El dsPIC tiene para ello direccionamiento bit reversed, que permite hacer la FFT mucho más rápido que con otros métodos. Mejor aún, un aumento lineal en el número de coeficientes implica un aumento logarítmico en el tiempo, así que si cambias de un filtro de 128 a 512 muestras el costo en tiempo sólo se duplica. Y has cuadruplicado el orden del filtro, pero no tan simple, eso implica un aumento increíble en su capacidad de discriminar creo que unos 128dB.

Ya que te estás metiendo en eso te recomiendo este libro que puedes encontrar en la web [California Technical Publishing][Steven W. Smith]  The Scientist and Engineer's Guide to Digital Signal Processing Second Edition. Es muy bueno, en mi opnión el mejor porque te explica todos los conceptos básicos de PDS sin meterse en los muy complicados problemas matemáticos.

Espero hber aclarado tus dudas.

Saludos
Reinier

PD: Si vas a hacer PDS con PICs cambia ahora mismo a dsPIC y comienza a estudiar el libro que te recomiendo. Verás que es un mundo fascinante pero también complejo. Aunque en el proceso puedes volverte uno de los pocos que son capaces de hacer procesamiento digital de señales más allá de MATLAB.

Desconectado Rango

  • PIC10
  • *
  • Mensajes: 6
Re: FFT Codigo alternativo
« Respuesta #7 en: 11 de Septiembre de 2013, 16:38:06 »
Me parece muy bien todo lo que argumentas reiniertl. Buscaré la referencia del libro que me indicas y le echaré un vistazo a ver que tal.

Bueno, a lo que iba. No se si habrás visto reiniertl el enlace que pongo en el post anterior. Esto está hecho con un PIC18F4550 compilado con Hi-Tech -vuelvo a repetir-, lo único que pretendo por ahora es migrar este código del Hi-Tech al CCS, y por lo que se puede leer según indico, tengo algunos problemas con algunas líneas -como he comentado en el primer post- , por lo que quiero utilizar este código, repito, pero migrado al CCS. No se si me he explicado.

Está perfecta toda la tecnología de los dsPic, y veo que hay mucha gente se mueve a esos niveles, pero ¿no va haber nadie que tenga la solución de migrar un par de lineas de una mierda de código para que todo esto funcione con un PIC18F4550, como aparece en el enlace que indico?


Nuevamente , gracias.

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: FFT Codigo alternativo
« Respuesta #8 en: 11 de Septiembre de 2013, 17:05:46 »
¿no va haber nadie que tenga la solución de migrar un par de lineas de una mierda de código para que todo esto funcione con un PIC18F4550, como aparece en el enlace que indico?

Nuevamente , gracias.

Disiento contigo en lo que dices.

  • Primero porque no has leido las reglas del foro, ya que exiges que te hagamos el trabajo, y con esos modos y forma de expresarte estas obteniendo exactamente lo opuesto de quienes te leen. Cambia de actitud y veras como consigues ayuda...
  • Segundo: Si vas a copiarte, al menos respeta el trabajo de quien lo hizo (seguramente sin pedir ayuda, o al menos sin exigirla) y que compartió 1040 líneas de código, en las cuales se apaño con tablas y librerías propias para meter todo esto dentro de un miserable PIC18F4550.  ((:-)) ((:-)) ((:-))
    Yo baje y lei el codigo, (no son dos líneas de mi.... como dices) y creo que si puede portarse muy bien al CCS, para ello deberás tener en cuenta las diferencias entre compiladores, especialmente el alcance numérico de ambos respecto a la misma declaración de variables (por ejemplo no es lo mismo una long Int en CCS que en Hitech), además del uso de instrucciones de reemplazo.


Es todo lo que puedo aportarte por ahora, si veo que intentas avanzar por tus medios te ayudare, y puedo asegurarte que muchos otros lo harán (somos casi 40000 usuarios registrados, asi que ayuda no te faltara), pero debes comenzar tu mismo, y desacreditando a tu fuente no es el mejor camino...
« Última modificación: 11 de Septiembre de 2013, 17:08:11 por MGLSOFT »
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado Rango

  • PIC10
  • *
  • Mensajes: 6
Re: FFT Codigo alternativo
« Respuesta #9 en: 11 de Septiembre de 2013, 17:55:11 »
Perdón por si alguien se ha sentido ofendido, no era mi intención ni tampoco creo que sea ofensivo el fondo del argumento de lo que escribo.

Pero.

1º.- Si preguntas una cosa, y reiteradamente te contestan con otra, me da la sensación de que, o no te quieres enterar o tengas la pretensión de vanagloriarte con cuatro conceptos puntuales, intentando dar a entender que posiblemente conozcan cuatro conceptos que ni si quiera domines, aunque claro, también he de contemplar una mala interpretación por mi parte y equivocarme en ello, por lo tanto, ya, desde ahora, pido disculpas.

2º.- Lo de "una mierda de código" no es despreciativo, y mucho menos hacia una persona que se lo ha currado y lo ha publicado para que otros lo utilicen. No es mas que una comparación coloquial con otro tipo de códigos como por ejemplo el asm para resolver este tipo de problemas, y sobre todo gracias a esta persona por ser de las pocas que se curra las cosas y encima las regala.

3º.- No pido que me hagan el trabajo, puesto que ya lo tengo migrado a falta de estas dos lineas que me están dando problemas, y es por lo que escribo en este foro, por si alguien sabe que solución se le puede dar --reiterada petición casi en todos los post que he puesto-- y por supuesto que he tenido en cuenta las diferencias en cuanto a los tipos de datos de un compilador a otro.

4º.- Si puedes pensar que estoy exigiendo que me están regalando el trabajo por estas dos líneas, desde luego, me he equivocado de foro.

Bueno. Nuevamente, pido disculpas, y solo me queda añadir, que lo único que busco es la solución a estas dos líneas.



Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: FFT Codigo alternativo
« Respuesta #10 en: 11 de Septiembre de 2013, 18:25:50 »
Piensa esto:
De cuantos bits es un Long Int en CCS y de cuantos bits es ese tipo de datos en Hitech.??

Por ahi pasa tu solucion, creo...
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado reiniertl

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1187
Re: FFT Codigo alternativo
« Respuesta #11 en: 11 de Septiembre de 2013, 18:44:58 »
Además:

Que valores tienen asignadas las variables. Si multiplicas dos valores de 16 bits obtienes 32 bits, así que para meterlo en 16 bits hay que desplazar el resultado de la multiplicación, lo que implica la posibilidad de perder una pila de bits. Esto es un error de redondeo y puede ser la primera causa de tus problemas.

Por cierto y MUY IMPORTANTE lo que te comenta MGLSOFT acerca del tamaño de los tipos de datos.


Otro aspecto muy importante es la confiabilidad del compilador. CCS tiene una amarga historia de ser bastante poco confiable, no por gusto me pasé para el C18 de Microchip hace mucho tiempo.

Un saludo
Reinier

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: FFT Codigo alternativo
« Respuesta #12 en: 11 de Septiembre de 2013, 21:19:27 »
Bueno, haciendo una búsqueda en San Google, obtienes respuestas como esta:

DEFINICION DEL TIPO DE VARIABLE: ANSI C maneja varios tipos de datos para sus constantes y variables, los cuales deben definirse previamente.
Existen diferencias entre las definiciones del Compilador HITECH y CCS.

DEFINICIÓN EN C          TIPO DE DATO             RANGO EN HITECH           RANGO EN CCS              EJEMPLO
char                                   entero, ASCII                0...255 (8 bits)            0...255 (8 bits)              char a,b,c;
unsigned char                   entero, ASCII                0...255 (8 bits)            0...255 (8 bits)              unsigned char x;
signed int                         entero con signo         -32,768...+32,767 (16 bits)   -128...+127 (8 bits)      signed int alfa,beta;
unsigned int                   entero positivo              0...65536 (16 bits)              0...255 (8 bits)      unsigned int fito;
long int                                entero                              32 bits                            16 bits              long int var1;
float                                   punto flotante                      24 bits                            32 bits              float rim;

Fuente:  http://www.puntoflotante.net/VARIABLES%20ARREGLOS.htm

Observa la diferencia de ambos compiladores en long int como tipo de datos !!
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado Rango

  • PIC10
  • *
  • Mensajes: 6
Re: FFT Codigo alternativo
« Respuesta #13 en: 13 de Septiembre de 2013, 16:15:33 »
Evidentemente es importante el tamaño de los datos, por eso he puesto el máximo interés y se han hecho las correcciones oportunas al respecto.

Además de esto, creo que habré probado con casi todos los tipos posibles similares del CCS con respecto a los que maneja el Hitech.
Está simulado tanto con el Proteus para el CCS, como con el MPLAB para el Hitech y el fallo se produce siempre en el mismo punto, en el comienzo de las líneas que indico en el primer post. El resultado que obtengo en el simulador del Proteus no coincide con el del Hitech.
He utilizado la misma función de multiplicación que utiliza el Hitech, creo que es lmul y la he copiado en el código --esto es para tener mas similitud con el código compilado con el Hitech--, y tampoco va.

Si los tipos no coinciden ahora en los archivos que adjunto es posiblemente porque se habrán quedado así desde los últimos cambios que hice, pero habré probado creo que casi todas las posibilidades.

Bueno, subo los archivos del CCS y del Proteus, por si alguien quiere probarlos.

No se si habrá algún detalle que corregir en el código del GLCD, pero como el fallo en el resultado de la multiplicación lo da en otro sitio antes de haber llegado al código del GLCD tampoco me he puesto a supervisarlo detalladamente, hasta conseguir resolver el error que comento en las primeras líneas de este post y en el primer post.

Gracias