Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 5 of 5

Thread: Teensy 4.0 ADC FFT - Current State

  1. #1

    Teensy 4.0 ADC FFT - Current State

    Hello! I have been working through a number of microphones to get FFT working from the Teensy 4.0. All of the code worked great with the i2s microphone, but then I found out it spoiled the timing for writing to WS2813 LEDs. Then I decided to make the modification to an Adafruit MAX4466 microphone to use it for FFT. However, according to this thread (comment 15) Paul Stoffregen replied:

    "This will work without the audio shield present, but I2S output (or any other I/O object that causes the library to update) is currently required. Future versions will remove this requirement."
    So the ADC need some type of external timing regulation. However, when I fire up a basic FFT program I get the following results.

    1. analogRead(A7): .6V biased signal that responds to audio
    2. ADC -> FFT without i2s: no data.
    3. ADC -> FFT with i2s: data that does not respond to sound Click image for larger version. 

Name:	unchanging.jpg 
Views:	122 
Size:	80.1 KB 
ID:	21374

    So in this case, the i2s makes the FFT return data, just not useful data. As I mentioned earlier, i2s breaks the LEDs anyway, so another "I/O object that causes the library to update" would be preferable.

    The sketch I have been using is this: analog_erad.ino.

    I would really appreciate hearing what may be done to get ADC -> FFT working on the 4.0. Thanks a lot for any help you are able to provide on this one.

    edit: Looks like having "AudioInputI2S i2s1; " in the sketch garbles the analogread() output. Goes from solid .6V to a random low value.
    Last edited by MSO; 08-14-2020 at 03:39 AM.

  2. #2
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,862
    Quote Originally Posted by MSO View Post
    1. analogRead(A7): .6V biased signal that responds to audio
    2. ADC -> FFT without i2s: no data.
    3. ADC -> FFT with i2s: data that does not respond to sound Click image for larger version. 

Name:	unchanging.jpg 
Views:	122 
Size:	80.1 KB 
ID:	21374
    You failed to call init(A7) on the adc object, so its defaulting to A2.

    Using code tags to post code is the way to go, make it easy for people...

  3. #3
    Thanks for taking a look I'll add the code with tags. I tried every pin for the ADC using adc1(A0-A7), I just moved it to A2 to more easily test different audio library configs.

  4. #4
    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioInputAnalog         adc1(A6);           //xy=263.00000762939453,49.00000476837158
    //AudioSynthWaveformSine   sine1;          //xy=294,142.00000476837158
    AudioMixer4              mixer1;         //xy=458.7826232910156,58
    AudioAnalyzeFFT1024      fft1024;      //xy=554,124
    AudioConnection          patchCord1(adc1, 0, mixer1, 0);
    //AudioConnection          patchCord2(sine1, 0, mixer1, 1);
    AudioConnection          patchCord3(mixer1, fft1024);
    // GUItool: end automatically generated code
    
    const int EQbins = 14;
    float EQbuff[EQbins];
    
    void setup() {
      AudioMemory(24);
      Serial.begin(115200);
      //mixer1.gain(0, 1);
      //mixer1.gain(1, 0);
      //mixer1.gain(2, 1);
      sine1.amplitude(1);
      sine1.frequency(330);
      //sine1.Set the frequency, from 0 to 22000. Very low values may be used to create a LFO (Low Frequency Oscillator) for objects with modulation signal inputs.
      sine1.phase(0);
    }
    
    void loop() {
      //delay(1);
      //readfft();
      logread();
      //finefft();
      
    }
    
    void logread(){
      Serial.print(0);  // To freeze the lower limit
      Serial.print(" ");
      Serial.print(1.2*10);  // To freeze the upper limit
      Serial.print(" ");
      float printle = analogRead(A6)*3.3/1024*10;
      Serial.println(printle);
    }
    
    void readfft(){
      if (fft1024.available()) {
        Serial.println(fft1024.read(0, 1024));
      }
    }
    void finefft(){
      if (fft1024.available()) {
        EQbuff[0] =  fft1024.read(0);
        EQbuff[1] =  fft1024.read(1);
        EQbuff[2] =  fft1024.read(2, 3);
        EQbuff[3] =  fft1024.read(4, 6);
        EQbuff[4] =  fft1024.read(7, 11);
        EQbuff[5] =  fft1024.read(12, 18);
        EQbuff[6] =  fft1024.read(19, 29);
        EQbuff[7] =  fft1024.read(30, 45);
        EQbuff[8] =  fft1024.read(46, 68);
        EQbuff[9] =  fft1024.read(69, 103);
        EQbuff[10] = fft1024.read(104, 154);
        EQbuff[11] = fft1024.read(155, 131);
        EQbuff[12] = fft1024.read(132, 184);
        EQbuff[13] = fft1024.read(344, 511);
    
        for(int i = 0; i < EQbins; i++){
          Serial.print(EQbuff[i]);
          Serial.print(" ");
        }
        Serial.println(" ");
      }
    }

  5. #5
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,862
    I had another look at this, and added an AudioOutputI2S to this sketch and then it triggers updates and you can see
    signals on ADC pins. The relevant TODO in input_adc.cpp
    Code:
        // TODO: configure I2S1 to interrupt every 128 audio samples
    Is what Paul was refering to in "This will work without the audio shield present, but I2S output (or any other I/O object that causes the library to update) is currently required. Future versions will remove this requirement."

    The way the Audio lib works is that there needs to be at least one AudioStream component that can drive updates, and on the T4 currently
    the AudioInputAnalog is not one of them until this gets fixed/written.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •