Go Down

Topic: localizar la frecuencia a la que la magnitud de la FFT es máxima (Read 748 times) previous topic - next topic

serggio

Buenas,
tengo una serie de datos obtenidos por un acelerometro, a los cuales quiero aplicarle la FFT. ¿Alguien me podria ayudar a encontrar la frecuencia a la que la magnitud es maxima dentro de un intervalo de datos?.
Gracias.

surbyte


TFTLCDCyg

¿Has considerado el poder de procesamiento que necesitas para combinar una FFT y un acelerómetro?, requerirás por lo menos tres de ellas, una para cada eje.

Te sugiero un núcleo ARM para llevar a cabo la tarea. Para las placas ARM que funcionan en entorno arduino, el procesador de punto flotante no está disponible, incluso el teensy 3.6 no lo tiene, ayudaría bastante con los cálculos complejos y mas aun con los filtros avanzados. Creo que las placas beagle bone e incluso el RPi-3 me parece que si lo tienen activo.

Desafortunadamente los acelerómetros económicos para arduino obligan a filtrar de alguna forma las lecturas, que dicho sea de paso, son de las más errático que he visto para un dispositivo que mide alguna variable del mundo real.

PD: me gustaría ver como implementas el código, he escrito muchas hojas tratando de entender el proceso de cálculo para FFT y aun no me animo a meterlo en un sketch...

serggio

Google : arduino fft library.
Se  que existe la libreria pero no he visto como localizar la frecuencia a la cual la magnitud es maxima

serggio

¿Has considerado el poder de procesamiento que necesitas para combinar una FFT y un acelerómetro?, requerirás por lo menos tres de ellas, una para cada eje.

Te sugiero un núcleo ARM para llevar a cabo la tarea. Para las placas ARM que funcionan en entorno arduino, el procesador de punto flotante no está disponible, incluso el teensy 3.6 no lo tiene, ayudaría bastante con los cálculos complejos y mas aun con los filtros avanzados. Creo que las placas beagle bone e incluso el RPi-3 me parece que si lo tienen activo.

Desafortunadamente los acelerómetros económicos para arduino obligan a filtrar de alguna forma las lecturas, que dicho sea de paso, son de las más errático que he visto para un dispositivo que mide alguna variable del mundo real.

PD: me gustaría ver como implementas el código, he escrito muchas hojas tratando de entender el proceso de cálculo para FFT y aun no me animo a meterlo en un sketch...
No tengo que hacer una para cada eje porque voy a utilizar smv. Cuando lo tenga listo lo comparto.

surbyte

Ahh bien.
Mira esto Arduino FFT Library

La presentación es para indicar que tan bien funciona frente a otros algoritmos.
Ahora modifiquemos el código básico sugerido

Programming example

para que la salida se vea en el monitor serie
Code: [Select]
/*
fft_adc.pde
guest openmusiclabs.com 8.18.12
example sketch for testing the fft library.
it takes in data on ADC0 (Analog0) and processes them
with the fft. the data is sent out over the serial
port at 115.2kb.  there is a pure data patch for
visualizing the data.
*/

// do #defines BEFORE #includes
#define LOG_OUT 1 // use the log output function
#define FFT_N 256 // set to 256 point fft

#include <FFT.h> // include the library

void setup() {
  Serial.begin(115200); // use the serial port
  TIMSK0 = 0; // turn off timer0 for lower jitter - delay() and millis() killed
  ADCSRA = 0xe5; // set the adc to free running mode
  ADMUX = 0x40; // use adc0
  DIDR0 = 0x01; // turn off the digital input for adc0
}

void loop() {
  while(1) { // reduces jitter
    cli();  // UDRE interrupt slows this way down on arduino1.0
    for (int i = 0 ; i < 512 ; i += 2) { // save 256 samples
      while(!(ADCSRA & 0x10)); // wait for adc to be ready
      ADCSRA = 0xf5; // restart adc
      byte m = ADCL; // fetch adc data
      byte j = ADCH;
      int k = (j << 8) | m; // form into an int
      k -= 0x0200; // form into a signed int
      k <<= 6; // form into a 16b signed int
      fft_input[i] = k; // put real data into even bins
      fft_input[i+1] = 0; // set odd bins to 0
    }
    // window data, then reorder, then run, then take output
    fft_window();   // window the data for better frequency response
    fft_reorder();  // reorder the data before doing the fft
    fft_run();      // process the data in the fft
    fft_mag_log();  // take the output of the fft
    sei(); // turn interrupts back on
    for (int i=0; i<FFT_N/2; i++) {
        Serial.print(i);
        Serial.print(" ");
        Serial.println(fft_log_out[i]);
    }
  }
}


La fundamental si la señal de entrada fuera una AC pura, sería un valor alto en dicha frecuencia.
Mi consejo es que uses un generador de funciones, e intentes primero adapatar la señal AC para que pueda ser analizada por el Arduino. (debes desplazar el 0 de la AC en 2.5V y su amplitud pico a pico no puede superar los 2.5V).

Si usaras por ejemplo una señal de f conocida, obtenerias un FFT tal que tengas un valor que sobresaldrá frente a los demás.



Para facilitar la explicación, supongamos por un momento que tu señal fuera algo como el 1er o 2do espectro.
Entonces con una simple determinación de la muestra mayor tendrias tu fundamental.
Esto es fácil en el caso de señales AC con armonicos bajos.
Los casos de estudio pueden complicarse pero solo te doy una idea que seguramente ya sabías.


Go Up