Migrate NodeSP
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
Before Width: | Height: | Size: 376 KiB After Width: | Height: | Size: 376 KiB |
Before Width: | Height: | Size: 182 KiB After Width: | Height: | Size: 182 KiB |
Before Width: | Height: | Size: 312 KiB After Width: | Height: | Size: 312 KiB |
|
@ -5,7 +5,7 @@ status: Aktiv
|
|||
difficulty: geht so ...
|
||||
time: ~4h
|
||||
date: 2020-02-20
|
||||
image: /images/NodeSP/NodeSP_Overview.jpg
|
||||
image: NodeSP_Overview.jpg
|
||||
keywords: NodeMCU,ESP32,FFT,Assembler
|
||||
---
|
||||
|
||||
|
@ -13,7 +13,8 @@ keywords: NodeMCU,ESP32,FFT,Assembler
|
|||
|
||||
ein Beitrag zum Thema *'Wieder versuchen./Wieder scheitern./Besser scheitern'* (Samuel Becket)
|
||||
|
||||
## Motivation ##
|
||||
## Motivation
|
||||
|
||||
Phail hat mir - temporär - ein ESP32-Dev-Board überlassen. Auf diesem
|
||||
ist ein FTDI-Chip zwecks Bereitstellung eines JTAG-Interfaces verbaut.
|
||||
Seit Sommer 2019 hat PlatformIO seinen Debugger für die Öffentlichkeit
|
||||
|
@ -22,34 +23,35 @@ Source-Level Debugging möglich ist, sondern auch auf die
|
|||
(Dis-)Assembler-Ebene gewechselt werden kann.
|
||||
Da ließe sich doch vielleicht etwas mit anfangen?
|
||||
|
||||
{{< fluid_img alt="Showtime" src="/images/NodeSP/NodeSP_Overview.jpg" >}}
|
||||
{{< fluid_img alt="Showtime" src="NodeSP_Overview.jpg" >}}
|
||||
|
||||
Wie wäre es mit einer Fingerübung in ESP32-Assembler? Eine FFT hätte
|
||||
den Charme einer späteren Nutzbarkeit für verschiedenste Projekte und
|
||||
wäre doch ein überschaubarer Aufwand ...
|
||||
|
||||
## Planung ##
|
||||
## Planung
|
||||
|
||||
Wichtig ist zunächst einmal, einen brauchbaren Algorithmus zu finden.
|
||||
Wenn ein Schneller gefunden ist, könnte dieser als Re-Implementierung
|
||||
in ESP32-Assembler vermutlich alle anderen wegblasen?!
|
||||
|
||||
+ Anforderungen:
|
||||
Anforderungen:
|
||||
|
||||
+ Der verwendete Algorithmus sollte hinreichend allgemein einsetzbar sein,
|
||||
d.h. die Meßwertblöcke sollten als 2er-Potenzen formuliert werden
|
||||
können.
|
||||
- Der verwendete Algorithmus sollte hinreichend allgemein einsetzbar sein,
|
||||
d.h. die Meßwertblöcke sollten als 2er-Potenzen formuliert werden
|
||||
können.
|
||||
|
||||
+ Außerdem sollte mit echten Fließkommazahlen gearbeitet werden
|
||||
(der ESP32 unterstützt 32-Bit IEEE754 mit 16 Registern native).
|
||||
- Außerdem sollte mit echten Fließkommazahlen gearbeitet werden
|
||||
(der ESP32 unterstützt 32-Bit IEEE754 mit 16 Registern native).
|
||||
|
||||
+ Für die Meßwerte sollen keine Vorinformationen vorliegen (d.h. beliebige
|
||||
Daten sollen verarbeitet werden können).
|
||||
- Für die Meßwerte sollen keine Vorinformationen vorliegen (d.h. beliebige
|
||||
Daten sollen verarbeitet werden können).
|
||||
|
||||
+ Neben der Fourier-Transformation soll auch die Inverse berechnet werden
|
||||
können.
|
||||
- Neben der Fourier-Transformation soll auch die Inverse berechnet werden
|
||||
können.
|
||||
|
||||
## Ausführung Testprogramm FFT
|
||||
|
||||
## Ausführung Testprogramm FFT ##
|
||||
Für die Geschwindigkeitsmessung habe ich zunächst ein Testprogramm in C(99)
|
||||
erstellt. Dies soll zunächst verschiedene Algorithmen bzw. deren Implementierungen vergleichen,
|
||||
später wird hiermit auch die Effizienz der eigenen Implementierung getestet. Es soll immer der
|
||||
|
@ -78,18 +80,18 @@ Der Speedup sinkt sehr schnell von 2.2 (für 8 Meßwerte) auf 1.1 (ab 256 Meßwe
|
|||
nicht so überzeugend (nur 10%) für den Aufwand (ich hatte mit einem Speedup von 2-5 gerechnet!). Nach einigem
|
||||
Kopfkratzen bin ich zu folgenden Erkenntnissen gelangt:
|
||||
|
||||
+ Der limitierende Faktor ist vermutlich der Speicherzugriff. Der ESP32 hat keinen Cache, d.h. alle
|
||||
- Der limitierende Faktor ist vermutlich der Speicherzugriff. Der ESP32 hat keinen Cache, d.h. alle
|
||||
Speicherzugriffe bremsen unmittelbar. Bei größeren Meßwertmengen schlägt das überproportional durch
|
||||
(Speicherzugriffe von C<->Assembler sind aufgrund der leistungsfähigen Befehle des 'Instruction Sets'
|
||||
gleich schnell, d.h. der Compiler wählt bereits die optimalen Befehle).
|
||||
|
||||
+ Moderne Prozessoren (ESP32 gemäß Doku eine 'post-RISC Architecture') haben sehr leistungsfähige
|
||||
- Moderne Prozessoren (ESP32 gemäß Doku eine 'post-RISC Architecture') haben sehr leistungsfähige
|
||||
Befehle & vergleichsweise viele Register (hier 16 'universelle' in einem Registerfile von 64 und
|
||||
16 FP-Register - sowie diverse andere hier nicht so Relevante). Früher war das mal anders ... (6510 et al.)!
|
||||
Letztlich kann dadurch der Compiler recht gut optimieren, der Gewinn durch 'Metawissen' seitens
|
||||
des Programmierers (also was man weglassen darf u.ä.) ist marginal.
|
||||
|
||||
+ Die speziellen Matrix-Support Operationen (multiply/add w/ storage pointer increment etc.)
|
||||
- Die speziellen Matrix-Support Operationen (multiply/add w/ storage pointer increment etc.)
|
||||
passten leider nicht zu dem von mir favorisierten Algorithmus (dumm gelaufen!).
|
||||
|
||||
Fazit: Nett, aber (weitgehend) sinnfrei! Eigentlich ist das zwar der Stand der Erkenntnisse (in der
|
||||
|
@ -97,18 +99,18 @@ Informatik), aber schön, das wir das noch einmal überprüft haben ...
|
|||
|
||||
Jetzt brauchen wir noch etwas 'zum Anfassen' ...
|
||||
|
||||
## Ausführung 'Spectrum Analyzer' (SP) ##
|
||||
## Ausführung 'Spectrum Analyzer' (SP)
|
||||
|
||||
Naheliegend für einen Realitätscheck ist natürlich der Aufbau eines 'Spectrum Analyzers', so eine
|
||||
Art Equalizer wie man es von Audio-Apps, Hifi-Anlagen (oder dem Autoradio) kennt - nur ohne
|
||||
Eingriffsmöglichkeit.
|
||||
|
||||
{{< fluid_img alt="Aufbaubild" src="/images/NodeSP/NodeSP_Aufbau.jpg" >}}
|
||||
{{< fluid_img alt="Aufbaubild" src="NodeSP_Aufbau.jpg" >}}
|
||||
|
||||
Aus alten Beständen hatte ich noch die LED-Streifen (WS2812) aus einem Sonderangebot. Hier fällt etwas
|
||||
Lötarbeit an (& die Heißklebepistole kommt auch zu ihrem Recht).
|
||||
|
||||
{{< fluid_img alt="Bohrschablone" src="/images/NodeSP/NodeSP_Bohrschablone.png" >}}
|
||||
{{< fluid_img alt="Bohrschablone" src="NodeSP_Bohrschablone.png" >}}
|
||||
|
||||
Für das Gehäuse habe ich eine Bohrschablone mit FreeCAD erstellt, die wir auf der neuen 'Großfräse' der
|
||||
Innovationswerkstatt dann ausgeführt haben.
|
||||
|
@ -148,8 +150,7 @@ Die Aufnahme der Meßwerte benötigt ca. 45ms, das Umrechnen per FFT ca. 0,8 ms!
|
|||
Da ich gerade keine Schalter zur Hand hatte, habe ich zum Feintuning eine Flutter-App per Multicast
|
||||
angebunden - die ich auf meinen 'NodeSwarm Devices' standardmäßig vorhalte.
|
||||
|
||||
|
||||
## NodeSP Android App ##
|
||||
## NodeSP Android App
|
||||
|
||||
Die App sendet Konfigurationsdaten an die NodeMCU per Multicast, am wichtigsten natürlich
|
||||
für das Einstellen der Empfindlichkeit. Wenn die Umgebung sehr laut ist, sollte man runterregeln können ...
|
||||
|
@ -157,10 +158,10 @@ Die restlichen Parameter dienen der Konfiguration der LED-Ausgabe.
|
|||
|
||||
<img style="max-width: 200px"
|
||||
alt="App picture"
|
||||
src="/images/NodeSP/NodeSP_App.png"
|
||||
src="NodeSP_App.png"
|
||||
/>
|
||||
|
||||
## Showtime! ##
|
||||
## Showtime!
|
||||
|
||||
Hier mal ein (kurzes) Beispiel mit Musik:
|
||||
|
||||
|
@ -170,11 +171,10 @@ Hier mal ein (kurzes) Beispiel mit Musik:
|
|||
</video>
|
||||
|
||||
|
||||
## Schwächen dieser Implementierung ##
|
||||
## Schwächen dieser Implementierung
|
||||
|
||||
Das Sampling ist nicht 'sustained rate' sondern intermittierend (wenn auch kaum spürbar).
|
||||
Es gibt lt. 'ESP32 - Technical Reference Manual' eine Betriebsart (LCD-Mode -> ADC/DAC-Mode) die hier Abhilfe schaffen könnte? Mal schaun ... (ein Tipp von Wolfgang).
|
||||
|
||||
Eine verbesserte Version werde ich zu einem späteren Zeitpunkt mittels I2S-Mikrofon (ein Tip von Markus) nachreichen
|
||||
(der ESP32 unterstützt den I2S-Bus mit DMA-Transfer - da sollte was gehen ... sagt auch das Internet :-).
|
||||
|