Forum: Mikrocontroller und Digitale Elektronik FFT auf dem ESP


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Kolja L. (kolja82)


Bewertung
0 lesenswert
nicht lesenswert
Hallo

Schon als Kind habe ich einen(analogen) Lichtorgel-Bausatz von Conrad 
mit meinem Vater gelötet.
Jetzt ist ja alles viel einfacher :-)
Mein Aufbau:

NodeMCU mit Mic (inkl. Verstärker) und bis zu 18 RGB LEDs.
Aber ertsmal möchte ich mich an einer 3 (oder 4) Kanal Lichtorgel 
versuchen,
um das Prinzip zu verstehen.

Mit der arduinoFFT.h Lib ist der große mathematische Teil ja schon 
ausgelagert.

Mein Verständniss zur Verwendung der Lib:

SAMPLES gibt die Anzahl der Kanäle an.
SAMPLING_FREQUENCY gibt die Frequenz an, mit der das Signal abgetastet 
wird.

Jetzt die esten beiden  Fragen:

Warum habe ich bei 16 Samples nur 8 Kanäle?
Wie hoch darf bzw. sollte die Abtastfrequenz sein?



Dieses Sketch verwende ich:
1
#include "arduinoFFT.h"
2
3
#define SAMPLES 16             //Must be a power of 2
4
#define SAMPLING_FREQUENCY 1000 //Hz, must be less than 10000 due to ADC
5
6
arduinoFFT FFT = arduinoFFT();
7
8
unsigned int sampling_period_us;
9
unsigned long microseconds;
10
11
double vReal[SAMPLES];
12
double vImag[SAMPLES];
13
14
void setup() {
15
  Serial.begin(115200);
16
17
  sampling_period_us = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
18
}
19
20
void loop() {
21
22
  /*SAMPLING*/
23
  for (int i = 0; i < SAMPLES; i++)
24
  {
25
    microseconds = micros();    //Overflows after around 70 minutes!
26
27
    vReal[i] = analogRead(0);
28
    vImag[i] = 0;
29
30
    while (micros() < (microseconds + sampling_period_us)) {
31
    }
32
  }
33
34
  /*FFT*/
35
  FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
36
  FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
37
  FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
38
  double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);
39
40
  /*PRINT RESULTS*/
41
//  Serial.println(peak);     //Print out what frequency is the most dominant.
42
43
  for (int i = 0; i < (SAMPLES / 2); i++)
44
  {
45
    /*View all these three lines in serial terminal to see which frequencies has which amplitudes*/
46
47
    Serial.print((i * 1.0 * SAMPLING_FREQUENCY) / SAMPLES, 1);
48
    Serial.print(" ");
49
    Serial.print(vReal[i], 1);    //View only this line in serial plotter to visualize the bins
50
    Serial.print(", ");
51
52
  }
53
  Serial.println(" ");
54
  //delay(1000);  //Repeat the process every second OR:
55
  //   while(1);       //Run code once
56
}

Und das ist die Ausgabe:
1
0.0 955.2, 62.5 439.9, 125.0 19.6, 187.5 8.1, 250.0 3.8, 312.5 1.9, 375.0 1.7, 437.5 0.3,  
2
0.0 955.6, 62.5 441.5, 125.0 23.2, 187.5 5.7, 250.0 2.2, 312.5 4.4, 375.0 0.2, 437.5 0.4,  
3
0.0 954.3, 62.5 438.7, 125.0 18.7, 187.5 7.9, 250.0 3.3, 312.5 3.3, 375.0 1.3, 437.5 1.0,  
4
0.0 955.2, 62.5 440.6, 125.0 19.8, 187.5 9.2, 250.0 3.4, 312.5 1.7, 375.0 2.5, 437.5 0.4,  
5
0.0 955.5, 62.5 440.7, 125.0 20.4, 187.5 7.8, 250.0 3.0, 312.5 3.2, 375.0 0.6, 437.5 0.5,  
6
0.0 955.4, 62.5 440.0, 125.0 19.4, 187.5 7.7, 250.0 3.9, 312.5 2.2, 375.0 1.6, 437.5 0.5,  
7
0.0 957.0, 62.5 441.2, 125.0 19.3, 187.5 8.6, 250.0 2.9, 312.5 2.9, 375.0 2.4, 437.5 1.1,  
8
0.0 955.1, 62.5 440.4, 125.0 20.1, 187.5 7.3, 250.0 3.5, 312.5 2.8, 375.0 0.7, 437.5 2.0,  
9
0.0 957.1, 62.5 441.5, 125.0 20.9, 187.5 7.4, 250.0 3.7, 312.5 2.0, 375.0 1.1, 437.5 0.5,


Wie ich mir das Prinzip vorstelle:

Jeder Kanal wird einer Frequenz besser Frequenzband zugeordnet und beim 
überschreiten eines Schwellwertes die LED eingeschaltet.

Ist das so richtig?

Danke und Gruß

Kolja

von M.K. B. (mkbit)


Bewertung
0 lesenswert
nicht lesenswert
Kolja L. schrieb:
> Warum habe ich bei 16 Samples nur 8 Kanäle?

In dem FFT Algorithmus werden in diesem Fall 16 Samples in komplexe 
Werte im Frequenzbereich umgewandelt. Bei reellen Eingangssignalen sind 
diese beiden Bereiche symmetrisch. Durch die Symmetrie reicht es für 
dich nur die Hälfte auszuwerten.

> Wie hoch darf bzw. sollte die Abtastfrequenz sein?
Die Abtastfrequenz legt den Frequenzbereich deiner FFT fest. [0 - 
0.5*f_abtast]
Bei einer höheren Abtastfrequenz ist der Frequenzbereich größer, die 
Anzahl der Kanäle bleibt aber gleich, d.h. der Kanal wird breiter.
Wird allerdings die Abtastfrequenz erhöht, dann ist der analysierte 
Zeitbereich kleiner.

Da es bei dir ja nur um eine Lichtorgel geht könntest du ja auch 
verschiedenen Längen und Frequenzen durchprobieren um herauszufinden was 
das bester Ergebnis bringt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.