cmatrixstm32halcmsis

Assignment of 1d array into 2d matrix for range and speed information in FMCW radar


I am using fmcw radar for finding distance and speed information of moving object using stm32l476 micro controller.

First, in order to get range of stationery object, I store the ADC value into "fft_in" array by using "HAL_ADC_ConvCpltCallback" function. Here I have intialized "is_data_ready_for_fft = 1"as follows:

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc1) {
        is_data_ready_for_fft = 1;
        }

and calculate the range using fft. Now I need this 1d array of ADC values to be stored in a 2d array as to calculate doppler frequency across chirp index.

below is the code which copies adc values into fft_in array and range calculation:

    while (1)
      {
          if (is_data_ready_for_fft == 1) {
                            for (size_t i = 0; i < ADC_BUF_LENGTH; i++) {
                                fft_in[i] = (float32_t) adcResultsDMA[i];
                            }
                     is_data_ready_for_fft = 0;

                     arm_rfft_fast_f32(&fft_handler, fft_in, fft_out, 0);

                    arm_cmplx_mag_f32(fft_out, fft_out2, ADC_BUF_LENGTH);
                    

                    fft_out2[0] = 0;
                

                    arm_max_f32(fft_out2, ADC_BUF_LENGTH/2, &Result, &Index);

                

                    R = (300000000 * 0.004064* Index)/500000000;

                         }
                      }

The above code copies the value into fft_in array. Here ADC_BUF_LENGTH = 512; Now my question is how can I add this fft_in buffer into a matrix as shown below: given that fft_in array changes every second: So here fft_in(0), fft_in(1), fft_in(2),......fft_in(20) are the fft_in arrays having ADC_values at that particular time.

[0,0]=fft_in(0)[0]   [0,1]=fft_in(0)[1]..............[0,512]=fft_in(0)[512]
[1,0]=fft_in(1)[0]   [1,1]=fft_in(1)[1]..............[1,512]=fft_in(1)[512]
[2,0]=fft_in(2)[0]   [2,1]=fft_in(2)[1]..............[2,512]=fft_in(2)[512]
.
.
.
.
[19,0]=fft_in(19)[0]  [19,1]=fft_in(19)[1].............[19,512]=fft_in(19)[512]

(Chirp index I have taken as 20 and number of samples as 512. So fft across rows yields range and fft across colums yields velocity)


Solution

  • I think you are looking for a tow dimensional array. You can declare one like this float32_t fftIn2D[NBR_CHIRPS_PER_FRAME][NBR_SAMPLES_PER_CHIRP];. The NBR_SAMPLES_PER_CHIRP are the columns where you put the values sampled during one chirp (512 samples in your case). The NBR_CHIRPS_PER_FRAME are the rows which are the number of chirps in one frame, in your case that would be 20.

    To access an element of the array, you need two nested for-loops. Here is a code-snippet for this purpose.

    for (uint32_t chirpIdx = 0; chirpIdx < NBR_CHIRPS_PER_FRAME; chirpIdx++)
    {
        for (uint32_t sampleIdx = 0; sampleIdx < NBR_SAMPLES_PER_CHIRP; sampleIdx++)
        {
            /*acess the element*/
            fftIn2D[chirpIdx][sampleIdx] = (float32_t) adcResultsDMA[i]
        }
    }
    

    For your Code, this could lock like this:

    float32_t fftIn2D[NBR_CHIRPS_PER_FRAME][NBR_SAMPLES_PER_CHIRP];
    fftInDoppler[NBR_CHIRPS_PER_FRAME];
    uint32_t chirpIdxGlobal = 0;
    
    
    while (1)
    {
        if (is_data_ready_for_fft == 1) {
             is_data_ready_for_fft = 0;
            
            for (uint32_t sampleIdx = 0; sampleIdx < NBR_SAMPLES_PER_CHIRP; sampleIdx++)
            {
                fftIn2D[chirpIdxGlobal][sampleIdx] = (float32_t) adcResultsDMA[i];
            }
            
            chirpIdxGlobal++;
            if(chirpIdxGlobal == (NBR_CHIRPS_PER_FRAME - 1)){
                is_data_ready_for_doppler_fft = 1;
            }
            
            arm_rfft_fast_f32(&fft_handler, &fftIn2D[sampleIdx][0], fft_out, 0);
            
            arm_cmplx_mag_f32(fft_out, fft_out2, ADC_BUF_LENGTH);
            
            fft_out2[0] = 0;
            
            arm_max_f32(fft_out2, ADC_BUF_LENGTH/2, &Result, &Index);
            
            R = (300000000 * 0.004064* Index)/500000000;
            
        }
        
        if (is_data_ready_for_doppler_fft){
            chirpIdxGlobal = 0;
            is_data_ready_for_doppler_fft = 0;
            
            for (uint32_t sampleIdx = 0; sampleIdx < NBR_SAMPLES_PER_CHIRP; sampleIdx++)
            {
                /* bring the data in the right order for the fft */
                for (uint32_t chirpIdx = 0; chirpIdx < NBR_CHIRPS_PER_FRAME; chirpIdx++)
                {
                    fftInDoppler[chirpIdx] = fftIn2D[chirpIdx][sampleIdx];
                }
                
                arm_rfft_fast_f32(&fft_handler, &fftInDoppler[0], fft_out_doppler, 0);
                
                arm_cmplx_mag_f32(fft_out_doppler, fft_out2_doppler, ADC_BUF_LENGTH);
            
                fft_out2_doppler[0] = 0;
            
                arm_max_f32(fft_out2_doppler, ADC_BUF_LENGTH/2, &Result, &Index);
            }
            
        }
    }
    

    Here a notes to my snippet, you can also calculate the second FFT on the samples where a target was detected in the range FFT (first FFT) and not over every sample.

    Keep in mind a fft takes some calculation time, maybe you need to sample all data for one frame before you calculate them.