www.mikrocontroller.net

Forum: Digitale Signalverarbeitung / DSP Schnelle FFT in Assembler

Autor: Benedikt (Gast)
Datum: 31.12.2004 09:56

Es wurde ja schon häufiger nach einem Spektrum Analyser gesucht.
Hier ein schneller Code für den mega8:
http://elm-chan.org/t/akilcd.zip
http://elm-chan.org/t/sa01.avi
http://elm-chan.org/t/sa02.avi

Leider ist das Programm für zwei LCDs mit je einem SED1520 (für Wave
und Spektrum Darstellung). Ich versuche gerade den Code für ein T6963
umzuschreiben, aber das ist nicht gerade einfach und bisher läuft noch
nicht viel, außer den Initialisierung...
Autor: Sebastian (Gast)
Datum: 31.12.2004 11:29

Cool. Die AVIs sind ja sehr vielversprechend. Schade, dass die
LCD-Routinen nicht in C geschrieben sind, das würde sie viel einfacher
portierbar machen. Ich habe z.B. eine Lib für den KS0108-Controller
geschrieben. Wenn ich jetzt eine geeignete Schnittstelle hätte, würde
ich ja glatt mal versuchen, die FFT-Routinen bei mir einzubinden.
Autor: Benedikt (Gast)
Datum: 31.12.2004 15:39

Ich habe immer noch kein LCD zum laufen gebracht, aber mal schnell ein
virtuelles Display am PC gebastelt.
Die FFT Routine ist echt beeindruckend. Nicht nur, dass diese sehr
schnell ist (ein vergleichbares C Programm ist um den Faktor 10-100
langsamer !!!!), sondern auch gleich eine Glättung beim FFT und eine
Filterung beim Oszilloskop ist eingebaut.
Autor: Berti (Gast)
Datum: 01.01.2005 13:31

Gibts einen Anschlussplan wie das Audiosignal dem AVR zugeführt
wird(Signalkonditionierung)
Autor: Benedikt (Gast)
Datum: 01.01.2005 13:52
Dateianhang: fft.jpg (46,2 KB, 2121 Downloads)
preview image for fft.jpg

Der Software nach wird das Signal über einen MAX292 Switched Capacitor
Tiefpass Filter an ADC6 eingespeist (-> SMD Version des mega8)
Für den Anfang reicht auch ein einfacher Tiefpass, oder man kann das
Signal auch direkt einspeisen, allerdings erscheint dann alle
Frequenzen über 4,7kHz gespiegelt.
An AREF wird eine externe Refernzspannung eingespeist, aber man kann es
ja auch auf interne Umschalten.

Ich werde damit jetzt einen "kleinen" Spektrum Analyser mit LEDs
bauen und zwar 32x16.
Hier schonmal ein kleiner Test.
Autor: Berti (Gast)
Datum: 01.01.2005 14:52

Zum Thema direkt einspeisen:
Wie bring i den Sttischen level von 2.5V zusammen um auch die negative
Halbwelle des Audiosignals erfassen zu können?
Autor: Benedikt (Gast)
Datum: 01.01.2005 15:03

Am einfachsten geht es wenn man VREF auf AVcc schaltet (per Software).
Ein Spannungsteiler aus zwei gleichen Widerständen zwischen AVcc und
GND und man hat die 2,5V. Mit einem kleinen Kondensator koppelt man das
Audiosignal ein.
Autor: Berti (Gast)
Datum: 01.01.2005 15:12
Dateianhang: audio.JPG (36 KB, 2191 Downloads)
preview image for audio.JPG

Passt die Schaltung so in Etwa?

Werte für C?
R1=R2 schätzomativ 4k7
Autor: Erik (Gast)
Datum: 01.01.2005 15:46

Für das C würde ich etwa 100 nF nehmen, R1 & R2 ehner hochohmiger,
resperktiv vom Spannungsteiler nochmals 100k und dan auf den Eingang
--> weniger Rauschen.
Autor: Berti (Gast)
Datum: 01.01.2005 20:14

@Benedikt:

Gibt es irgendwo einen Pseudo Code für die FFT
Oder a Flussdiagramm
Ich würd das gerne in C nachproggen aber das ASM entschlüsseln...

Das wär des Rätsels Lösung
Autor: Benedikt (Gast)
Datum: 01.01.2005 20:25

@Berti
google mal

Für C findest du einiges (z.B. fft.c), aber das ist alles verdammt
langsam (so 1/10 bis 1/100 der Geschwidnigkeit von dem ASM Programm)und
hat ehrlich gesagt bei mir noch nie richtig gut funktioniert.
Autor: Berti (Gast)
Datum: 01.01.2005 20:50

Ich google schon seit 3 Tagen finde auch einiges aber nix mit
ordentlicher Beschreibung...
Ein schöner C Code hilft wenig wenn man nicht weis was mit welchem
Parameter übergeben wird.
Ich habs mit den Numerical recipes in C versucht bin aber auch dort auf
keinen Grünen zweig gekommmen.
Autor: Benedikt (Gast)
Datum: 01.01.2005 21:02

Im Prinzip ist das immer dasselbe:
Ein Array mit den Wave Daten wird übergeben, fft läuft und man erhält
ein Array mit den Frequenzamplituden zurück. Einmal der Realteil in der
unteren Hälfte und der imaginär Teil in der oberen. Manchmal wird auch
nur der Betrag zurückgegeben.
Bei einigen Funktionen muss man auch noch die Länge mit angeben.

Eine einfache Erklärung dafür gibt es nicht. Ich habe es meistens nach
der zweiten Seite aufgegeben zu verstehen wie FFT wirklich
funktioniert...
Autor: Berti (Gast)
Datum: 01.01.2005 21:13

