# dsPIC33E ADC to FFT help

I am sampling an audio range signal with a bandwidth of 3100Hz and then applying a FFT using the DSP library example from Microchip to determine the most dominant frequency of the signal.

On the last step where I am supposed to get back the frequency with the highest energy, all I am getting are zeros.

The first step, which is sampling the analogue signal is working well as I have exported the array values into excel and plotted the graph.

The code is as follows:

void alarmFreq (void) //Detect the dominant frequency of the audio picked by the microphone
{
int i = 0;
fractional *p_real = &sigCmpx[0].real;
fractcomplex *p_cmpx = &sigCmpx[0];
{
sigCmpx[ix_MicADCbuff].imag = 0;                                        // set imaginary part with 0
}
{
*p_real++;
}*/
for ( i = 0; i < FFT_BLOCK_LENGTH; i++ )//The FFT function requires input data to be in the fractional fixed-point range [-0.5, +0.5]
{
*p_real = *p_real >>1 ;         //So, we shift all data samples by 1 bit to the right.
*p_real++;                      //Should you desire to optimize this process, perform data scaling when first obtaining the time samples or within the BitReverseComplex function source code
}
p_real = &sigCmpx[(FFT_BLOCK_LENGTH/2)-1].real; //Set up pointers to convert real array to a complex array. The input array initially has all the real input samples followed by a series of zeros
p_cmpx = &sigCmpx[FFT_BLOCK_LENGTH-1] ;
for ( i = FFT_BLOCK_LENGTH; i > 0; i-- )        //Convert the Real input sample array to a Complex input sample array
{
(*p_cmpx).real = (*p_real--);   //We will simply zero out the imaginary part of each data sample
(*p_cmpx--).imag = 0x0000;
}
FFTComplexIP (LOG2_BLOCK_LENGTH, &sigCmpx[0], (fractcomplex *) __builtin_psvoffset(&twiddleFactors[0]), (int) __builtin_psvpage(&twiddleFactors[0]));// Perform FFT operation
BitReverseComplex (LOG2_BLOCK_LENGTH, &sigCmpx[0]);// Store output samples in bit-reversed order of their addresses
SquareMagnitudeCplx(FFT_BLOCK_LENGTH, &sigCmpx[0], &sigCmpx[0].real);//Compute the square magnitude of the complex FFT output array so we have a Real output vector
VectorMax(FFT_BLOCK_LENGTH/2, &sigCmpx[0].real, &peakFrequencyBin);//Find the frequency Bin ( = index into the SigCmpx[] array) that has the largest energy
peakFrequency = peakFrequencyBin*(AUDIO_FS/FFT_BLOCK_LENGTH); //Compute the frequency (in Hz) of the largest spectral component
}


void readMic (void) //Sample microphone input
{
{
//delay_ms(1);          //FS without waiting time 66790 Hz
}
}


External variables

extern const fractcomplex twiddleFactors[FFT_BLOCK_LENGTH/2]
__attribute__ ((space(auto_psv), aligned (FFT_BLOCK_LENGTH*2)));

fractcomplex sigCmpx[FFT_BLOCK_LENGTH] __attribute__ ((section (".ydata, data, ymemory"),
aligned (FFT_BLOCK_LENGTH * 2 *2))) ={0};


UPDATE:

I am now getting a value, 16640 Hz for dominant frequency.

When I export the data generated to dsPICWorks I get this:

Seems like the function is returning the correct value but the FFT is not working properly as I should get something else right?

UPDATE 2

So I got it working! It was a data type issue. What I did was to change the ADC output data type bits from decimal to fractional and I loaded the samples directly into the array that the FFT function uses. However, I am still having strange behaviours.

The frequency bins are 66790/512 = 130Hz

Sometimes, when I pass a signal which dominant frequency is not a multiple of 130Hz, I get as a result the dominant frequency multiplied times 3. So I have added a divide by 3 instruction in case the result is too high. Luckily I only have two expected frequencies which are 520Hz and 3100 Hz so I can truncate the results, however, I would like to know what the issue is here.

• Hi! Can you upload the captured audio data of 3100 Hz bandwidth ? Also, what's the sampling rate and bit resolution of ADC? – Fat32 Oct 15 '18 at 0:10