FFT

Während ein Oszilloskop ein aufgenommenes Signal bezogen auf die Zeitbasis visualisiert, entspricht die X-Achse eines Spekrumanalysators einem endlichen Frequenzbereich, die Funktion der Y-Achse als Amplitude bleibt erhalten, obgleich bei der Spektrumanalyse meist eine logarithmische Skalierung (statt der Linearen) von Vorteil ist.

Spektrumanalysatoren können primär nach 2 Prinzipien realisiert werden, einmal analog in Form eines Heterodyn-Analysators, wo die linear ansteigende Frequenz eines Lokaloszillators mit dem Eingangssignal gemischt und anschließend durch einen Bandpassfilter geführt wird. Dieser Aufbau (der in Wirklichkeit noch einiges mehr enthält) stellt jedoch einige Anforderungen an die Qualität der verwendeten Baugruppen und ist ohne entsprechendes Wissen im Bereich HF sehr schwer umzusetzen. Wer dazu mehr wissen möchte, der Wikipedia-Artikel hält viele Infos bereit.
Daneben existiert eine rein informatische Lösung, um das Frequenzspektrum aus einer Reihe von analogen Messwerten zu extrahieren, die FFT oder Fast Fourier Transformation.

Hierfür gibt es schon ein paar wenige Bibliotheken für den Arduino, welche allerdings alle Berechnungen auf dem Mikrocontroller selbst ausführen und dementsprechend langsamer sind. Eine sehr gut Dokumentierte ist hier zu finden: http://wiki.openmusiclabs.com/wiki/ArduinoFFT
Auch ist die Größe der FFT (Anzahl an “Bins”, Einzelfrequenzen) begrenzt und nicht so einfach erweiterbar. Aus diesem Grund habe ich mich dazu entschieden, die Berechnungen und die Visualisierung auf einen Computer auszulagern und den Arduino nur zur Aufnahme der analogen Messwerte zu nutzen.

2 Dinge müssen im Bezug auf die Nutzung von FFT beachtet werden: die Größe der FFT und somit die Anzahl der Einzelfrequenzen muss eine Zweierpotenz sein. Zudem werden immer doppelt so viele Messwerter benötigt, als Einzelfrequenzen berechnet werden können.
Die maximale FFT-Länge ist auf den Arduinos mit 2 kB RAM also auf 1024 begrenzt, der nächsthöhere Wert 2048 würde einen Overflow induzieren (es werden schließlich noch andere Variablen und die serielle Kommunikation genutzt).

 


Ablaufdiagramm

Ablaufschema

Das Eingangssignal kann entweder direkt an einen Pin des Arduinos gelegt werden (wenn es im Bereich von 0-5V liegt) oder aber über den Eingangsschaltkreis “normalisiert” werden, sprich es wird ein DC-Offset hinzugefügt. In der Eingangsstufe kann zudem noch eine schaltbare Abschwächung/Verstärkung stattfinden.

Im nächsten Schritt wartet der Arduino auf einen Befehl von der seriellen Schnittstelle und führt bei Empfangen N AD-Wandlungen durch, die wiederum anschließend an die serielle Schnittstelle übergeben werden. Im Programm am PC wird nun die Fensterfunktion über die Messwerte gelegt und die FFT ausgeführt. Nach einer nachträglichen Skalierung und Übergabe an die Paint-Methode werden das Frequenzspektrum, sowie weitere Messwerte, auf dem Koordinatensystem angezeigt. Abschließend wird der nächste Startbefehl gesendet, die Kommunikation erfolgt somit synchron.

 


Eingangsbeschaltung

Eingangsbeschaltung