g Ja is sehr komplex das ganze... werd mal versuchen mit einem
fertigen Quellcode was anzufangen...
Autor: DerMax (Gast)
Datum: 02.01.2005 04:36

Ich hatte mal einen funktionierenden C-Code, leider war der wohl eher
für PC gedacht und verwendete Fließkommarechnung. Ich habs spaßes
halber mal auf nem AVR ausprobiert hat auch funktioniert aber ich
schätze mal der lag Performance-Mäßig noch nen ganzes Stück unter 1/100
von diesem hier.
Ich hab bisher noch keinen funktionierenden C-Code gefunden der mit
Integer-Arithmetik auskommt.

Ohne Verständnis der zu Grunde liegenden Mathematik hat man da denke
ich auch keine Chance irgendwas selber zu schreiben.
Ansonsten ist Asm imho eh der einzige Weg um da was halbwegs schnelles
aus nem AVR rauszuholen.

Bei diesem ist auch das Frequenzspektrum recht geschickt gewählt. Ich
hab früher mit voller Audio-Frequenz (44kHz) gesampled und dann die
höheren Frequenzbänder zusammengerechnet um einen logarithmischen
Frequenz-Maßstab zu bekommen. Das hat dann aber immer von den
Amplituden her nich richtig gepasst. Weiteres Problem war das man, um
die nötige Auflösung im niedriegen Frequenzbereich zu bekommen eine FFT
mit 512 oder besser sogar 1024 Punkten bräuchte wo dann der AVR
irgendwann endgültig das Handtuch schmeißt. Die oberen Bereiche sind
aber eigentlich eh uninterresant (jedenfalls wenn nur schön aussehen
soll) Und im unteren Bereich tuts dann auch ein linearer Maßstab so
kann man ne ganze Menge Performance sparen.
Autor: Benedikt (Gast)
Datum: 02.01.2005 08:29

512 Punkte wären ja kein Problem, es wären immernoch über 25
Messungen/s:

;----------------------------------------------------------;
; Spectrum analyzer
;----------------------------------------------------------;
; 16bit fixed point FFT performance with megaAVR @16MHz
;
;  Points:  Input,    FFT, Output,   Total: Throughput
;   64pts:  .17ms,  1.9ms,  1.4ms,   3.5ms:   18.3kpps   (expected)
;  128pts:  .34ms,  4.4ms,  2.6ms,   7.3ms:   17.5kpps   (measured)
;  256pts:  .68ms, 10.1ms,  5.2ms,  16.0ms:   16.0kpps   (expected)
;  512pts:  1.4ms, 22.6ms, 10.4ms,  34.4ms:   14.8kpps   (expected)
;
; Input: Input waveform into butterfly table with applying window
; FFT: Execute butterfly operations
; Output: Descramble and output the spectrum as scalar values

Nur leider habe ich keine Ahnung wie die dazu passende Hamming Tabelle
usw. aussehen muss.
Ich habe die Samplerate verdoppelt und so die Frequenz bis auf 10kHz
erhöht. Die 64 Werte werden "Pseudologarithmisch" zu 32 Werten
zusammengefasst. Da hatte ich anfangs auch das Problem wie ich die
Werte am besten zusammenfasse: Bilde ich Mittelwerte ist die Amplitude
bei 4 Mittelwerten maximal 1/4 wenn nicht alle 4 Frequenzen vorkommen.
Daher suche ich jetzt den Maximalwert aus den 4 Werten, was auch ganz
gut passt.
Eventuell werde ich später (falls es mal eine neue Version des FFT
Programms gibt) auf 256 oder 512 Punkte erhöhen um im unteren Bereich
eine höhere Auflösung zu erzielen. 156Hz sind nicht gerade das beste.
Mit 512 Punkten wären es immerhin 39Hz...
Die zusammengefassten Werte werden per UART an einen zweiten uC
übertragen der als Display Controller für eine 32x16 LED Matrix
arbeitet.
Autor: Matthias (Gast)
Datum: 02.01.2005 09:54

Hi

Hamming-Fenster berechnet sich ganz simpel nach
http://www.uni-regensburg.de/Fakultaeten/nat_Fak_I...
Seite 14.

Matthias
Autor: Benedikt (Gast)
Datum: 02.01.2005 10:16

Dann bleibt nur noch die unterste Tabelle, die mir überhaupt nichts
sagt.
Die Cosinus Tabelle muss ich auch auf die enstpreche Länge umrechnen,
oder ?

; These tables must be rebuilt when change FFT_N

t_cos_sin:  ; {cos(x),sin(x)} table (0 <= x < pi, in 64 steps)
  .dw  32767, 0, 32727, 1607, 32609, 3211, 32412, 4807
  .dw  32137, 6392, 31785, 7961, 31356, 9511, 30851, 11038
  .dw  30272, 12539, 29621, 14009, 28897, 15446, 28105, 16845
  .dw  27244, 18204, 26318, 19519, 25329, 20787, 24278, 22004
  .dw  23169, 23169, 22004, 24278, 20787, 25329, 19519, 26318
  .dw  18204, 27244, 16845, 28105, 15446, 28897, 14009, 29621
  .dw  12539, 30272, 11038, 30851, 9511, 31356, 7961, 31785
  .dw  6392, 32137, 4807, 32412, 3211, 32609, 1607, 32727
  .dw  0, 32767, -1607, 32727, -3211, 32609, -4807, 32412
  .dw  -6392, 32137, -7961, 31785, -9511, 31356, -11038, 30851
  .dw  -12539, 30272, -14009, 29621, -15446, 28897, -16845, 28105
  .dw  -18204, 27244, -19519, 26318, -20787, 25329, -22004, 24278
  .dw  -23169, 23169, -24278, 22005, -25329, 20787, -26318, 19519
  .dw  -27244, 18204, -28105, 16845, -28897, 15446, -29620, 14009
  .dw  -30272, 12539, -30851, 11038, -31356, 9511, -31784, 7961
  .dw  -32137, 6392, -32412, 4807, -32609, 3211, -32727, 1607

