hi , recently i brought a MAX9814 AGC microphone amplifier module for applying Fast Fourier Transform for input sound source (hiss kind of sounds) and detecting the frequency peaks in spectrum I have used Arduino uno
well i got the code example tutorial from Arduinoos » Blog Archive » Fast Fourier Transform (FFT) (Part 1)
When i am trying to run the main code the control switches to header file of “PlainFFT.h” in arduino IDE then shows an errors as
In file included from FFTDemo.ino:2:0:
PlainFFT.h:18: error: ‘PlainFFT’ has not been declared
void PlainFFT::windowing(double vData, uint8_t samples, uint8_t windowType, uint8_t dir) {
^
PlainFFT.h: In function 'void windowing(double, uint8_t, uint8_t, uint8_t)’:
PlainFFT.h:31: error: ‘pi’ was not declared in this scope
weighingFactor = 0.54 - (0.46 * cos(2.0 * pi * ratio));
^
FFTDemo.ino: At global scope:
FFTDemo:5: error: ‘PlainFFT’ does not name a type
FFTDemo:7: error: conflicting declaration ‘const uint16_t samples’
In file included from FFTDemo.ino:2:0:
PlainFFT.h:14: error: ‘samples’ has a previous declaration as ‘const uint8_t samples’
const uint8_t samples = 64; // data stored variable vectors
^
FFTDemo:12: error: redefinition of ‘double vReal [64]’
In file included from FFTDemo.ino:2:0:
PlainFFT.h:15: error: ‘double vReal [64]’ previously declared here
double vReal[samples];
^
FFTDemo:13: error: redefinition of ‘double vImag [64]’
In file included from FFTDemo.ino:2:0:
PlainFFT.h:16: error: ‘double vImag [64]’ previously declared here
double vImag[samples];
^
FFTDemo.ino: In function ‘void loop()’:
FFTDemo:34: error: ‘FFT’ was not declared in this scope
FFTDemo:34: error: ‘FFT_WIN_TYP_HAMMING’ was not declared in this scope
FFTDemo:34: error: ‘FFT_FORWARD’ was not declared in this scope
‘PlainFFT’ has not been declared
The main FFT code is
#include "Arduino.h"
#include "PlainFFT.h"
PlainFFT FFT = PlainFFT(); // Create FFT object
// These values can be changed in order to evaluate the functions
const uint16_t samples = 64;
double signalFrequency = 1000;
double samplingFrequency = 5000;
uint8_t signalIntensity = 100;
// These are input and output vectors
double vReal[samples];
double vImag[samples];
uint8_t runOnce = 0x00;
#define SCL_INDEX 0x00
#define SCL_TIME 0x01
#define SCL_FREQUENCY 0x02
void setup(){
Serial.begin(115200);
Serial.println("Ready");
}
void loop() {
if (runOnce == 0x00) {
runOnce = 0x01;
// Build raw data
double cycles = (((samples-1) * signalFrequency) / samplingFrequency);
for (uint8_t i = 0; i < samples; i++) {
vReal[i] = uint8_t((signalIntensity * (sin((i * (6.2831 * cycles)) / samples) + 1.0)) / 2.0);
}
printVector(vReal, samples, SCL_TIME);
FFT.windowing(vReal, samples, FFT_WIN_TYP_HAMMING, FFT_FORWARD); // Weigh data
printVector(vReal, samples, SCL_TIME);
FFT.compute(vReal, vImag, samples, FFT_FORWARD); // Compute FFT
printVector(vReal, samples, SCL_INDEX);
printVector(vImag, samples, SCL_INDEX);
FFT.complexToMagnitude(vReal, vImag, samples); // Compute magnitudes
printVector(vReal, (samples >> 1), SCL_FREQUENCY);
double x = FFT.majorPeak(vReal, samples, samplingFrequency);
Serial.println(x, 6);
}
}
void printVector(double *vD, uint8_t n, uint8_t scaleType) {
double timeInterval = (1.0 / samplingFrequency);
for (uint16_t i = 0; i < n; i++) {
// Print abscissa value
switch (scaleType) {
case SCL_INDEX:
Serial.print(i, DEC);
break;
case SCL_TIME:
Serial.print((i * timeInterval), 6);
break;
case SCL_FREQUENCY:
Serial.print((i / (timeInterval * (samples-1))), 6);
break;
}
Serial.print(" ");
// Print ordinate value
Serial.print(vD[i], 6);
Serial.println();
}
Serial.println();
}
The header file named as “PlainFFT.h”
// Custom constants
#define FORWARD 0x01
#define REVERSE 0x00
// Windowing type
#define WIN_TYP_RECTANGLE 0x00// rectangle (Box car)
#define WIN_TYP_HAMMING 0x01// hamming
#define WIN_TYP_HANN 0x02// hann
#define WIN_TYP_TRIANGLE 0x03// triangle (Bartlett)
#define WIN_TYP_BLACKMAN 0x04// blackmann
#define WIN_TYP_FLT_TOP 0x05// flat top
#define WIN_TYP_WELCH 0x06// welch
const uint8_t samples = 64; // data stored variable vectors
double vReal[samples];
double vImag[samples];
void PlainFFT::windowing(double *vData, uint8_t samples, uint8_t windowType, uint8_t dir) {
// The weighing function is symetric; half the weighs are recorded
double samplesMinusOne = (double(samples) - 1.0);
for (uint8_t i = 0; i < (samples >> 1); i++) {
double indexMinusOne = double(i);
double ratio = (indexMinusOne / samplesMinusOne);
double weighingFactor = 1.0;
// compute and record weighting factor
switch (windowType) {
case WIN_TYP_RECTANGLE: // rectangle (box car)
weighingFactor = 1.0;
break;
case WIN_TYP_HAMMING: // hamming
weighingFactor = 0.54 - (0.46 * cos(2.0 * pi * ratio));
break;
case WIN_TYP_HANN: // hann
weighingFactor = 0.54 * (1.0 - cos(2.0 * pi * ratio));
break;
case WIN_TYP_TRIANGLE: // triangle (Bartlett)
weighingFactor = 1.0 - ((2.0 * abs(indexMinusOne - (samplesMinusOne / 2.0))) / samplesMinusOne);
break;
case WIN_TYP_BLACKMAN: // blackmann
weighingFactor = 0.42323 - (0.49755 * (cos(2.0 * pi * ratio))) + (0.07922 * (cos(4.0 * pi * ratio)));
break;
case WIN_TYP_FLT_TOP: // flat top
weighingFactor = 0.2810639 - (0.5208972 * cos(2.0 * pi * ratio)) + (0.1980399 * cos(4.0 * pi * ratio));
break;
case WIN_TYP_WELCH: // welch
weighingFactor = 1.0 - sq((indexMinusOne - samplesMinusOne / 2.0) / (samplesMinusOne / 2.0));
break;
}
if (dir == FORWARD) {
vData[i] *= weighingFactor;
vData[samples - (i + 1)] *= weighingFactor;
}
else {
vData[i] /= weighingFactor;
vData[samples - (i + 1)] /= weighingFactor;
}
}
}