Das Signal wird über den Schutzwiderstand R1 eingespeist und durch die beiden Dioden auf -9,6 V bis 9,6 V limitiert. Der Operationsverstärker IC1B ist als nichtinvertierender Summierverstärker konfiguriert, der dem Eingangssignal ein konstantes Offset von 2,5 V hinzufügt. Der Summierverstärker hat einen Verstärkungsfaktor von 2, was die halbierte Signalamplitude bedingt durch R2 und R3 kompensiert, somit wird ein Eingangssignal von -2 V bis 2 V auf 0,5 V-4,5V skaliert.
Weiterführend wäre es noch sinnvoll, einen (LC-)Tiefpassfilter hinter R3 einzufügen. Beim Operationsverstärker muss auf eine ausreichend hohe Bandbreite geachtet werden, weswegen ich beim Arduino Due und einer Abtastrate von über 660 kHz einen OPA37 eingesetzt habe.

 


Arduino-Code (für Uno)

 

Arduino-Code (für Due -> empfohlen)

 

Hinweis: getestet mit dem jeweiligen Modell und Standardtakt. Auf anderen Modellen kann es sein, dass die AD-Konvertierung schneller oder langsamer erfolgt und somit die Frequenzeinteilung der X-Achse und des Cursors nicht übereinstimmen.

 


Software

GUI_markiert

Erklärung der nummerierten Positionen:

  1. Markierung des höchsten Peaks nach Frequenz und Signalintensität
  2. Resolution Band Width: Frequenzschritt pro Bin; f/Div: Frequenz pro Division
  3. Cursorposition nach Frequenz und Signalintensität
  4. Aktuelle Verbindung trennen
  5. Verfügbare COM-Ports auflisten
  6. Mit in 5 ausgewähltem Port verbinden
  7. Anzeige eines Info-Displays über dem Diagramm: aus – Wasserfall (Verlauf der Frequenzen) – Signalform (originales Signal, Zeitbasis)
  8. Mittelung der durch FFT errechneten Werte (weniger Rauschen, aber verlangsamt die Aktualisierungsrate)
  9. Größe der FFT: 64 – 1024 (bei Arduino Due bis 16384)
  10. Skalierung der Y-Achse: linear, Magnitude, logarithmisch
  11. Fensterfunktion: Hann, Hamming, Blackman
  12. Anzeige der Maximal-/Minimalwerte, Rücksetzen durch Button
  13. Persistenz der Wellenform
  14. Anzeige des Cursors (Positionierung durch Mauseingabe)
  15. Zoom bei mehr als 1024 Bins: Verschieben der Position durch Ziehen der Maus über der Zoom-Übersichtsleiste
  16. Messwerte für Debug-Zwecke: compute = Berechnungszeit der FFT, single FFT = Periodendauer eines kompletten Durchlaufs (siehe Ablaufdiagramm)

 

Wichtig:

Die Software ist in Java geschrieben, um eine plattformunabhängige Funktion zu ermöglichen. Zusätzlich werden 2 Bibliotheken benötigt, die ich aufgrund vom Copyright nicht in die Jar integriert habe, ihr müsst diese unter folgenden Links downloaden und die genannten .jar-Dateien in den leeren “lib”-Ordner kopieren. (Name nicht ändern!)

-> Bei RXTX muss noch eine DLL-Datei in das Installationsverzeichnis von Java kopiert werden, eine kurze Anleitung ist in der Readme-Datei vom heruntergeladenen RXTX-Archiv.

Hinweis: Dieses Programm verwendet folgende Software Dritter:

JTransforms:
Copyright (c) 2007 onward, Piotr Wendykier
All rights reserved.

RXTX:
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999

 

Download der Software:

  FFT-GUI.zip (489.6 KiB, 775 hits)

 [:en]

FFT

While a signal captured by an oscilloscope ist visualized related on the time base, the x-axis of spectrum analyzers respresent a limited frequency span. The intention of the y-axis as the intensity of the signal remains unaffected, although there is often used a different scaling method such as the logarithmic one.

Spectrum analyzers can be realized primarily by two principles, once analog in the form of a heterodyne analyzer, where the linearly increasing frequency of a local oscillator is mixed with the input signal and then passed through a band-pass filter. However, this structure (which in fact contains a lot more) makes some demands on the quality of the components used and is very difficult to implement without appropriate knowledge in the field of HF. Those who want to know more, the Wikipedia article holds a lot of information ready.
In addition, there is a purely informatic solution to extract the frequency spectrum of a series of analog measurement values, the FFT or Fast Fourier Transformation.