t_hamming: ; Hamming window (for 128 samples)
  .dw  2621, 2639, 2693, 2784, 2910, 3073, 3270, 3502
  .dw  3768, 4068, 4401, 4765, 5161, 5587, 6042, 6525
  .dw  7036, 7571, 8132, 8715, 9320, 9945, 10588, 11249
  .dw  11926, 12616, 13318, 14031, 14753, 15482, 16216, 16954
  .dw  17694, 18433, 19171, 19905, 20634, 21356, 22069, 22772
  .dw  23462, 24138, 24799, 25443, 26068, 26673, 27256, 27816
  .dw  28352, 28862, 29345, 29800, 30226, 30622, 30987, 31319
  .dw  31619, 31885, 32117, 32315, 32477, 32603, 32694, 32748
  .dw  32767, 32748, 32694, 32603, 32477, 32315, 32117, 31885
  .dw  31619, 31319, 30987, 30622, 30226, 29800, 29345, 28862
  .dw  28352, 27816, 27256, 26673, 26068, 25443, 24799, 24138
  .dw  23462, 22772, 22069, 21356, 20634, 19905, 19171, 18433
  .dw  17694, 16954, 16216, 15482, 14753, 14031, 13318, 12616
  .dw  11926, 11249, 10588, 9945, 9320, 8715, 8132, 7571
  .dw  7036, 6526, 6042, 5587, 5161, 4765, 4401, 4068
  .dw  3768, 3502, 3270, 3073, 2910, 2784, 2693, 2639

t_desc:  ; Descramble table (for 128 point FFT)
  .dw  0*4, 64*4, 32*4, 96*4, 16*4, 80*4, 48*4, 112*4
  .dw  8*4, 72*4, 40*4, 104*4, 24*4, 88*4, 56*4, 120*4
  .dw  4*4, 68*4, 36*4, 100*4, 20*4, 84*4, 52*4, 116*4
  .dw  12*4, 76*4, 44*4, 108*4, 28*4, 92*4, 60*4, 124*4
  .dw  2*4, 66*4, 34*4, 98*4, 18*4, 82*4, 50*4, 114*4
  .dw  10*4, 74*4, 42*4, 106*4, 26*4, 90*4, 58*4, 122*4
  .dw  6*4, 70*4, 38*4, 102*4, 22*4, 86*4, 54*4, 118*4
  .dw  14*4, 78*4, 46*4, 110*4, 30*4, 94*4, 62*4, 126*4
Autor: Matthias (Gast)
Datum: 02.01.2005 10:47

Hi

die FFT würfelt bei Eingangsdaten der Form x[0], x[1], x[2] usw. die
Reihenfolge des Ergebnisfelds etwas durcheinander. Hier ist eine Grafik
wie das etwa aufgebaut ist:

http://www.kgw.tu-berlin.de/lehre/skript/ds/node36.html

Solltest du mit etwas Denken auf mehr Punkte ausbauen können.

Matthias
Autor: Benedikt (Gast)
Datum: 02.01.2005 11:39

Mit etwas nachdenken wars klar:
Die Bitreihenfolge wird gedreht: 0->0, 1->128, 2->64, 4->32 usw

Jetzt habe ich zwar die Tabellen, aber es geht nicht. Ich hätte auch
eher drauf kommen können:
CaptBuf:.byte  FFT_N*2    ;Sampling buffer
BflyBuf:.byte  FFT_N*4    ;Butterfly operation table, Wave form buffer
LvlBuf:  .byte  FFT_N/2    ;Spectrum bar length

Bei 128 Punkten sind das schon 832 Bytes, bei 256 wären es 1664, aber
der mega8 hat nur 1kB SRAM.
Dann muss ich wohl einen mega8515 mit 32kb SRAM verwenden und den ADC
ebenfalls nach draußen verlagern...
Autor: VHDL (Gast)
Datum: 02.01.2005 14:07

Die FFT lässt sich mit Bestimmtheit auch inplaced umbauen. Dann
benötigst du nur noch den BflyBuf: .Byte FFT_N*4 Buffer.

Falls du statt der Fixed Point/Floating Point FFT eine Integer FFT
benutzt so kannst du diesen Buffer auf FFT_N Bytes reduzieren.
Allerdings arbeiten fast alle Integer FFT's modular, also mit
Divisionen und diese sind langsammer. Es gibt zwei Ausnahmen, die
Montgomery basierte FFT die statt vieler modularer Divisionen eben
Multiplikationen in der sogenannten Montgomery Domain benutzt. Oder
eben die modulare Fermat FFT nach Schönhage/Strassen. Diese FFT
arbeitet modular 2^(N*M) und solche Divisionen zu dieser speziellen
Form der modularen Ringe kommen ganz ohne Multiplikationen und
Divisionen aus. Sie benötigen nur Shift Operationen , Additionen und
Subtraktionen. Allerdings dürfte dies für einen AVR eher schlecht sein
da die Multiplikation nur 2 Takte benötgt, dagegen aber eine beliebige
Shift Operation 1*i Takte benötigt.

Ich vermute das eine modulare Integer FFT wie die von Nussbaumer mit
Primzahlringen auf dem AVR der beste Kompromiss ist. Leider habe ich
persönlich mit diesen FFT's nur auf Intel PC's praktische Erfahrungen
gesammelt.

Gruß hagen
Autor: Benedikt (Gast)
Datum: 02.01.2005 14:19

