Hi everybody, I am running an analog microphone into Pin 36 on a wireless stick light. It tracks frequency well [using a new 50 until it gets down to 175Hz at which point the FFT jumps up so that at 170Hz it is reading about 480-500Hz as the peak frequency - I am guessing this is something to do with sampling rate at the pin - any suggestions would be very welcome.
This is the code I am using
/*
ADC read voltage via GPIO13 with 1% accuracy.
by Aaron.Lee from HelTec AutoMation, ChengDu, China
成都惠利特自动化科技有限公司
www.heltec.cn
*/
#include “arduinoFFT.h”
#include “Arduino.h”
#define SAMPLES 256 //SAMPLES-pt FFT. Must be a base 2 number. Max 128 for Arduino Uno.
#define SAMPLING_FREQUENCY 22050 //Ts = Based on Nyquist, must be 2 times the highest expected frequency.
//const int micPin = A0; //A0;
arduinoFFT FFT = arduinoFFT();
unsigned int samplingPeriod;
unsigned long microSeconds;
double vReal[SAMPLES]; //create vector of size SAMPLES to hold real values
double vImag[SAMPLES]; //create vector of size SAMPLES to hold imaginary values
double peakAverage[10];
double peakPrint = 0;
double peak = 0;
double oldPeak = 0;
int counter;
int averagingSteps=10;
void setup() {
Serial.begin(115200);
// adc_power_on( );
// adc1_config_width(ADC_WIDTH_12Bit);
// // ADC1 channel 0 is GPIO36 (ESP32), GPIO1 (ESP32-S2)
// adc1_config_channel_atten(ADC1_CHANNEL_0 , ADC_ATTEN_DB_11);
}
int readPin = micPin;
double ReadVoltage(byte pin){
double reading = analogRead(readPin); // Reference voltage is 3v3 so maximum reading is 3v3 = 4095 in range 0 to 4095
// if(reading < 1 || reading >= 4095){
// return 0;
return -0.000000000009824 * pow(reading,3) + 0.000000016557283 * pow(reading,2) + 0.000854596860691 * reading + 0.065440348345433;
// return (-0.000000000000016 * pow(reading,4) + 0.000000000118171 * pow(reading,3)- 0.000000301211691 * pow(reading,2)+ 0.001109019271794 * reading + 0.034143524634089);
// }
} // Added an improved polynomial, use either, comment out as required
long mil=millis();
void loop() {
//Serial.println(ReadVoltage(readPin),3);
// Serial.println(analogRead(readPin));
/*Sample SAMPLES times*/
for(int i=0; i<SAMPLES; i++)
{
microSeconds = micros(); //Returns the number of microseconds since the Arduino board began running the current script.
//vReal[i] = ReadVoltage(readPin); //Reads the value from analog pin 0 (A0), quantize it and save it as a real term.
vReal[i] = analogRead(36);
vImag[i] = 0; //Makes imaginary term 0 always
//
/*remaining wait time between samples if necessary*/
while(micros() < (microSeconds + samplingPeriod))
{
// Serial.print("Real: ");
Serial.println(vReal[i]);
}
}
/*Perform FFT on samples*/
FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
/*Find peak frequency and print peak*/
peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);
peakAverage[counter] = peak;
counter++;
if(counter > averagingSteps){
counter = 0;
}
for (int x = 0; x < averagingSteps; x++)
{
peakPrint = peakPrint+peakAverage[x];
}
Serial.println(peakPrint/averagingSteps); //Print out the most dominant frequency.
peakPrint = 0;
}
//See more APIs about ADC here: https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series/blob/master/esp32/cores/esp32/esp32-hal-adc.h
/* ADC readings v voltage
- y = -0.000000000009824x3 + 0.000000016557283x2 + 0.000854596860691x + 0.065440348345433
// Polynomial curve match, based on raw data thus: - 464 0.5
- 1088 1.0
- 1707 1.5
- 2331 2.0
- 2951 2.5
- 3775 3.0
*/