For this, there are already a few libraries for the Arduino, but which perform all calculations on the microcontroller itself and are therefore slower. A very well documented one can be found here: http://wiki.openmusiclabs.com/wiki/ArduinoFFT
The size of the FFT (number of “bins”, single frequencies) is limited and not easily expandable. For this reason I have decided to outsource the calculations and visualization to a computer and use the Arduino only for receiving the analog measurements.

2 things to note with respect to the use of FFT: the size of the FFT and thus the number of frequencies must be a power of two. In addition, always twice as many measurement measurements are needed as individual frequencies could be calculated.
The maximum FFT length is therefore limited on an Arduino with 2 kB RAM to 1024, the next higher value 2048 would induce an Overflow (there are also other variables and serial communication is used).

 


Flowchart

Ablaufschema

The input signal can be applied either directly on a pin of the Arduino (if it is in the range of 0-5V) or can be “normalized” through the input circuit, so a DC offset is added. In the input stage there can also be a switchable attenuation / gain implemented.

In the next step the Arduino waits for a command from the serial interface and performs upon receiving N AD conversions and then passes them to the serial interface. In the program on the PC, the window function is now placed over the readings and the FFT is calculated. After a post-scaling and transfering to the paint method, the frequency spectrum and other metrics on the coordinate system display are displayed. Finally, the next start command is sent, the communication is thus synchronized.

 


Input circuit

Eingangsbeschaltung

The signal is fed through the protection resistor R1 and limited by the two diodes to -9.6 V to 9.6 V. The operational amplifier IC1B is configured as an inverting summing amplifier which adds a constant offset of 2.5V to the input signal. The summing amplifier has a gain of 2, which halves the signal amplitude conditioned by R2 and R3, thus an input signal from -2 V to 2 V is scaled to 0.5 V 4.5V.
Beyond it would still makes sense to add a (LC) low pass filter behind R3 to reduce aliasing. The type of the operational amplifier used in this configuration depends on the input frequency, the sampling rate of the ADCs of the Due can go as high as 660 kHz, so I have selected the OP37.

 


Arduino-Code (for Uno)

 

Arduino-Code (for Due -> recommended)

 

Note: tested with specific models on standard clocking. On other models, AD conversion may be faster or slower and thus the frequency scale of the X-axis and the cursor would not match.

 


Software

GUI_markiert

Explanation of the numbered positions:

  1. marking the highest peak based on the frequency and signal intensity
  2. resolution band width, frequency step per bin; f/Div: frequency per division
  3. cursor position based on frequency and intensity
  4. close current connection
  5. list all available com ports
  6. connect to port chosen in 5)
  7. show info display above frequency spectrum diagram: off – waterfall (progression of frequencies) – waveform (original on timebase)
  8. averaging of the FFT values (lower noise floor but slower refreshing rate)
  9. size of FFT: 64 – 1024 (on Arduino Due up to 32768)
  10. scaling of y-axis: linear, magnitude, logarithmical
  11. windowing function: Hann, Hamming, Blackman
  12. show maximum values, reset through button
  13. persistence of the spectral waveform
  14. show cursor (positioning through mouse)
  15. zooming possible with more than 1024 bins: shifting of position by dragging the mouse on the zoom overview
  16. reading for debug purpose: compute = computing time of FFT, single FFT = peroide length (see also flowchart)

 

Important:
The software is written in Java to allow a cross-platform operation. In addition, 2 libraries are needed, which I have not integrated into the jar because of copyright, you must download them at the following links and copy the mentioned .jar files in the empty “lib” folder. (Don’t change the name!)

-> For RXTX there is still a DLL file needed, it has to be copied into the installation directory of Java, a quick guide can be found in the readme file inside the downloaded RXTX archive.

 

Download software:

  FFT-GUI.zip (489.6 KiB, 775 hits)

 

[Total: 0    Average: 0/5]

Leave Comment

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.