Ich verstehe zwar ehrlich gesagt nicht viel von dem was du geschrieben
hast, weshalb ich leider auch auf fertige Software angewiesen bin, aber
da diese Version so extrem schnell läuft, bin ich mit den ganzen
Kompromissen mit dem Speicherbedarf durchaus zufrieden.
Ich habe eine Application Note die eine FFT auf einem PIC beschreibt.
Dieser benötigt 100ms für eine 256Punkt FFT, während der AVR gerade mal
16ms benötigt.
Autor: ape (Gast)
Datum: 17.01.2005 03:26

So ich hab jetzt auch mal ein bisschen mit dem Code rumexperimentiert.
Ich hab den LCD-Kram erstmal rausgeschmissen und sende jetzt die
Spektrum-Daten über UART an den PC. Ist schon sehr geil der Code.
Extrem schnell und das Spektrum sieht ganz gut aus (und das obwohl ich
im moment noch nichtmal einen Tiefpass davor hab :))
Ein paar Probleme hat mir die recht kleine Amplitude (auf die 32 pixel
Höhe vom im Original verwendeten LCD skaliert?) des Spektrums bereitet.
Ich hab jetzt die Zeile
  ldi  AH, 256/3
in make_bars durch
  ldi  AH, 255
ersetzt. Damit erreichen die Spektrum-Werte einen Maximal-Wert von
knapp 160, was für meine Zwecke ausreichend ist. Trotzdem wärs ganz
schön, wenn man 8 bit voll ausnutzen würde. Kennt da jemand ne Stelle
wo man noch dran drehen kann. (Ich bin so schon kein Freund von asm,
aber bei den Berechnungen dadrin blick ich nichts mehr...)

Der Plan sieht jedenfalls vor den Mega über TWI anzusprechen um dann
die Spektrum-Daten darüber auslesen zu können. Auf diese Weise kann
sich der Master noch um andere Dinge kümmern und ist nicht völlig mit
der FFT ausgelastet.
Außerdem werd ich mich auch mal an einer 256-Punkte FFT versuchen.
Allerdings werde ich dafür einen Mega32 verwenden. Der kostet auch
nicht mehr wie ein kleinerer Mega + SRAM und nimmt weniger Platz weg :)
Autor: Matthias Waldhauer (Gast)
Datum: 17.01.2005 12:05

Was haltet ihr davon:

http://www.jjj.de/fft/int_fft.c

Sehr viel mehr zum Thema FFT gibt es direkt unter www.jjj.de zu finden.
Autor: Matthias (Gast)
Datum: 17.01.2005 13:12

Hi

ist in C geschrieben. Die Fixkomma-Berechnungen werden wohl nicht mit
dem FMUL-Befehl gemacht werden. Das dürfte die Berechnungen dann doch
deutlich ausbremsen.

Matthias
Autor: Matthias Waldhauer (Gast)
Datum: 17.01.2005 13:16

Ich habe es gepostet, weil jemand nach einem C-Code fragte, um den
Algorithmus besser verstehen zu können. Die oben verlinkte ASM-Version
soll dadurch natürlich nicht ersetzt werden.
Autor: ape (Gast)
Datum: 17.01.2005 17:03
Dateianhang: SpecAna.zip (5,2 KB, 468 Downloads)

Hi,
da ich danach gefragt wurde hier mal mein editierter Code für den
mega8. Das AudioSignal wird mittels Koppel-Kondensator und
Spannungsteiler auf AVCC/2 gebracht (weiter oben ist es glaub ich
irgendwo nochmal genauer beschrieben) und an den ADC0-Channel
angeschlossen.
Die Daten werden übers UART mit 115kbps übertragen. Es existiert so gut
wie kein Protokoll. Es werden lediglich immer die 64 Werte des Spektrums
übertragen gefolgt von einem '\r'. Man sollte aber beachten dass auch
werte aus dem Spektrum den wert 13 (also '\r') haben können. Is halt
ein ganz billiger Prototyp, wer das wirklich verwenden will, sollte da
noch ein wenig dran arbeiten.
Außerdem verwende ich einen 18,432MHz Quarz (ich weiß damit ist der AVR
leicht übertaktet), wenn jemand einen anderen verwenden möchte, muss er
die Einstellungen für die UART Baud-Rate anpassen.
Alles andere hab ich erstmal rausgeschmissen. Also kein LCD, keine
Pause-Funktion, und auch keine Takterzeugung für den MAX293.

mfg
ape
Autor: Benedikt (Gast)
Datum: 17.01.2005 17:32
Dateianhang: fft232.asm (16,5 KB, 817 Downloads) | formatierter Code

@ape
Ich hatte es bei mir genauso gemacht:
18,432MHz Quarz an den AVR (selbst 24MHz machen die meisten noch mit),
Teiler für den ADC auf 64 um etwa 22kHz Samplerate zu erhalten, für
einen nutzbaren Bereich 0-10kHz (der brauchbare Teil des
Audiospektrums).
Im Anhang mal meine Software, bereits mit Tabellen für eine 256-Punkte
FFT. Das einzige was mir im Moment dazu noch fehlt ist der mega32 o.ä.
Wenn jemand noch für andere Werte die Tabellen braucht, kann ich diese
gerne erstellen.
Die Software überträgt die Werte ebenfalls über UART, aber nicht als 64
Werte, sondern als Grafikdaten, da ich damit ein 32x16 LED Display
ansteuere. Die Daten werden als 2x 32x 8bit übertragen: Erst die 32
Werte der oberen Hälfte der 16 LED Zeilen, dann nochmal 32 Werte für
die untere Zeile. Als Synchronisation dient Pin D.2. Die 64 Werte
werden pseudologarithmisch zu 32 Werten zusammengefasst: Im unteren
Frequenzbereich werden die Werte einzeln übertragen, dann immer zwei,
später drei und am oberen Ende dann vier Werte zusammengefasst zu
einem. Beim Zusammenfassen wird immer der Maximalwert der Einzelwerte
verwendet.
Aus irgendeinem, mir unerklärlichen Grund hängt sich die Software ab
und zu auf wenn man das Eingangssignal übersteuert, daher der Watchdog.
Autor: ape (Gast)
Datum: 17.01.2005 19:03
Dateianhang: SpektrumAnalyser.zip (47,6 KB, 559 Downloads)

