You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »


Background

We can combine waves at different frequencies and amplitudes to generate complicated waves.


A Fourier transform takes a complicated looking wave and spits out the individual frequencies that it contains.


Sampling

We can sample a wave with a freqency equal to half of our sampling rate. So,  if we are sampling at 10,000 Hz, we can sample wave of 5000 Hz.




Input Circuit


Sample Code


Size of band = Sampling Rate/#Samples


#include <arduinoFFT.h>
#define AUDIO_IN_PIN    A0
#define SAMPLES         128
#define SAMPLING_FREQ   3200 
#define AMPLITUDE       100
#define NUM_BANDS       8 
#define NOISE           500           // Used as a crude noise filter, values below this are ignored

unsigned int sampling_period_us;

double vReal[SAMPLES];
double vImag[SAMPLES];
int bandValues[] = {0,0,0,0,0,0,0,0};
unsigned long newTime;

arduinoFFT FFT = arduinoFFT(vReal, vImag, SAMPLES, SAMPLING_FREQ);


void setup() {
  Serial.begin(115200);
  sampling_period_us = round(1000000 * (1.0 / SAMPLING_FREQ));
  //pinMode(AUDIO_IN_PIN,INPUT);
  Serial.println("Reading....");
  sampleInput();
  
}

void loop() {}

void sampleInput() {

  // Reset bandValues[]
  for (int i = 0; i<NUM_BANDS; i++){
    bandValues[i] = 0;
  }

  // Sample the audio pin
  for (int i = 0; i < SAMPLES; i++) {
    newTime = micros();
    vReal[i] = analogRead(AUDIO_IN_PIN); // A conversion takes about 9.7uS on an ESP32
	//Serial.print("analogVal: ");
	//Serial.println(vReal[i]);
    vImag[i] = 0;
    while ((micros() - newTime) < sampling_period_us) { /* chill */ }
  }

  // Compute FFT
  FFT.DCRemoval();
  FFT.Windowing(FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(FFT_FORWARD);
  FFT.ComplexToMagnitude();

  // BandSize = SamplingRate / NumberOfSamples
  // Bandsize = 3200/64 = 50Hz

  // Analyse FFT results
  int f = 0;
  int c = 0;
  int freqSize = SAMPLING_FREQ / SAMPLES;

  // Don't use sample 0 and only first SAMPLES/2 are usable. 
  // Each array element represents a frequency bin and its value the amplitude.
  for (int i = 2; i < (SAMPLES/2); i++){       
    if (vReal[i] > NOISE) {                    // Add a crude noise filter
      Serial.print(i);
      Serial.print("[");
      Serial.print((i-1)*freqSize);
      Serial.print("]");
      Serial.print(": ");
      Serial.println((int)vReal[i]);
      if((int)vReal[i] > c){
        f=(i-1)*freqSize;
        c=(int)vReal[i];
      }
    }
  }

  if(c>0){
    Serial.print("f=");
    Serial.print(f);
    Serial.print(" c=");
    Serial.println(c);
  }
  
}


References

ReferenceURL
Arduino FFT Libraryhttps://github.com/kosme/arduinoFFT
ESP32 spectrum analyser VU meter using arduinoFFT and a FastLED matrixhttps://www.youtube.com/watch?v=Mgh2WblO5_c
ESP32_FFT_VU - Codehttps://github.com/s-marley/ESP32_FFT_VU
  • No labels