FFT de señal eléctrica.

Hola.

Me gustaría si alguien pudiese orientarme sobre como puedo calcular una FFT a una señal eléctrica. Tengo valores instantáneos de tensión e intensidad de 3 ciclos en un array y sus respectivos arrays de tiempos en microsegundos. También tengo el desfase entre las señales.

Se que hay librerías de FFT por ahí pero no tengo claro como aplicarlas para sacar los valores de cada armónico fundamental.

Espero que me podáis ayudar.

Un saludo.

Da igual que sea una señal de audio o una señal electrica, todos deben ingresar por las entradas analogicas.
La librería mas usada ultimamente es Arduino FFT Library
Mira esto tambien Fun with FFT on Arduino

Hay ejemplos, estúdialos y no tendras problemas en ponerlo en marcha.
Mira bien las limitaciónes en memoria que tiene y te aconsejo un Mega aunque anda con UNO tambien.

Esta es otra de las buenas librerías Audio Fast Fourier Transform

Este puede ser buen punto de partida Audio Spectrum Monitor

Gracias surbyte, como siempre tus respuestas me son de bastante ayuda. Ya tenía algún enlace de los que has puesto, pero me los miraré todos con detenimiento.

Un salu2.

Hola.

He mirado los enlaces y para empezar lo que viene en el enlace Fun with FFT on Arduino ni si quiera me compila. Da algún error dentro de la propia librería o algo.

En el resto no entiendo muy bien como obtener lo que quiero. No se como meter mis datos y como sacar la descomposicion en armónicos. No se si me explico.

yo tengo un sistema de medición de la señal que me captura por la entrada analógica valores de una senoidal. quiero meter esos valores en una FFT y que me de los armónicos que tiene esa señal. Ya sea un porcentaje sobre la señal original...su propio valor para cada armónico que aparezca...

A ver si alguien que haya usado antes las FFT me puede ayudar. por que no termino de ver el como hacerlo. Si es posible específico para arduino, ya que algunos de los ejemplos de arriba no lo son.

Un saludo.

Hola.

Ya he conseguido reparar la librería del ejemplo "Fun with FFT on Arduino". Tiene desactualizados varios #define #include en las propias librerías.

Intentaré ver como calcula las cosas a ver si puedo sacar lo que quiero. De todas formas, agradecería a cualquiera que sepa como va el tema que me eche una mano.

Un saludo.

Hola.

Después de trastear un poco con varios programas y librerías, consigo con una que me saque valores de fft de una señal que meto. La cosa es que no tengo muy claro el ancho en Hz de cada "bin" o columna.

Mi señal es una adaptación de la señal de red eléctrica, por lo que el armónico fundamenta (el "bin" o columna 1) debe ser 50Hz, o muy aproximado a esto, y el resto deben ser multiplos de 50Hz. Osea que mi fft debe sacar "bins" o columnas de la forma...

1 -> 0-50Hz
2 -> 50-100Hz
3 -> 100-150Hz
....etc

No se muy bien como hacerlo. Pido si alguien sabe o ya lo ha hecho antes, que me ayude a modificar el siguiente programa para conseguir lo que quiero. Ya sea cambiando las muestras, la velocidad del oscilador ADC de arduino o como sea. (solo me interesa la parte de fft no la de las bandas para las luces)

P.D: Cuando subo las muestras de 256 el programa no saca valores. Creo que este fallo está en la función de la ventana de Hann pero no localizo como solucionarlo.

Gracias.

/*
*  Organo de luces psicodelicas 
*  Organo de luces de tres canales , utilizando la FFT   
*  Autor: Jose Daniel Herrera
*  Fecha: 05/09/2012
*  http://arduino-guay.blogspot.com.es
*/

#include "fix_fft.h"

#define MUESTRAS 128           // Numero de muestras para el cálculo de la FFT
#define LOGM 7                 // Logaritmo en base 2 del número de muestras

#define BAJOS_MEDIOS 7         // Nº de banda para el corte entre Bajos y Medios
#define MEDIOS_AGUDOS 35       // Nº de banda para el corte entre Medios y Agudos