So hab nochma nen bissle an meinem Prog gebastelt
nach den 64 Werten wird jetzt der Wert 254 gesendet. So große Werte
nehmen die Spektrum-Werte nicht an, daher kann man sich darauf
synchronisieren.
Außerdem hab ich noch mein Java-Programm mit reingepackt was das ganze
aufm PC auswertet. Standardmäßig wird COM2 verwendet, für einen anderen
Port muss man die start.bat entsprehend anpassen.

@benedikt
Hab hier schon nen mega32 liegen, werd das gleich mal ausprobieren.
Bei der Sampling-Rate werd ich aber denke ich bei 11kHz bleiben. Mit
22kHz hat man auch bei 256 Punkten nur rund 80Hz Auflösung 40 find ich
da schöner und über 5kHz sind die Amplituden der Frequenzen auch nich
mehr sonderlich hoch, so dass es da auch nicht mehr all zu viel zu
sehen gibt.
Autor: ape (Gast)
Datum: 18.01.2005 00:22

Mhmm also mit 128 Punkte FFT läuft das ganze jetzt aufm mega32 (nachdem
ich drauf gekommen bin das an bei den Interrupt-Vektoren jmp-Befehle an
Stelle der rjmp müssen). Für 256 Punkte muss man aber neben den Tabellen
auch noch alle Zähler die bis FFT_N zählen auf 16-Bit umbauen, damit sie
bis 256 zählen können und damit sind meine bescheidenen asm-Kenntnisse
leider erstmal etwas überfordert.
Autor: Quark (Gast)
Datum: 18.01.2005 17:42

Hallo Benedikt,
Du machst doch viel mit dem M16C?
Lohnt es sich den FFT-Code zu portieren, dann hätte
man genug RAM für große Tabellen.
Was meinst Du, ist der Code schwer zu portieren?
Ich würde mich dann auch für den M16C interessieren.
Allerdings bringt Atmel auch immer schnellere, Codekompatible
MCs raus, brauche ichalso nur etwas zu warten.
Vielen Dank für Deine Meinung/Bewertung.
Grüüe
Quark

P.S. ich freue mich auch über die Meinung anderer.
Autor: Benedikt (Gast)
Datum: 18.01.2005 18:33

M16C ist eben eine ganz andere Klasse als der AVR, nicht nur in der
Rechenleistung/Ausstattung, sondern auch im Preis und Gehäuse:
Unter 25€, 100 Pins bekommt man die normalen M16C nicht (es gibt
spezielle, abgespeckte Varianten, aber da hat man wieder das Problem
mit einer geeigneten Bezugsquelle).
Ich hatte schonmal einen C Code auf dem M16C ausprobiert und war
ehrlichgesagt enttäuscht. Eine 256 Punkt FFT hatte rund 0,5s gedauert,
obwohl nichtmal Fließkommazahlen verwendet wurden.
Auch von der Qualität her waren die Ergebnisse lange nicht so gut.

Ein speziell für den M16C optimierter Assembler Code müsste aber bei
24MHz mindestens doppelt so schnell laufen, wie auf dem AVR mit 16MHz,
nicht nur wegen den 16bit sondern auch daher, dass der M16 im gegensatz
zum AVR ein CISC uC ist, der u.a. über Barrelshifter o.ä. verfügt.

Falls es mal jemand versuchen sollte, ich wäre an dem Code
interessiert...

Andere Frage: Wo bekommt man eigentlich den MAX292 ?
Damit könnte man schön ohne aufwendige 256 Punkt FFT den gesamten
Bereich logarithmisch darstellen, indem man mehrere Messungen für
unterschiedliche Frequenzbereiche macht:
Eine 32 Punkt FFT für den Bereich <500Hz mit 16Hz Auflösung, dann
eine 32 Punkt FFT für den Bereich bis 10 oder 20kHz mit 300 oder 600Hz
Auflösung. Das sollte eine bessere Auflösung im unteren Bereich geben,
aber trotzdem schneller sein als ein 256Punkt FFT.
Autor: Matthias (Gast)
Datum: 18.01.2005 18:50

Hi

ich bin mir nichtmla so sicher das der M16C soviel schneller ist als
ein AVR bei der FFT. Der AVR hat mit seinen schnellen FMUL-Befehlen ein
Möglichkeit zur sehr schnellen Multiplikation von Fixkommazahlen. Diese
fehlt dem M16C.

Matthias
Autor: Benedikt (Gast)
Datum: 18.01.2005 19:28

Für eine 16x16 Multiplikation benötigt der AVR aber eine Menge Befehle,
für den M16 sind es weitaus weniger, es sollte daher schneller sein.
Ein großer Vorteil beim M16 ist die CPU Architektur mit einem sehr
schnellen Zugriff auf den SRAM und den Flash.
Der AVR benötigt für das Lesen eines Bytes aus dem Flash 187ns (bei
16MHz), beim M16C ist es nur die Hälfte für einen 16bit Wert. Insgesamt
sollte es also deutlich schneller werden, wenn man alles richtig
optimiert.
Autor: Quark (Gast)
Datum: 18.01.2005 19:59

also ist das "Übersetzen" des Code nicht so einfach,
bzw. eine aufwendige Sache, schade, wäre interessant.
Was ein Barrelshifter frage ich hier lieber nicht
(ich suche mal selber (wiki)).
Sonst werde ich hier im Thread noch völlig OT.
Quark
Autor: Benedikt (Gast)
Datum: 19.01.2005 06:48

