ADC in free running on Teensy 3.6

Status
Not open for further replies.
ADC in free running on Teensy 3.6

Hello, I am trying to port a program I had on an Arduino Mega which takes samples of live music and runs FFT over them. I am hoping to replicate this functionality on the teensy exactly as it was on the Arduino, just much faster, and with more samples. Here is the program as it was on the Arduino:

Code:
    void setup() {

        ADCSRA = 0b11100110;      // set ADC to free running mode and set pre-scalar to 32 (0xe5)

        ADMUX = 0b00000000;       // use pin A0 and external voltage reference
    }


    void loop() {
       // ++ Sampling

       for(int i=0; i<SAMPLES; i++)
        {
          while(!(ADCSRA & 0x10));        // wait for ADC to complete current conversion ie ADIF bit set
          ADCSRA = 0b11110101 ;               // clear ADIF bit so that ADC can do next operation (0xf5)
          int value = ADC - 512 ;                 // Read from ADC and subtract DC offset caused value
          vReal[i]= value/4;                      // Copy to bins after compressing
          vImag[i] = 0;                         
        }
        // -- Sampling
    }


Can I use analogRead() to get the same effect? How can I port this code over to work the same way? I want to make sure it will still have ADC in free running mode, but the tutorial on this site for that didn't seem to compile for a Teensy 3.6 using Teensyduino. Thank you for any help you can give me!
 
The audio lib has some examples of FFT and analog input. Here is a slightly messy sketch that samples (44.1khz) mic input on Teensy A2 and runs fft1024 and displays FFT cells on tiny OLED (SPI or I2C version). The teensy audio lib manages ADC and FFT with double-buffered DMA @44.1KHz. The example does not require the PJRC audio adaptor board.
Code:
// Spectrum Analyzer using a Teensy 3.2 & OLED 128x32 mono
//  Test microphone is connected to A2, I2C and pin 4 or SPI
// https://forum.pjrc.com/threads/45418-FFT-analysis-using-teensy-3-2
#include <SPI.h>
#include <Wire.h>
#include <Audio.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define HT 31
#define WD 128

// define 1 for I2C  else 0 will do SPI
#define DOI2C  0

#if DOI2C
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#else
#define OLED_DC     6
#define OLED_CS     7
#define OLED_RESET  8
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
#endif

#define MIC_GAIN  2  // multiplier for the specific mic

//Set-up the audio library functions
AudioInputAnalog         adc1(A2);             //default for adc1 is A2
AudioAnalyzeFFT1024      fft1024_1;
AudioConnection          patchCord1(adc1, fft1024_1);

// An array to hold the 16 frequency bands
float level[16];

void setup() {
  Serial.begin(9600);
  //  while (!Serial);

#if DOI2C
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
#else
  display.begin(SSD1306_SWITCHCAPVCC);
#endif
  display.display();   // splash screen
  delay(2000);

#if DOI2C
  //  TWBR = 12;   // I2C @400khz  really 333khz
  I2C0_F = 0x1a;    // I2C analyzer shows 395khz
#endif

#if 0
  // benchmark
  for (int i = 0; i < 10; i++) {
    uint32_t t = micros();
    display.display();
    t = micros() - t;
    Serial.println(t);
    delay(1000);
  }
#endif


  // Audio connections require memory to work.
  AudioMemory(12);

  // Configure the window algorithm to use
  fft1024_1.windowFunction(AudioWindowHanning1024);

}


void spectrum() {
  uint32_t  t2;

  if (fft1024_1.available()) {
    // each time new FFT data is available, bin it into 16 channels, octaves
    // Note- response doesn't seem flat so each is normalized <experimenting!
    // Note- these calculations go very fast!

    level[0] =  fft1024_1.read(0) * 1.21 * MIC_GAIN;
    level[1] =  fft1024_1.read(1) * 1.18 * MIC_GAIN;
    level[2] =  fft1024_1.read(2, 3) * 1.15 * MIC_GAIN;
    level[3] =  fft1024_1.read(4, 6) * 1.12 * MIC_GAIN;
    level[4] =  fft1024_1.read(7, 10) * 1.09 * MIC_GAIN;
    level[5] =  fft1024_1.read(11, 15) * 1.06 * MIC_GAIN;
    level[6] =  fft1024_1.read(16, 22) * 1.03 * MIC_GAIN;
    level[7] =  fft1024_1.read(23, 32) * 1.00 * MIC_GAIN;
    level[8] =  fft1024_1.read(33, 46) * 0.96 * MIC_GAIN;
    level[9] =  fft1024_1.read(47, 66) * 0.93 * MIC_GAIN;
    level[10] = fft1024_1.read(67, 93) * 0.90 * MIC_GAIN;
    level[11] = fft1024_1.read(94, 131) * 0.87 * MIC_GAIN;
    level[12] = fft1024_1.read(132, 184) * 0.84 * MIC_GAIN;
    level[13] = fft1024_1.read(185, 257) * 0.81 * MIC_GAIN;
    level[14] = fft1024_1.read(258, 359) * 0.78 * MIC_GAIN;
    level[15] = fft1024_1.read(360, 511) * 0.75 * MIC_GAIN;

    //***** LCD OUTPUT
    t2 = micros();
    display.clearDisplay();

    for (int i = 0; i < 16; i++) {
      int line1 = level[i] * HT;
      if (line1 > HT) {
        line1 = HT;
      }
      display.fillRect(i * 8,  HT - line1, 6, line1 + 1, 1); // insure a base line of 1
    }
    display.display();
    t2 = micros() - t2;
#if 0
    Serial.println(t2);
#endif
  }
}

void spectrum_bins() {
  // just linear FFT data first 128 bins
  int h, i;
  uint32_t t2;

  if (fft1024_1.available()) {
    t2 = micros();
    display.clearDisplay();
    for (i = 0; i < WD; i++) {
      h = 5 * HT * fft1024_1.read(i); // need * MICGAIN ?
      // display.drawLine(i, HT - h, i, HT, WHITE);
      display.drawFastVLine(i, HT - h, h, WHITE);
    }
    display.display();
    t2 = micros() - t2;
#if 0
    Serial.println(t2);
#endif
  }
}

void print_fft() {
  float n;
  int i;

  if (fft1024_1.available()) {
    // each time new FFT data is available
    // print it all to the Arduino Serial Monitor
    int printed = 0;
    //  Serial.print("FFT: ");
    for (i = 0; i < 40; i++) {
      n = fft1024_1.read(i);
      if (n >= 0.04) {
        printed = 1;
        Serial.print(i); Serial.print(":");
        Serial.print(n);
        Serial.print(" ");
      } else {
        //Serial.print("  -  "); // don't print "0.00"
      }
    }
    if (printed)Serial.println();
  }
}

void loop() {
  // pick one
  //spectrum();  //octaves
  spectrum_bins();
  // print_fft();

}
I don't think the mic I was using is available any longer.

OLEDs:
https://www.adafruit.com/product/931
https://www.adafruit.com/product/661
 
Status
Not open for further replies.
Back
Top