#define BPIN  9                // Pin de salida Bajos
#define MPIN  10               // Pin de salida Medios 
#define APIN  11               // Pin de salida Agudos

#define MAX_PASADAS 10         // Nº de pasadas para el cálculo de los límites

char data[MUESTRAS];           // Array con los valores muestreados (parte real)
char im[MUESTRAS];             // Array con los valores muestreados (parte imaginaria)

unsigned char salida[MUESTRAS/2];  // Valores obtenidos de la FFT (espectro de 64 bandas)
unsigned char bajos,medios,agudos; // Valores calculados para cada canal 

byte  pasada,                            // nº de pasada para el cáculo de los límites
      acumBajos,acumMedios,acumAgudos,   // acumuladores de veces que se supera el límite
      limBajos,limMedios,limAgudos;      // límites calculados para cada canal


/*
* Funcion que aplica una ventana de Hann a los datos muestreados para reducir el 
* efecto de las discontinuidades en los extremos
*/
void aplicaVentana (char *vData) {
    double muestrasMenosUno = (double(MUESTRAS) - 1.0);
 // Como la ventana es simétrica , se calcula para la mitad y se aplica el factor por los dos extremos
    for (uint8_t i = 0; i < MUESTRAS/2 ; i++) {
        double indiceMenosUno = double(i);
        double ratio = (indiceMenosUno / muestrasMenosUno);
        double factorPeso = 0.5 * (1.0 - cos(6.28 * ratio));
 vData[i] *= factorPeso;
 vData[MUESTRAS - (i + 1)] *= factorPeso;
    }
}

void setup() {
    Serial.begin (9600);
      
    // Configuramos el prescaler a 32 -> 16Mhz/32 = 500 KHz
    // como cada conversion son 13 ciclos 500/13 ~ 38.4KHz
    // Es decir podemos medir en teoria hasta unos 19KHz, 
    // que para este proyecto sobra.
    bitWrite(ADCSRA,ADPS2,1);
    bitWrite(ADCSRA,ADPS1,0);
    bitWrite(ADCSRA,ADPS0,1); 

    // Como la señal es muy baja,utilizamos la referencia interna 
    // de 1.1 V en vez de la de defecto de 5 V.
//    analogReference(INTERNAL);   
    
    // Salidas para los canales de Bajos,Medios y Agudos
    pinMode(BPIN,OUTPUT);
    pinMode(MPIN,OUTPUT);
    pinMode(APIN,OUTPUT);
    
    // Variables para el cálculo de los límites
    pasada = 0;
    acumBajos = acumMedios = acumAgudos = 0;
    limBajos = limMedios = limAgudos = 50;
}

void loop() {

    // Realizamos el muestreo 
    for( int i=0; i < MUESTRAS; i++) {
       data[i] = analogRead(0)/4 -128;  //Convertimos de 0..1024 a -128..127                                 
       im[i] = 0;                       // parte imaginaria = 0                          
    }
    
    // Aplicamos la ventana de Hann
    aplicaVentana (data);
    
    // Calculamos la FFT 
    fix_fft(data,im,LOGM,0);
    
    // Sólo nos interesan los valores absolutos, no las fases, asi que 
    // calculamos el módulos de los vectores re*re + im*im.
    for (int i=0; i < MUESTRAS/2; i++){
       salida[i] = sqrt (data[i] * data[i] + im[i] * im[i]);
    }
    
    for (int i=0; i < (MUESTRAS/2); i++){             
       Serial.print (i+1);
       Serial.print (" : ");
       Serial.println (salida[i]);     
    }
 delay (2000);
}

Luego lo miro y te respondo acá mismo

Hola, quisiera saber como se puede modificar esta libreria para que el arreglo me lo grave en una micro-SD y asi tener una mayor cantidad de datos

Antes de consultar, te recomiendo dos cosas:
1. Lee las normas del foro y
2. No revivas hilos viejos que tengan mas de 120 dias. Este hilo es del 2015.
Ahora cierro el hilo de modo que crea un hilo nuevo con tu consulta.