/* This example shows the most basic usage of the Adafruit ZeroFFT library.
* it calculates the FFT and prints out the results along with their corresponding frequency
*
* The signal.h file constains a 200hz sine wave mixed with a weaker 800hz sine wave.
* The signal was generated at a sample rate of 8000hz.
*
* Note that you can print only the value (coment out the other two print statements) and use
* the serial plotter tool to see a graph.
*/#include"Adafruit_ZeroFFT.h"#include"signal.h"//the signal in signal.h has 2048 samples. Set this to a value between 16 and 2048 inclusive.//this must be a power of 2// #define DATA_SIZE 1024#define DATA_SIZE 1024 // This is compatible with Arduino serial plotter where x axis ring buffer cant be changed from 500.// To make the actual plot, data size is reduced to 1000 and then divided by 2.// the sample rate:#define FS 39700 // Limited by speed of analogReadint16_t data[DATA_SIZE];
int16_t bigData[DATA_SIZE];
// the setup routine runs once when you press reset:voidsetup(){
Serial.begin(115200);
while(!Serial); //wait for serial to be ready/* // run the FFT
ZeroFFT(signal, DATA_SIZE);
// data is only meaningful up to sample rate/2, discard the other half
for(int i=0; i<DATA_SIZE/2; i++)
{
//print the frequency
//Serial.print(FFT_BIN(i, FS, DATA_SIZE));
//Serial.print(" Hz: ");
//print the corresponding FFT output
//Serial.println(signal[i]);
}
*/
}
voidloop(){
for(int i=0; i<DATA_SIZE; i++)
{
bigData[i] = 0;
}
int32_t avg = 0;
unsignedlong beforeMicros = micros();
int k = 50;
for(int j=0; j<k; j++)
{
for(int i=0; i<DATA_SIZE; i++)
{
int16_t val = analogRead(A2);
// delayMicroseconds(50);// delayMicroseconds(10); // ( 1u = 1MHz, 10u = 100 KHz, 100u = 10KHz)
avg += val;
data[i] = val;
}
unsignedlong afterMicros = micros();
float totalMicros = afterMicros - beforeMicros;
//remove DC offset and gain up to 16 bits
avg = avg/DATA_SIZE;
for(int i=0; i<DATA_SIZE; i++) data[i] = (data[i] - avg) * 64;
//run the FFT
ZeroFFT(data, DATA_SIZE);
for(int i=0; i<DATA_SIZE; i++)
{
bigData[i] = data[i] + bigData[i];
}
}
int dataMax = 0;
int dataMaxIndex = 600;
for(int i=0; i<DATA_SIZE; i++)
{
data[i] = bigData[i]/k;
// Find whichvalue of i gives the fundamental frequency:if(data[i] > dataMax)
{
dataMax = data[i];
dataMaxIndex = i;
}
}
int fundamental_center = dataMaxIndex;
int fundamental_1 = fundamental_center - 4;
int fundamental_2 = fundamental_center - 3;
int fundamental_3 = fundamental_center - 2;
int fundamental_4 = fundamental_center - 1;
int fundamental_5 = fundamental_center + 0;
int fundamental_6 = fundamental_center + 1;
int fundamental_7 = fundamental_center + 2;
int fundamental_8 = fundamental_center + 3;
int fundamental_9 = fundamental_center + 4;
//data is only meaningful up to sample rate/2, discard the other halffor(int i=0; i<(DATA_SIZE-24)/2; i++) // The '-24' is to try get the data to fit in Arduino serial plot window.
{
// Try and remove the fundamental frequency from the plot:if((i==fundamental_1)||(i==fundamental_2)||(i==fundamental_3)||(i==fundamental_4)||(i==fundamental_5)||(i==fundamental_6)||(i==fundamental_7)||(i==fundamental_8)||(i==fundamental_9))
{
data[i] = 0;
// Serial.println(data[i]);
}
if(data[i]<0)
{
data[i]=0;
// Serial.print(" negative value detected at index: ");Serial.println(i);
}
// print the frequency// Serial.print(FFT_BIN(i, FS, DATA_SIZE));// Serial.print(" Hz: ");// print the corresponding FFT output
Serial.println(data[i]);
}
// delayMicroseconds(1000);// Serial.print(" Total micro seconds: ");Serial.println(totalMicros);// Serial.print(" Data size: ");Serial.println(DATA_SIZE);// Serial.print(" Time per analogRead: ");Serial.print(totalMicros/DATA_SIZE);Serial.println(" micro seconds");// Serial.print(" analogRead frequency: ");Serial.print((1/((totalMicros/DATA_SIZE)/1000000))/1000);Serial.print(" KHz");// Serial.print(" dataMaxIndex value: ");Serial.println(dataMaxIndex);// delay(1000);
}
People might notice a rather clumsily coded high pass filter which takes out some of the frequency bands around the fundamental frequency. Needs to be improved with something a bit more elegant, I think.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.