2014-07-20 01:08:55 +00:00
/*
2021-12-09 11:42:40 +00:00
Example of use of the FFT library
2014-07-20 03:43:58 +00:00
Copyright ( C ) 2014 Enrique Condes
2014-07-20 01:08:55 +00:00
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2016-12-30 22:35:36 +00:00
2014-07-20 01:08:55 +00:00
*/
2017-04-25 19:16:27 +00:00
/*
In this example , the Arduino simulates the sampling of a sinusoidal 1000 Hz
signal with an amplitude of 100 , sampled at 5000 Hz . Samples are stored
inside the vReal array . The samples are windowed according to Hamming
function . The FFT is computed using the windowed samples . Then the magnitudes
of each of the frequencies that compose the signal are calculated . Finally ,
the frequency with the highest peak is obtained , being that the main frequency
present in the signal .
*/
2014-07-20 03:43:58 +00:00
# include "arduinoFFT.h"
2014-07-20 01:08:55 +00:00
2014-07-20 03:43:58 +00:00
arduinoFFT FFT = arduinoFFT ( ) ; /* Create FFT object */
2016-12-30 22:35:36 +00:00
/*
These values can be changed in order to evaluate the functions
2014-07-20 01:08:55 +00:00
*/
2014-07-20 03:43:58 +00:00
const uint16_t samples = 64 ; //This value MUST ALWAYS be a power of 2
2017-08-03 18:41:57 +00:00
const double signalFrequency = 1000 ;
const double samplingFrequency = 5000 ;
const uint8_t amplitude = 100 ;
2016-12-30 22:35:36 +00:00
/*
These are the input and output vectors
2014-07-20 01:08:55 +00:00
Input vectors receive computed results from FFT
*/
2016-12-30 22:35:36 +00:00
double vReal [ samples ] ;
2014-07-20 01:08:55 +00:00
double vImag [ samples ] ;
2018-02-10 19:21:10 +00:00
# define SCL_INDEX 0x00
# define SCL_TIME 0x01
# define SCL_FREQUENCY 0x02
# define SCL_PLOT 0x03
2014-07-20 03:43:58 +00:00
void setup ( )
{
Serial . begin ( 115200 ) ;
2020-10-06 19:47:01 +00:00
while ( ! Serial ) ;
2014-07-20 03:43:58 +00:00
Serial . println ( " Ready " ) ;
2014-07-20 01:08:55 +00:00
}
2016-12-30 22:35:36 +00:00
void loop ( )
2014-07-20 01:08:55 +00:00
{
2014-07-20 03:43:58 +00:00
/* Build raw data */
double cycles = ( ( ( samples - 1 ) * signalFrequency ) / samplingFrequency ) ; //Number of signal cycles that the sampling will read
2017-04-25 17:34:46 +00:00
for ( uint16_t i = 0 ; i < samples ; i + + )
2014-07-20 03:43:58 +00:00
{
2017-04-25 18:02:49 +00:00
vReal [ i ] = int8_t ( ( amplitude * ( sin ( ( i * ( twoPi * cycles ) ) / samples ) ) ) / 2.0 ) ; /* Build data with positive and negative values*/
//vReal[i] = uint8_t((amplitude * (sin((i * (twoPi * cycles)) / samples) + 1.0)) / 2.0);/* Build data displaced on the Y axis to include only positive values*/
2017-08-28 18:48:02 +00:00
vImag [ i ] = 0.0 ; //Imaginary part must be zeroed in case of looping to avoid wrong calculations and overflows
2014-07-20 03:43:58 +00:00
}
2017-05-11 18:21:42 +00:00
/* Print the results of the simulated sampling according to time */
2014-07-20 03:43:58 +00:00
Serial . println ( " Data: " ) ;
2018-02-10 19:21:10 +00:00
PrintVector ( vReal , samples , SCL_TIME ) ;
2014-07-20 03:43:58 +00:00
FFT . Windowing ( vReal , samples , FFT_WIN_TYP_HAMMING , FFT_FORWARD ) ; /* Weigh data */
Serial . println ( " Weighed data: " ) ;
2018-02-10 19:21:10 +00:00
PrintVector ( vReal , samples , SCL_TIME ) ;
2014-07-20 03:43:58 +00:00
FFT . Compute ( vReal , vImag , samples , FFT_FORWARD ) ; /* Compute FFT */
Serial . println ( " Computed Real values: " ) ;
2018-02-10 19:21:10 +00:00
PrintVector ( vReal , samples , SCL_INDEX ) ;
2014-07-20 03:43:58 +00:00
Serial . println ( " Computed Imaginary values: " ) ;
2018-02-10 19:21:10 +00:00
PrintVector ( vImag , samples , SCL_INDEX ) ;
2014-07-20 03:43:58 +00:00
FFT . ComplexToMagnitude ( vReal , vImag , samples ) ; /* Compute magnitudes */
2014-07-20 05:09:27 +00:00
Serial . println ( " Computed magnitudes: " ) ;
2018-02-10 19:21:10 +00:00
PrintVector ( vReal , ( samples > > 1 ) , SCL_FREQUENCY ) ;
2014-07-20 03:43:58 +00:00
double x = FFT . MajorPeak ( vReal , samples , samplingFrequency ) ;
Serial . println ( x , 6 ) ;
while ( 1 ) ; /* Run Once */
// delay(2000); /* Repeat after delay */
2014-07-20 01:08:55 +00:00
}
2018-02-10 19:21:10 +00:00
void PrintVector ( double * vData , uint16_t bufferSize , uint8_t scaleType )
{
for ( uint16_t i = 0 ; i < bufferSize ; i + + )
{
double abscissa ;
/* Print abscissa value */
switch ( scaleType )
{
case SCL_INDEX :
abscissa = ( i * 1.0 ) ;
break ;
case SCL_TIME :
abscissa = ( ( i * 1.0 ) / samplingFrequency ) ;
break ;
case SCL_FREQUENCY :
abscissa = ( ( i * 1.0 * samplingFrequency ) / samples ) ;
break ;
}
Serial . print ( abscissa , 6 ) ;
if ( scaleType = = SCL_FREQUENCY )
2018-02-10 19:59:45 +00:00
Serial . print ( " Hz " ) ;
Serial . print ( " " ) ;
2018-02-10 19:21:10 +00:00
Serial . println ( vData [ i ] , 4 ) ;
}
Serial . println ( ) ;
}