Ein Barrelshifter ist im prinzip ein normaler Rechts/Linksshift, mit dem
Unterschied, dass man direkt angeben kann um wieviele Bits geschoben
werden soll. Das ist vor allem bei Multiplikationen/Divisionen mit 2^n
hilfreich und sehr viel schneller als Multiplikationen.
Ich weiß jetzt allerdings nicht, ob das für den FFT Code jetzt speziell
hilfreich ist, aber es sind eben die vielen Kleinigkeiten die alles
etwas beschleunigen.
Autor: Matthias Waldhauer (Gast)
Datum: 19.01.2005 15:47

@VHDL:
Die meisten der von dir genannten Integer-FFT-Verfahren (und NTTs) sind
zwar gut geeignet, um z.B. große Integer-Zahlen (mod 2^n-1) zu
multiplizieren, aber für eine Frequenzanalyse leider ungeeignet.

Die hier oft zitierte "Integer-FFT" arbeitet ja nicht direkt mit
Integer-Werten, sondern mit per Integer-Datentyp repräsentierten
Festkommazahlen. Das hat sogar den Vorteil, daß z.B. Optimierungen im
Speicherlayout oder z.B. der Butterfly-Struktur (z.B. Split-Radix)
problemlos von Floating-Point-FFTs auf die Fixed-Point-Varianten
übertragen werden können.
Autor: Winfried Alex (Gast)
Datum: 20.01.2005 07:23

Hallo,

falls einer das ganze mit dem MEGA64 oder 128 machen möchte (wegen mehr
RAM..) habe ich vor einiger Zeit kleine Adapterboards gemacht mit allem
drauf, was ein AVR zum Laufen benötigt. Eine zweite etwas größere
Version sogar mit ISP und JTAG-Steckverbinder. Alle Pins des AVR sind
auf Pfostenleisten gelegt, so daß auch mit Lochrasterplatinen
gearbeitet werden kann.

Infos dazu gibt es hier:
http://www.alex-elektronik.de/html/produkte.htm

Vielleicht hilft das ja jemandem von euch.
Gruß Winfried
Autor: Matthias Asselborn (Gast)
Datum: 20.01.2005 13:04

ah wie ich sehe ist nun aus der digitalen Spec Analyzer Variante nun
doch was geworden g
Autor: ape (Gast)
Datum: 20.01.2005 13:24
Dateianhang: IMG_4397.JPG (126,6 KB, 1237 Downloads)
preview image for IMG_4397.JPG

So hab jetzt mal nen Versuchsaufbau mit LCD fertig (siehe Bild im
Anhang) Der mega32 auf dem Steckbrett macht die FFT (immernoch nur 128
Punkte) und sendet das Ergebnis an den mega128 auf dem STK500, welcher
dann das LCD ansteuert. Natürlich brauch man dafür keinen mega128 aber
der lag gerade rum :)
Das ganze würde sich natürlich auch von einem einzigen AVR erledigen
lassen (so wie beim Original), aber später soll der AVR der das Display
ansteuert noch eine ganze Menge mehr tun, so dass für die FFT nicht mehr
wirklich viel Zeit bleiben würde.
Der mega32 schafft übrigens 80 FFTs pro Sekunde, die auch alle auf dem
Display angezeigt werden.
Autor: Paul (Gast)
Datum: 20.01.2005 13:24

Leider versteh ich von dem allen hier noch sehr wenig. Wäre mit einem
übertakteten AVR auch die anzeige von frequenzen um die 16-18khz
möglich? Ich wollte einen mono spectrumanalyzer mit 8-12Bändern von
40hz bis 16-18khz bauen, funktioniert sowas? oder sind die AVRs dazu
einfach zu langsam so dass ich auf analoge mittel zurückgreifen muss?
Autor: ape (Gast)
Datum: 20.01.2005 13:29
Dateianhang: IMG_4398.JPG (106,1 KB, 1432 Downloads)
preview image for IMG_4398.JPG

Hier nochmal das Display aus der Nähe

@Paul:
um Frequenzen von 40Hz bis 18kHz anzeigen zu können bräuchtest du eine
1024 Punkte FFT (20kHz / 40Hz = 500 Schritte d.h. 1024 Samples) da ist
sicherlich auch dieser Code nicht mehr wirklich shcnell, außerdem
bräuchtest du ne Menge externes RAM.
Eine andere Möglichkeit wären 2 FFTs, eine hochauflösende für diue
niedrigen Frequenzen und eine grobe für die hohen, wie es Benedikt
vorgeschlagen hat. Damit könnte es funktionieren.
Autor: Benedikt (Gast)
Datum: 20.01.2005 13:33

@Matthias Asselborn

Wo hast du eigentlich deine LEDs gekauft ?
Diese sind bei meiner Version eigentlich das teuerste (>60€ nur für die
LEDs, vor allem da Reichelt die Preise von 9 auf 12Cent pro LED erhöht
hat...). Die restlichen paar Transistoren und die zwei uC ändern da
fast nichts mehr am Preis.
Hast du normale LEDs verwendet, oder irgendwelche Superhellen ?

Ich bin noch am Überlegen was ich verwende (32 Frequenzen mit je 16
LEDs ergibt 512 LEDs !) Matte LEDs sehen warscheinlich besser aus, aber
da macht mir die Helligkeit Probleme da ich mit einem 1/32 Multiplex
arbeite. Daher müssten die LEDs mindestens 150mA Spitzenstrom schaffen
um auf etwa 5mA mittleren Strom zu kommen.
Autor: ape (Gast)
Datum: 20.01.2005 13:37

