Arm_rfft Pi Pico need help debugging

Hi & thanks in advance for your patience. I am trying to get arm_rfft running on a Pi Pico. My basic problem is that I have a working sketch, but when I paste the code into my larger application - it fails. First observation is that this FFT is wicked fast, outputting results in 800 uS for a 512 sample size at 500,000 samples/sec (1mS of real time). Which means that the FFT is faster than the Pico can acquire data, potentially opens the opportunity to process ultrasonic (20kHz-100kHz) in real time. I am limited to troubleshooting using Serial.print statements. Also limited coding abilities.

Below is a comparison of the results of the two sketches, the first one shows proper operation, the second illustrates the characteristics of the failure:

Index Bin pResult Freq Mag Time
0 51 7935 49806.6 7935.0 1024 (all remaining are identical)

Index Bin pResult Freq Mag Time
0 0 4678 0.0 4678.0 148
1 0 1974 0.0 1974.0 144
2 0 8247 0.0 8247.0 143
3 0 12939 0.0 12939.0 147
4 0 15130 0.0 15130.0 147
5 0 14412 0.0 14412.0 143
6 0 10918 0.0 10918.0 158
7 0 5323 0.0 5323.0 146
8 0 1292 0.0 1292.0 143
9 0 7663 0.0 7663.0 150
10 0 12556 0.0 12556.0 146
11 0 15032 0.0 15032.0 143
12 0 14611 0.0 14611.0 149
13 0 11371 0.0 11371.0 147
14 0 5943 0.0 5943.0 142
15 0 627 0.0 627.0 158
Max Mag 627

I see hints; first, all bin number are zero, which seems to hint that only noise is being detected, second, the time is much quicker indicating that the input data array includes a lot of “0” data. I have printed the input buffer before arm_rfft is executed and the data in both sketches is identical. Lastly; not all bins are identical, which indicates to me that there is data in the input buffer, just invalid data.

My theory is that something is stomping on the input buffer - but how can I isolate the culprit?

Working sketch appears below.

Preferences:https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json

Compiler:”“Standard” and “Fast” (20% faster)

Board: Pi Pico 2040, Pico 2 fails to execute in both cases

Code size working sketch: Sketch uses 139684 bytes (6%) of program storage space. Maximum is 2093056 bytes.
Global variables use 29712 bytes (11%) of dynamic memory, leaving 232432 bytes for local variables. Maximum is 262144 bytes.

Code size failed sketch: Sketch uses 81672 bytes (3%) of program storage space. Maximum is 2093056 bytes.
Global variables use 46912 bytes (17%) of dynamic memory, leaving 215232 bytes for local variables. Maximum is 262144 bytes.

Working sketch:


#include <arm_math.h>                     // Include the CMSIS-DSP library header

int16_t  adcBuffer[8192];     // adc data
uint32_t  fftStartTime;
uint32_t  fftCalcTime;

arm_rfft_instance_q15 rfft;// RFFT instance

void setup() {
  Serial.begin(115200);                 // arduino ide
  delay(3000);
  arm_status status = arm_rfft_init_q15(&rfft, 512, 0, 1);// 0=fft,1=no bit rev
}

void loop() {
  for(int i=0; i<8192;i++) adcBuffer[i] = 2000*sin(float(i)*50/80.) + 2048; // 50kHz
  generateSpectrogram();
  delay(5000);
}

q15_t fftInput[512];          // q15, 1.15 format, convert <<4  q15 result
q15_t fftOutput[1024];     // q15, 9.7 format,  convert >>17 int16 result
q15_t fftPower[256];   // Buffer for magnitude results
int16_t maxMag;                           // spectrogram->max mag among all slices
float   fftSliceFreq[16];     // 
float   fftSliceMag[16];      // 
char TAB = 9;
// ---------------------------- fft ----------------------------------------------
void generateFFT(int slicePtr) {
  maxMag = 0;
  q15_t    pResult;                  // signal magnitude, does not matter if q15 or no "<<4"
  uint32_t pIndex;                   // bin number, doc says "q15_t*" but behaves like uint32_t
  float   peakFreq;
  
  fftStartTime = micros();           // 512 samples
  for (int i=0; i<512; i++) {
    fftInput[i]=((adcBuffer[i+slicePtr*512]-2048)<<4); // xform->q15, remove dc
  }
  
  arm_rfft_q15(&rfft, fftInput, fftOutput);
  arm_cmplx_mag_q15(fftOutput, fftPower, 256);  // output is real/imaginary pairs), calculate magnitude
  arm_max_q15(fftPower, 256, &pResult, &pIndex);  // Find the peak magnitude and its index (bin number)

  fftSliceFreq[slicePtr] = float(pIndex*976.6);  // save peak freq for this slice
  fftSliceMag[slicePtr]  = float(pResult);  // save peak signal magnitude
  if(pResult>maxMag) maxMag = pResult;
    
  fftCalcTime = micros() - fftStartTime;
  Serial.print(slicePtr);                 // index
  Serial.print(TAB);
  Serial.print(pIndex);                   // bin
  Serial.print(TAB);
  Serial.print(pResult);                  // mag
  Serial.print(TAB);
  Serial.print(fftSliceFreq[slicePtr],1); // freq
  Serial.print(TAB);
  Serial.print(fftSliceMag[slicePtr],1);    // mag
  Serial.print(TAB);
  Serial.print(fftCalcTime);              // time
  Serial.println();
}

// ------------------------ Spectrogram ---------------------------------------
// slice adc buffer into 1ms/slice, fft each slice, output to array
void generateSpectrogram() {
  Serial.println("Index   Bin     pResult Freq    Mag     Time");
  for(int slicePtr=0; slicePtr<16; slicePtr++) {   // perform fft on 512 samples window (1 mS) 16 times
    generateFFT(slicePtr);   // 512 slice * 16 slices = 8192 whole buffer 
  }
  Serial.print("Max Mag ");
  Serial.println(maxMag);
}

Just a quick question. You want help debugging a sketch you haven't shown?

And yet your working sketch is larger than what you say is "my larger application", which you say fails.

Interesting.

I misspoke - working code is smaller than failed code