This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

12 bit from ADC to Q15 for a FFT

I have a project on a STM32F103 using the ADC.

I'm trying to make simple VU meter. I made a litle circuit (a resistor divisor and a decoupling capacitor) to put the audio signal into de uC. Becouse of the resistor I get 2048 counts for no audio input.

So, when I put audio to the systems I get my ADC sampling it around 2048. Now I want to convert 16 bits unsigned (but centered at 2048) to Q15 to use CMSIS FFT_Q15

Is there any CMSIS function to do that? Is there a simple way to do that?

Thank!

Parents
  • This is part of my code:

     

    	for(i=0;i<128;i+=2)
    	{
    		FFT_ADCvalues[i]=(q15_t)((int16_t)(DMA_ADCvalues[i/2]-2048)<<3);
    		FFT_ADCvalues[i+1]=(q15_t)0;
    	}
    	arm_cfft_q15(&arm_cfft_sR_q15_len64, FFT_ADCvalues, 0, 1);
    	arm_cmplx_mag_q15(FFT_ADCvalues, MAG_of_fft, 64);

    As I have 12 bits binary offset stored in an unsigned int16_t I'm trying to convert to q15 but it seems that don't work ok, becouse the result of arm_cmplx_mag_q15 is 255,0,0,0,0,0,0,.....

     

    So, what am I doing wrong?

Reply
  • This is part of my code:

     

    	for(i=0;i<128;i+=2)
    	{
    		FFT_ADCvalues[i]=(q15_t)((int16_t)(DMA_ADCvalues[i/2]-2048)<<3);
    		FFT_ADCvalues[i+1]=(q15_t)0;
    	}
    	arm_cfft_q15(&arm_cfft_sR_q15_len64, FFT_ADCvalues, 0, 1);
    	arm_cmplx_mag_q15(FFT_ADCvalues, MAG_of_fft, 64);

    As I have 12 bits binary offset stored in an unsigned int16_t I'm trying to convert to q15 but it seems that don't work ok, becouse the result of arm_cmplx_mag_q15 is 255,0,0,0,0,0,0,.....

     

    So, what am I doing wrong?

Children
  • I made this code test:

    	float fltSinWave[64];
    	q15_t q15SinWave[64];
    	q15_t q15FFT[128];
    	q15_t q15MAG[64];
    	uint32_t F=1562;
    	uint32_t Fs = 10000;
    	uint8_t i;
    	for(i=0;i<64;i++)
    	{
    		// Seno discreto FLOTANTE
    		fltSinWave[i] = (sin(2*M_PI*i*F/Fs));
    		// Seno discreto en Q15
    		q15SinWave[i] = (q15_t)(fltSinWave[i] * (1<<15));
    	}
    	// Preparo el array de la FFT
    	for(i=0;i<128;i+=2)
    	{
    		q15FFT[i] = q15SinWave[i/2];
    		q15FFT[i+1] = 0;
    	}
    	// Calculo la FFT
    	arm_cfft_q15(&arm_cfft_sR_q15_len64, q15FFT, 0, 1);
    	// Calculo la magnitud de cada punto
    	arm_cmplx_mag_q15(q15FFT, q15MAG, 64);

    This way the fft and mag is working ok. Except for the mag output. I get 8191 in the bin number 10. 8191 is 0001 1111 1111 1111 in q2.14 format (arm_cmplx_mag_q15 change 1.15 to 2.14). So left shiting 1 bit I get 0011 1111 1111 1110 that is almost 0.5. But I should get 1. So there is another scale factor...

    Idea?

  • Hi,

    This is a common characteristic of complex FFT on real signals, just have a look at the bin number (64 - 10), you should have the same magnitude.

    Real signals have a symmetric spectrum at output of Complex FFT, you can try to search or read this.