@benedikt: LEDs gibs oft bei ebay sehr günstig
Autor: Matthias Asselborn (Gast)
Datum: 20.01.2005 13:43

habe 2mA led s verwendet vom reichelt platinen in bulgarien ätzen lassen
!

habe aber daheim auch noch samsung led dot matrix displays 3 farbig...
Autor: Matthias Asselborn (Gast)
Datum: 20.01.2005 13:45

sendest du mir bitte mal einen schaltplan deiner version mit µC das
würde mich nun brennend interessieren !

bzw layouts oder codes ?
Autor: Benedikt (Gast)
Datum: 20.01.2005 14:13

@Matthias Asselborn

Den Schaltplan werde ich warscheinlich erst erstellen wenn alles
läuft.
Bisher habe ich nur einen mega8 aufgebaut der die FFT macht und die
Daten über den UART an einen zweiten uC sendet. Dieser zweite uC (ein
AT89C2051) arbeitet als LED Displaycontroller um über zwei 74HC4094
Schieberegister mit Latch die 16 LED Zeilen anzusteuern. Die 32 Spalten
werden dann mit zwei 4-zu-16 Dekoder und MOSFETs angesteuert, immerhin
fließen hier über 2A pro Spalte.
Sobald das Ding läuft werde ich den Schaltplan und die Software hier
reinstellen. Erste Tests mit einem simulierten 32x16 LED Display am PC
waren auf jedenfall sehr vielversprechend.

Das ganze hat eigentlich nicht wirklich ein Nutzwert, sondern es ist
nur ein Dekorationsobjekt, das ich mir als Art "High-Tech Bild" an
die Wand hängen werde. Warscheinlich werde ich noch eine weitere
Software programmieren, die auf der 32x16 LED Matrix Texte oder eine
Uhr anzeigt.
Autor: Paul (Gast)
Datum: 20.01.2005 14:54

ich scheue mich nicht davor gleich 2 oder 3 AVR's zu verwenden da die
ausgabe sowieso auf LEDs erfolgt. Nur schaff ich damit noch 50-60fps?
30-40 fps wären auch noch ausreichend aber darunter fängt alles an zu
stocken und sieht unschön aus. Angenommen man lässt die AVRs mit 24mhz
laufen, würden die das schaffen? Ein frequenzspektrum von 40hz bis nur
10khz ist doch etwas mager.. bis 16khz wollte ich mindestens gehen
damit ich wirklich alle bänder drin hab. Notfalls könnte ich für die 3
bänder über 10khz jeweils einen eigenen AVR verwenden

mfg Paul
Autor: Benedikt (Gast)
Datum: 20.01.2005 15:11

@Paul
Der Frequenzbereich ist kein Problem, allerdings muss man beim ADC
aufpassen, der schafft max. 30-40kHz Samplerate für etwa 8bit
Auflösung.
Verwendet man einen größeren Frequenzbereich (z.B. 0-20kHz) so wird
dieser in 64 Frequenzen aufgetrennt, man hat also eine Auflösung von
312Hz, was vor allem im unteren Bereich nicht gerade hochauflösend
ist.
50-60Hz ? Für was denn ? Selbst irgendein Winamp Plugin schafft das
gerade mal so. 10fps reichen für eine flüssige Darstellung aus, und das
schafft der AVR sogar mit 16MHz. Die FFT Routine benötigt 7,3ms zum
Berechnen der 64 Punkt, so dass theoretisch 137fps möglich sind.
Autor: ape (Gast)
Datum: 20.01.2005 15:19
Dateianhang: IMG_4401.JPG (96 KB, 1214 Downloads)
preview image for IMG_4401.JPG

So hab jetzt auch noch ein Peakhold eingebaut. Die Peakwerte fallen mit
steigender Geschwindigkeit nach unten (so wie bei WinAmp)

@paul:
Naja wenn du 2 AVRs verwenden möchtest könnte der erste mit 10kHz
samplen mit einer 256 Punkte FFT (so sie denn irgendwann funktioniert)
ergäbe sich dann eine Auflösung von 40Hz bis zu einer Frequenz von
5kHz. Der zweite könnte mit 32kHz samplen. Das Ergebnis ginge dann dann
bis 16kHz mit 125Hz Auflösung. Damit sollten dann 30fps möglich sein
(reiner Schätzwert...)
Abgesehen von der Berechnung musst du dir dann aber auch noch Gedanken
über die Aufbereitung der Daten machen. Immerhin müsstest du dan
30mal/s 256 Werte aus 2 AVRs übertragen, diese Daten zu den einzelnen
Bändern zusammenrechnen und dann noch auf einem Display anzeigen.
Autor: Benedikt (Gast)
Datum: 20.01.2005 15:45

@ape
Könntest du mal die Software dazu posten ?
Was ist das für ein LCD ? irgendein KS oder T6963 ?
Ich habe gerade mein altes 120x48 LCD wieder gefunden, und bekam direkt
Lust das ganze mal auszuprobieren.
Vielleicht werde ich das ganze auch mal an einem 128x64 OLED
ausprobieren, aber da muss ich erstmal schauen ob der uC das schafft,
denn das OLED hat keinen Controller und ist deshalb etwas CPU lastig.
Autor: Paul (Gast)
Datum: 20.01.2005 16:02

Naja das ganze soll wie gesagt über LED's ausgegeben werden..

nur mittlerweile bin ich an der überlegung ob das mit analogtechnik
nicht sogar einfacher geht?

Wenn ich zb. einen 32 Band spectrum analyzer nehme und über ein
sinussignalgenerator alle frequenzen gleichmäßig durchlaufen lass,
laufen die frequenzen gleichmäßig über das display drüber? In dem fall
würde mir ein AVR der mit 32 Bändern der den Frequenzbereich von
0-20khz abdeckt schon ausreichen.

