0

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!

Henrik-Wo
  • 1
  • 2
  • 3
    There is no question in your question. You have not stated what output is observed or what output is expected instead. What does “returns no frequency” mean? Edit the code to provide a [mre]: Mock up some data that demonstrates the problem and build that into the program, removing all the device-specific stuff, so anybody can compile and run the program with just the FFT code to reproduce the problem. – Eric Postpischil Nov 11 '21 at 15:59
  • 1
    Try plotting the time-domain signal to make sure you are at least starting with meaningful input data to the FFT. – Paul R Nov 11 '21 at 16:10
  • I added some more Informations. Sorry, is some software/hardware problem. The FFT only in the software wouldn't be a problem but is sadly no option... – Henrik-Wo Nov 11 '21 at 17:30

0 Answers0