Chat freely about anything...

By albzn
#75062 Hi!
(If anybody has got fft to work on a esp 8266, please share your experiences and/or libraries. I would really like to get this working as efficient as possible.)

I'm trying to get the fft algorithm working on my esp8266, but I'm having big troubles with the analogread function. At least, I think the problem lies there. :/

I found a already written example and tried it but no luck.
When I call analogread outside the for loop I get a read value of around 30, but inside the loop the read value is always 0.

I'm thinking that the conversion from analog too digital takes too long?
I've seen some code examples where they change stuff in the adc conversion settings to make it faster, have anybody seen that before?

Here's the whole code....

Code: Select all/* ESP8266/32 Audio Spectrum Analyser on an SSD1306/SH1106 Display
 * The MIT License (MIT) Copyright (c) 2017 by David Bird.
 * The formulation and display of an AUdio Spectrum using an ESp8266 or ESP32 and SSD1306 or SH1106 OLED Display using a Fast Fourier Transform
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, but not to use it commercially for profit making or to sub-license and/or to sell copies of the Software or to
 * permit persons to whom the Software is furnished to do so, subject to the following conditions: 
 * The above copyrigh
 * t notice and this permission notice shall be included in all copies or substantial portions of the Software.
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * See more at http://dsbird.org.uk
*/

#include <Wire.h>
#include <Arduino.h>
#include <arduinoFFT.h> // Standard Arduino FFT library
// https://github.com/kosme/arduinoFFT, in IDE, Sketch, Include Library, Manage Library, then search for FFT
arduinoFFT FFT = arduinoFFT();

/////////////////////////////////////////////////////////////////////////
#define SAMPLES 256              //Must be a power of 2
#define SAMPLING_FREQUENCY 10000 //Hz, must be 10000 or less due to ADC conversion time. Determines maximum frequency that can be analysed by the FFT.
#define amplitude 50
unsigned int sampling_period_us;
unsigned long microseconds;
byte peak[] = {0,0,0,0,0,0,0};
double vReal[SAMPLES];
double vImag[SAMPLES];
unsigned long newTime, oldTime;

unsigned long nr = 0;
/////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(115200);
  Serial.println("Initializing");
  sampling_period_us = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
}

void loop() {

  Serial.printf("\rLoop: %d\tAnal: %d", ++nr, analogRead(A0));
  //display.drawString(0,0,"0.1 0.2 0.5 1K  2K  4K  8K");
  for (int i = 0; i < SAMPLES; i++) {
    newTime = micros()-oldTime;
    oldTime = newTime;
    vReal[i] = analogRead(A0); // A conversion takes about 1mS on an ESP8266
    Serial.printf("\tAnalogread: %d", vReal[i]);
    vImag[i] = 0;
    while (micros() < (newTime + sampling_period_us)) { /* do nothing to wait */ }
  }
  FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
  FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
  for (int i = 2; i < (SAMPLES/2); i++){ // Don't use sample 0 and only first SAMPLES/2 are usable. Each array eleement represents a frequency and its value the amplitude.
  Serial.printf("\tvReal[%d] %d", i, vReal[i]);
    if (vReal[i] > 200) { // Add a crude noise filter, 4 x amplitude or more
      if (i<=5 )             Serial.printf("0: %d\t",(int)vReal[i]/amplitude); // 125Hz
      if (i >5   && i<=12 )  Serial.printf("1: %d\t",(int)vReal[i]/amplitude); // 250Hz
      if (i >12  && i<=32 )  Serial.printf("2: %d\t",(int)vReal[i]/amplitude); // 500Hz
      if (i >32  && i<=62 )  Serial.printf("3: %d\t",(int)vReal[i]/amplitude); // 1000Hz
      if (i >62  && i<=105 ) Serial.printf("4: %d\t",(int)vReal[i]/amplitude); // 2000Hz
      if (i >105 && i<=120 ) Serial.printf("5: %d\t",(int)vReal[i]/amplitude); // 4000Hz
      if (i >120 && i<=146 ) Serial.printf("6: %d",(int)vReal[i]/amplitude); // 8000Hz
      Serial.println(i);
    }
  }
  if (millis()%4 == 0) {for (byte band = 0; band <= 6; band++) {if (peak[band] > 0) peak[band] -= 1;}} // Decay the peak
}