FFT analysis using teensy 3.2

Status
Not open for further replies.

Wicky21

Well-known member
Guys i need to make a spectrum analyzer by using AGC microphone and TFT display as shown in below link by using Teensy 3.2.

https://www.youtube.com/watch?v=FyuCdbqJtEo

Please somebody tell how to make the "design" by using Audio System Design tool.(If somebody can attach a screenshot of the design highly appreciated.
 
If your AGC mic delivers an analog signal out, you can use the Audio lib's ADC object on a connected pin.
Lots of forum discussions on this.
The input must be 1.2v peak-to-peak, centered on a bias of 0.6 v.
The Audio design tool for the adc object links to some of these threads, I believe.

With a successful adc input, the remainder of the design is an fft1024 object, and a patch cord between.
You'll poll the fft1028 object for available() and then you'll have access to the FFT bins, as often as every 12 ms.

So, the mic is a challenge - search for threads involving user NEUTRONNED and you'll learn a lot.
NEUTRONNED (Leon) has designed a mic the solves this. I've used it with good success.
 
Last edited:
YouTube video - code

Code:
// Spectrum Analyzer using a Teensy 3.2 & the Adafruit 1.8" TFT module w/ ST7735S chip
//  Test microphone is connected to A3
//  Adding some FastLED code to test interaction

//*********************************************************************************** INIT
//
#define TFT_SCLK 14  // SCLK can also use pin 13
#define TFT_MOSI 7   // MOSI can also use pin 11
#define TFT_CS   10  // CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
#define TFT_DC   20  //  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define TFT_RST   8  // RST can use any pin
#define SD_CS     4  // CS for SD card, can use any pin
#define MIC_GAIN  2  // multiplier for the specific mic

#include <Adafruit_GFX.h>    // Core graphics library
#include <ST7735_t3.h>       // Hardware-specific library for the ST7735 LCD controller
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SerialFlash.h>
#include "FastLED.h"

// create the LCD object
ST7735_t3 tft = ST7735_t3(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

// Assign human-readable names to some common 16-bit color values:
#define WHITE   0xFFFF
#define BLACK   0x0000
#define GREEN   0x07E0

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

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

// How many leds are in the strip?
#define NUM_LEDS 45

// Data pin that led data will be written out over
#define DATA_PIN 2

// Clock pin only needed for SPI based chipsets when not using hardware SPI
//#define CLOCK_PIN 8

// This is an array of leds.  One item for each led in your strip.
CRGB leds[NUM_LEDS];

#define LEDBRIGHTNESS  64   // display brightness
byte colorMap = 160;        // the offset position for the color map 
byte colorScale = 2;        // the variation in the color map - 0=one color, 4=full spectrum


//*********************************************************************************** SETUP
void setup() {
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);

  tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab
  tft.fillScreen(ST7735_BLACK);
  
  tft.setRotation(1);  // 1=270 
  tft.setTextColor(WHITE);  
  tft.setTextSize(1);
  tft.print("TFT Spectrum Analyzer ");
  
  // Audio connections require memory to work.
  AudioMemory(12);

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

}

//*********************************************************************************** LOOP
void loop() {
   byte pColor;    // a color map position
   byte Channel;   // specific frequency channel
   byte Red1;      // temporary Red value
   byte Green1;    // temporary Green value
   byte Blue1;     // temporary Blue value

//****************************************************************************** INPUT
  if (fft1024_1.available()) {
    // each time new FFT data is available, bin it into 16 channels
    // 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;

//****************************************************************************** LED OUTPUT
  for (int i = 0; i < NUM_LEDS; i++){   // cycle through all the LEDs
    pColor = i * colorScale * 4 + colorMap;  // this results in a color map position
    Channel = i/3  ;   // there are 16 frequency bands - not perfect - needs better math
 
    Red1 = (WheelR(pColor) * level[Channel]) ;   // brightness proportionally to the loudness
    Green1 = (WheelG(pColor) * level[Channel]) ; //  of the individual channel
    Blue1 = (WheelB(pColor) * level[Channel]) ;    
    
    leds[i].setRGB( Red1, Green1, Blue1);
  }
 
  FastLED.show();   //show the new strip colors - FYI - takes rough 4.66 milliseconds on the Uno


//****************************************************************************** LCD OUTPUT
    for (byte i = 0; i < 16; i++){   // cycle through the 16 channels

      // takes about 1.66msec on a Teensy 3.2 to draw two fillRect 9-pixels wide - one
      //  black to erase any old information and one for the new data
      // takes about 190usec per line on a Teensy 3.2 to draw the two drawFastVLines
      //  needed to erase the old information and draw a new line

      int line1 = level[i] * 100;
      if (line1 > 100){
        line1 = 100;
      }

      tft.fillRect( i*10, 10, 10, 128-line1, BLACK);    //erase old information
      tft.drawRect( i*10, 128-line1, 10, line1, WHITE);     //paint new bar 

      for (byte j = 1; j < 9; j++){  // draw muliple lines to create the bar
        //tft.drawFastVLine( i*10 + j, 10, 128-line1, BLACK);
        tft.drawFastVLine( i*10 + j, 128-line1, line1, Wheel565(i * 15 + 60));
      }

    }
  }
}


//*******************************************************************************************/
// Wheel565: standard color look-up routine - Input a value 0 to 255 to get an RGB color value. 
//  NOTE: The colors are a transition Green (0) to Red (85) to Blue (170) back to Green
//  RGB565 format!!
//  R4-R3-R2-R1-R0-G5-G4-G3-G2-G1-G0-B4-B3-B2-B1-B0   Bits
// |-----------|-----------|-----------|-----------|  Bytes
//*******************************************************************************************/
long Wheel565(byte WheelPos) {
  if(WheelPos < 85) {
   return ((((WheelPos * 3) / 8) * 0x0800) + ((63 - ((WheelPos * 3) / 4)) * 0x0020));
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return (((31 - ((WheelPos * 3) / 8)) * 0x0800) + (0 * 0x0020) + (WheelPos * 3 / 8));
  } else {
   WheelPos -= 170;
   return ((((WheelPos * 3) / 4) * 0x0020) + (31 - ((WheelPos * 3) / 8)));
  }
}

//******************************************************************************************/
// WheelR: Neopixel RGB color wheel - returns the Red byte (not the entire RGB word)
byte WheelR(byte WheelPos) {
  if(WheelPos < 85) {
    return WheelPos * 3; 
  } 
  else if(WheelPos < 170) {
    WheelPos -= 85;
    return 255 - WheelPos * 3;
  } else {
    return 0;
  }
}
//*******************************************************************************************/
// WheelG: same as above but just returns the Green byte 
byte WheelG(byte WheelPos) {
  if(WheelPos < 85) {
   return 255 - WheelPos * 3;
  } else if(WheelPos < 170) {
   return  0;
  } else {
   WheelPos -= 170;
   return  WheelPos * 3;
  }
}
//*******************************************************************************************/
// WheelB: same as above but just returns the Blue byte 
byte WheelB(byte WheelPos) {
  if(WheelPos < 85) {
   return 0;
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return  WheelPos * 3;
  } else {
   WheelPos -= 170;
   return  255 - WheelPos * 3;
  }
}
 
Hello Leon,
Can i buy this assembled microphone board from somewhere for my project? Are you going to sell this board?
 
Status
Not open for further replies.
Back
Top