From e7a9e47b9ecc84bb90bbd7165006ce97c692517c Mon Sep 17 00:00:00 2001 From: G6EJD Date: Sat, 16 Dec 2017 10:43:12 +0000 Subject: [PATCH] Update ESP8266_Spectrum_Display_01.ino --- ESP8266_Spectrum_Display_01.ino | 165 ++++++++++++++++---------------- 1 file changed, 83 insertions(+), 82 deletions(-) diff --git a/ESP8266_Spectrum_Display_01.ino b/ESP8266_Spectrum_Display_01.ino index 18c2c23..67afa14 100644 --- a/ESP8266_Spectrum_Display_01.ino +++ b/ESP8266_Spectrum_Display_01.ino @@ -1,83 +1,84 @@ -/* 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 copyright 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 -#include "arduinoFFT.h" // Standard Arduino FFT library -arduinoFFT FFT = arduinoFFT(); -///////////////////////////////////////////////////////////////////////// -// Comment out the display your nNOT using e.g. if you have a 1.3" display comment out the SSD1306 library and object -#include "SH1106.h" // https://github.com/squix78/esp8266-oled-ssd1306 -SH1106 display(0x3c, D3,D4); // 1.3" OLED display object definition (address, SDA, SCL) Connect OLED SDA , SCL pins to ESP SDA, SCL pins - -//#include "SSD1306.h" // https://github.com/squix78/esp8266-oled-ssd1306 -//SSD1306 display(0x3c, D3,D4); // 0.96" OLED display object definition (address, SDA, SCL) Connect OLED SDA , SCL pins to ESP SDA, SCL pins -///////////////////////////////////////////////////////////////////////// -#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; -///////////////////////////////////////////////////////////////////////// -void setup() { - Serial.begin(115200); - Wire.begin(5,4); // SDA, SCL - display.init(); - display.setFont(ArialMT_Plain_10); - display.flipScreenVertically(); // Adjust to suit or remove - sampling_period_us = round(1000000 * (1.0 / SAMPLING_FREQUENCY)); -} - -void loop() { - display.clear(); - 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 - 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. - if (vReal[i] > 200) { // Add a crude noise filter, 4 x amplitude or more - if (i<=5 ) displayBand(0,(int)vReal[i]/amplitude); // 125Hz - if (i >5 && i<=12 ) displayBand(1,(int)vReal[i]/amplitude); // 250Hz - if (i >12 && i<=32 ) displayBand(2,(int)vReal[i]/amplitude); // 500Hz - if (i >32 && i<=62 ) displayBand(3,(int)vReal[i]/amplitude); // 1000Hz - if (i >62 && i<=105 ) displayBand(4,(int)vReal[i]/amplitude); // 2000Hz - if (i >105 && i<=120 ) displayBand(5,(int)vReal[i]/amplitude); // 4000Hz - if (i >120 && i<=146 ) displayBand(6,(int)vReal[i]/amplitude); // 8000Hz - //Serial.println(i); - } - for (byte band = 0; band <= 6; band++) display.drawHorizontalLine(18*band,64-peak[band],14); - } - if (millis()%4 == 0) {for (byte band = 0; band <= 6; band++) {if (peak[band] > 0) peak[band] -= 1;}} // Decay the peak - display.display(); -} - -void displayBand(int band, int dsize){ - int dmax = 50; - if (dsize > dmax) dsize = dmax; - for (int s = 0; s <= dsize; s=s+2){display.drawHorizontalLine(18*band,64-s, 14);} - if (dsize > peak[band]) {peak[band] = dsize;} -} - +/* 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 copyright 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 +#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(); +///////////////////////////////////////////////////////////////////////// +// Comment out the display your nNOT using e.g. if you have a 1.3" display comment out the SSD1306 library and object +#include "SH1106.h" // https://github.com/squix78/esp8266-oled-ssd1306 +SH1106 display(0x3c, D3,D4); // 1.3" OLED display object definition (address, SDA, SCL) Connect OLED SDA , SCL pins to ESP SDA, SCL pins + +//#include "SSD1306.h" // https://github.com/squix78/esp8266-oled-ssd1306 +//SSD1306 display(0x3c, D3,D4); // 0.96" OLED display object definition (address, SDA, SCL) Connect OLED SDA , SCL pins to ESP SDA, SCL pins +///////////////////////////////////////////////////////////////////////// +#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; +///////////////////////////////////////////////////////////////////////// +void setup() { + Serial.begin(115200); + Wire.begin(5,4); // SDA, SCL + display.init(); + display.setFont(ArialMT_Plain_10); + display.flipScreenVertically(); // Adjust to suit or remove + sampling_period_us = round(1000000 * (1.0 / SAMPLING_FREQUENCY)); +} + +void loop() { + display.clear(); + 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 + 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. + if (vReal[i] > 200) { // Add a crude noise filter, 4 x amplitude or more + if (i<=5 ) displayBand(0,(int)vReal[i]/amplitude); // 125Hz + if (i >5 && i<=12 ) displayBand(1,(int)vReal[i]/amplitude); // 250Hz + if (i >12 && i<=32 ) displayBand(2,(int)vReal[i]/amplitude); // 500Hz + if (i >32 && i<=62 ) displayBand(3,(int)vReal[i]/amplitude); // 1000Hz + if (i >62 && i<=105 ) displayBand(4,(int)vReal[i]/amplitude); // 2000Hz + if (i >105 && i<=120 ) displayBand(5,(int)vReal[i]/amplitude); // 4000Hz + if (i >120 && i<=146 ) displayBand(6,(int)vReal[i]/amplitude); // 8000Hz + //Serial.println(i); + } + for (byte band = 0; band <= 6; band++) display.drawHorizontalLine(18*band,64-peak[band],14); + } + if (millis()%4 == 0) {for (byte band = 0; band <= 6; band++) {if (peak[band] > 0) peak[band] -= 1;}} // Decay the peak + display.display(); +} + +void displayBand(int band, int dsize){ + int dmax = 50; + if (dsize > dmax) dsize = dmax; + for (int s = 0; s <= dsize; s=s+2){display.drawHorizontalLine(18*band,64-s, 14);} + if (dsize > peak[band]) {peak[band] = dsize;} +} +