mfg Paul
Autor: ape (Gast)
Datum: 20.01.2005 16:28
Dateianhang: specAna.zip (21,9 KB, 374 Downloads)

Hier meine aktuelle Software. Ich hab mich bemüht die Software fürs LCD
halbwegs zu kommentieren :)
Mein LCD hat ein KS0108 Chipset und ich verwende zwar meine Lib, es
sollte aber dennoch nicht schwer sein ein anderes einzubinden, da ich
sämtliche Daten direkt ans Display sende, alles andere ist zu langsam.
Autor: Benedikt (Gast)
Datum: 20.01.2005 16:35

@ape
Danke, werde ich mir mal anschauen und auf T6963 bzw. OLED
umschreiben...

@Paul
>Wenn ich zb. einen 32 Band spectrum analyzer nehme und über ein
>sinussignalgenerator alle frequenzen gleichmäßig durchlaufen lass,
>laufen die frequenzen gleichmäßig über das display drüber?

Ja, schau dir mal die beiden Videos ganz oben an, da wird genau das
gemacht.

Mit LEDs will ich es auch machen: 32Bänder, zu je 16LEDs.
Das ganze kann man natürlich auch analog machen, das sieht dann so aus
und kostet eine Kleinigkeit mehr (irgendwo im Anhang sind ein paar
schöne Fotos von Matthias Asselborn):
http://www.mikrocontroller.net/forum/read-1-31511.html
Autor: Paul (Gast)
Datum: 20.01.2005 16:39

ok dann ist ja wunderbar :) geht das mit einem einzelnen AVR? Der AVR
hat nur 8 Ausgänge wie splittest du die auf 32? und vor allem wie
steuerst du die jeweils 16 LED's an? LED-Treiber? Das wäre ja fast der
gleiche aufwand wie beim analogen :S

so ein Spectrum analyzer muss im Partykeller der Hit sein :)

mfg Paul
Autor: ape (Gast)
Datum: 20.01.2005 16:52

oh ich seh gerade noch nen kleinen Bug, der oben definte Wert PEAK_SPEED
wird gar nicht verwendet. Der muss in Zeile 88 an Stelle der beiden 6
eingefügt werden.
Autor: Benedikt (Gast)
Datum: 20.01.2005 16:52

Ich steuere die 32x16=512 LEDs im Multiplex mit einem zweiten uC an (1.
uC macht die FFT, der zweite die Displaysteuerung.)
Die 16 Zeilen steuere ich mit zwei 8bit Schieberegistern und 16
Transistoren, die Zeilen mit zwei 4 zu 16 Dekoder und 32 MOSFETs.
Insgesamt also 2 uC und 4 CMOS ICs neben ein paar Transistoren, MOSFETs
usw.
Und wenn du diese Schaltung mit der analogen vergleichst, erkennst du,
dass die mit uC viel einfacher ist...

Allerdings ist die Schaltung noch nicht fertig, im Moment verwende ich
noch 16x10 LEDs um schonmal die Schaltung testen zu können.
Autor: ape (Gast)
Datum: 20.01.2005 17:02

Noch nen Bug :P
In Zeile 115 muss ein <= an Stelle eines < hin
es muss heißen:

if(j <= peak[i] && peak[i]-j < 8) {

Sonst verschwinden die Peak-Werte alle 8 Pixel kurz
Autor: philip (Gast)
Datum: 21.01.2005 15:15

könntet ihr einen kompletten schalt plan für 16x64 leds machen also
64band, a 16LEds ?

so das man das ganze relativ einfach zusammen bauen kann ?


gruß philip
Autor: Matthias Asselborn (Gast)
Datum: 21.01.2005 16:55

n 12x28 oder 32 würde ja auch schon reichen
aber das lässt sich ja variieren
Autor: ape (Gast)
Datum: 21.01.2005 18:25

So hab jetzt die Kommunikation auf TWI umgestellt. Das Ergebnis der
letzten FFT kann jeder Zeit ausglesen werden, allerdings kann es
vorkommen, das während des Auslesen die nächste FFT fertig ist und dann
die erste Hälfte des ausgelesenen Spektrums von der letzten FFT stammt
und die zweite von der aktuellen, aber das fällt auch nicht weiter
auf.
Die Übertraung der 64 Spektrum-Werte dauert bei vollem TWI-Speed
(immerhin 512kHz bei 18,432MHz) gerade mal 1,3ms.
Dadurch das die Übertragung per UART wegfällt (die TWI-Übertragung
läuft im Gegensatz zu der Übertragung via UART interrupt-gesteuert im
Hintergrund ab) schafft der FFT-AVR jetzt knapp 85 Berechnungen pro
Sekunde und das auch nur, weil er warten muss bis der Sampling-Buffer
neu gefüllt ist, mit höherer Sampling-Rate wäre noch mehr drin.
Last but not least, macht das Display jetzt knapp über 70fps, da die
Übermittlung des Spektrums schneller von statten geht und die Wartezeit
bis zur nächsten Übertragung wegfällt.

@philip:
16x64 LEDs, das wären ja 1024 Stück...
viel Spaß beim "einfach zusammen bauen", von den Kosten und der
Stromaufnahme mal ganz zu schweigen :)
Autor: philip (Gast)
Datum: 21.01.2005 21:02

hehe ja das habe ich auch grade gesehen... ^^ ups ja 64 kanal bekomme
ich net unter lach...

nein 12x32... oder 16x32... werde ich bauen das ist noch machbar...
strom verorgung währ kein problem ^^ ich werde vermutlich ein kelineres
PC netzteil verbauen.. habe noch eins ohne lüfter....
das ist schön leise und liefert genug :)

jetzt muss ich nur drauf warten das einer schalt pläne macht,
damit ich alles ätzen lassen kann :)