Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] ArduinoFFT.h generates weird results

Status
Not open for further replies.

wogoos

Member level 2
Joined
Apr 20, 2010
Messages
49
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,909
Hi folks,
I have a question about ArduinoFFT.h running on a Atmega328. I use it on a perfect sine wave sampled with 32*Fb the base frequency of 60Hz with no DC component and no harmonics. The array vReal[SAMPLES] is loaded with the 32 values, one sine cycle period I have generated in excel. The FFT seems to see a DC component in the Bin0 and harmonic in Bin2. Neither are the amplitudes right. The signal itself has a peak of 165 and the FFT calculates a peak of 1374 at bin 1 =60Hz and second harmonic at 120Hz at Bin2 with and amplitude of 620?
The same FFT in excel with the same data produces correct results.

Might the declaration of double vReal[SAMPLES be a problem here?
Is there a problem with ArduinoFFT.h or am I missing something here. Anyone that give me a helping hand? Thanks


C++:
#include <Arduino.h>
#include <arduinoFFT.h>
 
#define SAMPLES 32              //Must be a power of 2
#define SAMPLING_FREQUENCY 1920  //Hz, must be less than 10000 due to ADC
 
arduinoFFT FFT = arduinoFFT();
 
unsigned int sampling_period_us;
unsigned long microseconds;
 
double vReal[SAMPLES]={   
0.0000    ,
32.1899    ,
63.1428    ,
91.6691    ,
116.6726    ,
137.1925    ,
152.4401    ,
161.8296    ,
165.0000    ,
161.8296    ,
152.4401    ,
137.1925    ,
116.6726    ,
91.6691    ,
63.1428    ,
32.1899    ,
0.0000    ,
-32.1899    ,
-63.1428    ,
-91.6691    ,
-116.6726    ,
-137.1925    ,
-152.4401    ,
-161.8296    ,
-165.0000    ,
-161.8296    ,
-152.4401    ,
-137.1925    ,
-116.6726    ,
-91.6691    ,
-63.1428    ,
-32.1899   
};   

double vImag[SAMPLES];
 
void setup() {
    Serial.begin(115200);
 
    sampling_period_us = round(1000000.0/SAMPLING_FREQUENCY);
}
 
void loop() {
  
    /*SAMPLING*/
    // for(int i=0; i<SAMPLES; i++)
    // {
    //     microseconds = micros();    //Overflows after around 70 minutes!
    
    //     vReal[i] = analogRead(A0);
    //     vReal[i] -= 511;
    //     vImag[i] = 0;
    
    //     while(micros() < (microseconds + sampling_period_us)){
    //     }
    // }
 
    for (int i=0; i<SAMPLES;i++) { Serial.print(vReal[i], 1); Serial.print("\n"); } 
    Serial.print("\n");

    /*FFT*/
    FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
    FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
    FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
    double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);
 
    /*PRINT RESULTS*/
    Serial.println(peak);   Serial.println("\n");  //Print out what frequency is the most dominant.
 
    for(int i=0; i<(SAMPLES/2); i++)
    {
        /*View all these three lines in serial terminal to see which frequencies has which amplitudes*/
        
        //Serial.print((i * 1.0 * SAMPLING_FREQUENCY) / SAMPLES, 1);
        //Serial.print(" ");
        Serial.println(vReal[i], 1);    //View only this line in serial plotter to visualize the bins
    }
 
    //delay(1000);  //Repeat the process every second OR:
    while(1);       //Run code once
}

Spectrum.jpg
 

I am not familiar with your fft but I can see in matlab fft figures of 1374 in bin 1 and 620 in bin2.
They are caused by your hanning window and is just smearing of bin 1.

1638835185317.png
 

I am not familiar with your fft but I can see in matlab fft figures of 1374 in bin 1 and 620 in bin2.
They are caused by your hanning window and is just smearing of bin 1.

View attachment 173208
Thanks for the help I was informed that in my case windowing is not needed because I measure precise over one period. I tested it and now the values are generated as expected.

For others someone on an other forum told me that the HANN windowing has a bug, I don't know what the exact problem is but be aware that it might not work exactly as it should work.

I tested the procedure with inputs from a sinewave of 60Hz Ampl=165V + 200V DC and a 300Hz 10V noise harmonic. The FFT calculated also these values.

The performance of the code at and Atmega328 was as follows:
At N-32 the FFT.Compute + FFT.ComplexToMagnitude took 11ms, at N-64 it took 25ms. With and ISR sample routine the FFT can be done in real-time on a N=32 samples per cycle of a 60Hz grid signal.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top