I'm working with a dsPIC33EP128GP502 and try to run a FFT to measure the dominant frequency on the input. The compiler shows no errors and the ADC itself seems to work... (for single values)
I expect as result some frequency value between 0 Hz and ~96 kHz in the variable peakFrequency
. With a noise signal (or no signal at all) the value should be more or less random. With an external applied single tone signal I expect to measure the input frequency +/- ~100 Hz. Sadly, my frequency output is always 0.
The test signals are generated by external signal generators and the ADC works fine if I want to measure single values!
The FFT has to run on the DSP-core of the dsPIC33E due to some performance needs.
Has anyone any experience with the dsPIC33E and an idea were my mistake is?
ADC: TAD -> 629.3 ns, Conversion Trigger -> Clearing sample bit ends sampling and starts conversion, Output Format -> Fractional result, signed, Auto Sampling -> enabled
#include "mcc_generated_files/mcc.h"
#include <xc.h>
#include <dsp.h>
#define FFT_BLOCK_LENGTH 1024
#define LOG2_BLOCK_LENGTH 10
#define AUDIO_FS 192042
int16_t peakFrequencyBin;
uint16_t ix_MicADCbuff;
uint16_t peakFrequency;
fractional fftMaxValue;
fractcomplex twiddleFactors[FFT_BLOCK_LENGTH/2] __attribute__ ((space(xmemory)));
fractcomplex sigCmpx[FFT_BLOCK_LENGTH] __attribute__ ((space(ymemory), aligned(FFT_BLOCK_LENGTH * 2 *2)));
bool timeGetAdcSample = false;
void My_ADC_IRS(void)
{
timeGetAdcSample = true;
}
void readOutput(void)//Sample output
{
for(ix_MicADCbuff=0;ix_MicADCbuff<FFT_BLOCK_LENGTH;ix_MicADCbuff++)
{
ADC1_ChannelSelect(mix_output);
ADC1_SoftwareTriggerEnable();
while(!timeGetAdcSample); //wait for TMR1 interrupt (5.2072 us)
timeGetAdcSample = false;
ADC1_SoftwareTriggerDisable();
while(!ADC1_IsConversionComplete(mix_output));
sigCmpx[ix_MicADCbuff].real = ADC1_Channel0ConversionResultGet();
sigCmpx[ix_MicADCbuff].imag = 0;
}
}
void signalFreq(void)//Detect the dominant frequency
{
readOutput();
FFTComplexIP(LOG2_BLOCK_LENGTH, &sigCmpx[0], &twiddleFactors[0], COEFFS_IN_DATA);/
BitReverseComplex(LOG2_BLOCK_LENGTH, &sigCmpx[0]);
SquareMagnitudeCplx(FFT_BLOCK_LENGTH, &sigCmpx[0], &sigCmpx[0].real);
VectorMax(FFT_BLOCK_LENGTH/2, &sigCmpx[0].real, &peakFrequencyBin);
peakFrequency = peakFrequencyBin*(AUDIO_FS/FFT_BLOCK_LENGTH);
}
int main(void)
{
SYSTEM_Initialize();
TwidFactorInit(LOG2_BLOCK_LENGTH, &twiddleFactors[0], 0);
TMR1_SetInterruptHandler(My_ADC_IRS);
TMR1_Start();
while (1)
{
signalFreq();
UART1_32_Write((uint32_T)peakFrequency); // output via UART
}
return 1;
}
Perhaps anyone can figure out the error/problem in my code!