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...
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.
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.
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.
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?
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.
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.
@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
@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.
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.
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...
g Ja is sehr komplex das ganze... werd mal versuchen mit einem fertigen Quellcode was anzufangen...
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.
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.
Hi Hamming-Fenster berechnet sich ganz simpel nach http://www.uni-regensburg.de/Fakultaeten/nat_Fak_IV/Physikalische_Chemie/Schmeer/PDF_Files/DSP06.pdf Seite 14. Matthias
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
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
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...
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
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.
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 :)
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.
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
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.
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
@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.
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.
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.
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.
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.
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
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.
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
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.
@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.
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
ah wie ich sehe ist nun aus der digitalen Spec Analyzer Variante nun doch was geworden g
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.
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?
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.
@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.
habe 2mA led s verwendet vom reichelt platinen in bulgarien ätzen lassen ! habe aber daheim auch noch samsung led dot matrix displays 3 farbig...
sendest du mir bitte mal einen schaltplan deiner version mit µC das würde mich nun brennend interessieren ! bzw layouts oder codes ?
@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.
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
@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.
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.
@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.
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
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.
@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
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
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.
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.
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
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
n 12x28 oder 32 würde ja auch schon reichen aber das lässt sich ja variieren
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 :)
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 :)
Für die LEDs empfehle ich so vielfachLEDfassungen da man die LEDs sonst schwierig exakt gerade in eine reihe bekommt.
ach ja ich poste anbei mal Fotos @ Steuerung , Display ! Frontplatte usw...
So sitz jetzt gerade an der 256 Punkte Version... Den Zähler in der adc_isr habe ich bereits umgebaut, der in do_window ist auch kein Problem, in do_fft und make_bars wird immer nur FFT_N/2 geladen, das ist also eigentlich auch kein Problem. Dennoch funktioniert das ganze nicht. Ich vermute das das u (bzw. XH) in do_fft der Übeltäter ist und im Verlauf der Schleifen bis FFT_N zählt. Da wird die Sache dann aber wirklich gemein, da mit XH auch multipliziert wird und ich nicht weiß wie man in asm eine Multiplikation mit einem 16-bit Wert realisiert. Hat da jemand nen Tipp? Im Anhang mal mein momentaner Code.
mul AL,XH ; T10L = u*4 Wenn der Kommentar " u*4 " stimmt, kann man diese Multiplikation mit zwei Shifts ersetzen (immer noch schneller als eine 16x16 Bit Multiplikation). Um mit einem 8-Bitter eine 16Bit-Multiplikation auszuführen, muß man (um den Hardware-Mul-Befehl nutzen zu können) die Faktoren in Summen zerlegen, einzeln multiplizieren und dann wieder zusammensetzen. Dann kommen aber 4 Mul-Befehle zusammen, nebst einigen 32-Bit - Additionen. Wenn man den Wertebereich des Ergebnisses auf 16 Bit begrenzen könnte, würde es einfacher werden. Ob das 100% ig richtig ist, müßte ich aber erst mal nachlesen, ich habe irgendwo ein Buch herumliegen, in dem der Algorithmus drinnen ist - aus dem Kopf weiß ich ihn momentan nicht.
mhmm wenn ich mir das nochmal genauer angucke is mir da sganze eh ein ziemliches Rätsel wo kommt überhaupt das AL her, das wird in dieser Routine vorher gar nich initialisiert und dann multipliziert er einfach damit... Naja ich denke ich werds dann jetzt doch erstmal bei den 128 Punkten belassen und mal den von Benedikt vorgeschlagenen Weg mit 2 FFTs ausprobieren, einer hochauflösenden für den unteren Bereich und einer gröberen für die hohen Frequenzen.
D.h. du sampelst mit 22Khz den Inputbuffer voll. Die hochauflösende 128 FFT geht über diesen Buffer. Die niedrig auflössende FFT geht dann zB. über 4 solcher Buffers, wobei aber immer 4 Samples zu einem Sample zusammengefasst wurden. Die effektive Samplingrate wäre dann 22Khz/4=5.5Khz mit 128 Punkten FFT. Der ADC sampled nur einen Kanal mit 22KHz. Pro 4 hochauflösende FFT's fällt eine niedrig auflösende FFT an. Oder wie möchtest du das machen ? Gruß Hagen
Meine Idee ging anderst: Wenn man einfach mit einer niedrigeren Samplerate aufzeichnet bekommt man Störungen, da das Eingangssignal auf halbe Samplerate begrenzt sein muss, daher war in der Orginalschaltung auch ein steiler Switched Capacitor Tiefpass mit einem MAX292 eingebaut. Um mit zwei unterschiedlichen Samplerates aufzuzeichnen muss man auch die MAX292 Taktfrequenz verändern. An sich kein Problem, aber wo bekommt man das IC zu bezahlbaren Preisen ?
warum baut ihr das ganze nicht einfach mit mehreren avrs auf ? ist doch viel einfacher... ein paar avrs um das signal zu verarbeiten (FFT) und dann einen avr der das ganze dann zusammen fast... auf 1-2 avrs kommt es mit sicherheit nicht an...
Ziemlich genau so hatte ich mir das vorgestellt. Ich nehme 2 Sample-Buffer. Im 1. Buffer landet jeder ADC Wert, im 2. nur jeder 4. Wenn der erste buffer voll ist startet die erste (loRes) FFT. Danach hatte ich ursprünglich vor einfach zu warten, bis der zweite voll ist, aber es is natürlich sinnvoller die Zeit mit was nützlichem zu verbringen und die loRes FFT upzudaten. Obwohl der Controller nicht alle 4 schaffen dürfte, aber 2 Durchgänge sollten schon drin sein. Wenn der zweite Buffer dann jedenfalls voll ist wird die hiRes FFT berechnet und danach gehts wieder von vorne los. Die hiRes FFT hätte dann jedenfalls einen Frequenzbereich von 0-2,75kHz in 43Hz Schritten. Bei der loRes würden die Werte bis 11kHz in 172Hz Schritten gehen.
Die AVRs sind nicht das Problem, sondern der Tiefpassfilter, der ausreichend steil sein muss. Mit einem RC, bzw. LC Tiefpass kommt man leider nicht sehr weit. Auf dem oberen Video sieht man gut, dass der Balken beim Sinuston bis ganz nach rechts läuft, und dann wieder ein Stück zuück bis er verschwindet. Bei einem RC Tiefpass läuft der Balken 5-6 mal hin und her, bis er annähernd verschwunden ist.
@Ape: ok, das Vorgehen halte ich für die beste Lösung. Du sampelst mit 22Khz jeweils 128 Samples in den Buffer der schnellen FFT und führst diese wie bisher aus. Zusätzlich werden jeweils 4 succesive Samples in einer Variablen addiert und dann durch 4 geteilt. Dieser Wert landet in einem zweiten 128 Samples Buffer. Wenn der voll ist sind 4 schnelle FFT's vergangen und nun folgt noch eine 128 Punkte FFT zusätzlich. Du benötigst also 25% mehr Rechenzeit relativ zu deinem jetzigen Code. Dafür nichts mit zusätzlicher Hardware oder erhöhtem ADC Aufwand. Du könntest natürlich auch jweils 5, 6 usw. Samples zusammenfassen und somit nur 1/5'tel oder 1/6'tel mehr Rechenzeit verbrauchen. Ich würde aber 2,4 oder 8 Samples vorschlagen da sich damit besser der Duchschnitt berechnen liese. Alternativ könnte man auch die jeweils 4'te, 5'te usw. schnelle FFT ausfallen lassen und statt dessen die FFT über den zweiten Buffer berechnen. Das dürfte bei deinen jetzigen 70 fps nicht sehr auffallen. Und gerade die tieferen Frequenzen folgen eher einem langsammeren Rhythmus. Somit würde sich an der Performance garnichts ändern. Gruß Hagen
Ja stimmt der Tiefpass ist in der Tat nen Problem. Man kann nen 8th Order Tiefpass auch diskret mit 4 Ops aufbauen, aber da ist dann halt die Trenn-Frequenz nicht einstellbar. Im übrigen würde ich die Verwendung mehrerer AVRs zum Berechnen gerne vermeiden, obwohl es durch die Kommunikation über TWI sehr leicht zu realisieren wäre.
@Hagen: Ist eine Mittelwert-Bildung der letzten 4 Werte für den langsamen Buffer wirklich nötig? Wenn ich den AD-Wandler Speed runterdrehen würde würde ich auch immer nur den momentanen Wert erhalten. Oder lassen sich durch die Mittelwertbildung die störenden Auswirkungen der höheren Frequenzen verringern?
So langsam bin ich irritiert :D Matthias Asselborn, wie hast du den eine so schöne Front herbeigezaubert? ;) Btw: ich versteh die LED ansteuerung noch nicht wie man so viele LEDs mit nur so einer kleinen Leiste ansteuern kann. Ausserdem wie bekommst du es hin dein Frequenzspektrum so genau aufzuteilen? Du hast da ja sehr viele Frequenzen mit verschiedenem abstand zueinander. Bei meinem wissensstand wird das wohl leider nie was :-/ mfg Paul
@Ape Die von dir vorgeschlagene Methode, nur jeden 4. Wert zu nehmen funktioniert wegen dem fehlen Tiefpass nicht, da dies nur Undersampling aber kein richtiger Tiefpass ist. Man müsste daher aus den gesampleten Werten über einen Software Tiefpass mit etwa 1-2kHz nur die tiefen Frequenz rausfiltern, aber ich bin mir nicht sicher ob das nicht mehr Rechenleistung benötigt als die eigentliche FFT. Eine andere Lösung wären die zwei getrennte Opamp Tiefpässe (einer mit 10kHz für die normale FFT mit 20kS/s und ein zweiter Tiefpass mit 1kHz der an einem anderen ADC angeschlossen wird für die FFT mit etwa 2,5kS/s. Das ergäbe dann eine Auflösung von 10Hz im Bereich <500Hz !
gewusst wie :-) ich warte allerdings nur noch auf den source einer fft selber bin ich gerade beim thema furier analyse evtl klärt sich dann was auf die funktions weise usw...
@Matthias Asselborn Ich vermute mal du hast analoge Filter verwendet. Irgendein AVR digitalisiert die Werte und steuert die LEDs im Multiplex an ?
die Mittelwertbildung ist unbedingt nötig ansonsten reduziert sich nicht die Samplingfrequenz. Der Trick den du anwenden willst basiert ja auf der Reduzierung der Samplingfrequenz. 22Khz Samplingfrequenz -> 11Khz / 128 = 86 Hz Bandbreite pro Schritt, Grenzfrequenz 11Khz. Reduzierung 22Kz/4 -> 2.75Khz / 128 = 21Hz Bandbreite pro Schritt, Grenzfrequenz 2.75Khz. Die ersten 32 Samples mit 11Khz werden durch die 128 Samples mit 2.75Khz überdeckt. Dein Display würde also 128 Samples mit 21Hz Bandbreite plus 96 mit 81Hz Bandreite anzeigen -> 224 Samples. Die ersten 128 Samples zeigen die tiefen Frequenzen bis 2750Hz, die nachfolgenden 96 Samples zeigen die Frequenzen zwischen 2750-11000Hz. Die Mittelwertbildung ist nicht die beste Methode aber die einfachste. Wenn du mit einem ADC bei 22Khz samplest so arbeitet er pro Sample wie ein Buffer der 1/22000 Sekunde den Analogwert buffert. Wenn du mit 5.5Khz sampelst so hält der ADC für 1/5500 Sekunde den analogen Wert. Da die meisten ADC per succesiver Approximation arbeiten und so einen Buffer benötigen verhält sich das wie eine Mittelwertbildung über den Zeitbereich eines Samples. Bei der Mittelwertbildung passwiert doch folgendes: Stelle dir mal 11Khz bei 22Khz Sampling vor. Wir haben dann Werte im Buffer wie 0,+127,0,-127, eben 11Khz. Nun bilden wir den Mittelwert zu einem virtuellem Downsampling von 22Khz/4 = 5.5Khz. Sprich bilden den Mittelwert von obigen 4 Werten -> 0 + 127 + 0 + -127 == 0 ! Eine 11Khz Frequenz virtuell down-sampled auf 1/4 würde Samples aus lauter Nullen ergeben -> ergo die 11Khz sind rausgefiltert worden. Soweit habe ich das zumindestens verstanden :) In deinem Falle stellt das ja kein großer Aufwand dar. Probiers doch einfach :) Gruß Hagen
Jup das werd ich... Hab übrigens gerade 2 MAX297 bekommen. Direkt bei Maxim als Muster bestellt, da ich sie sonst wirklich nirgendsow gefunden habe. Ich hab den 297 genommen weil der nur die halbe Frequenz benötigt.
@Hagen: Du musst deine Werte alle durch 2 teilen, da ja bei einer FFT immer nur halb so viele Werte rauskommen wie man reinsteckt, in diesem Falle also 64 ;) Habe jetzt jedenfalls 2 FFTs nach obigem Schema laufen. Auf dem Display werden alle 64 Werte der hochauflösenden FFT und die letzten 48 Werte der zweiten FFT dargestellt (der Frequenzbereich der ersten 16 Werte wwird ja von der ersten FFT abgedeckt). Das Ergebnis ist aber eher mäßig. Am meisten stören die hohen Frequenzen bei der hiRes FFT. Diese werden zwar durch die Mittelwertbildung gedämpft, aber sind halt trotzdem noch sehr deutlich zu sehen. Bei Musik fällts nicht so auf, aber wenn man einen Ton "durchs Spektrum laufen lässt", sieht man es doch sehr deutlich. Ich denke ich werde da noch mal probieren die FFTs nacheinander zu machen und die Trennfrequenz des MAX297 zu verändern. Außerdem stört mich noch der sehr abrupte Übergang von hochauflösend zu niedrig auflösend, neben den unterschiedlichen Frequenzschritten sind auch die Amplituden der Balken etwa sunterschiedlich, wodurch sich eine kleine Stufe im Spektrum ergibt. Auf jeden Fall ist aber die Auflösung im niedrigen Frequenz-Bereich verdammt hoch, das würde ich schon gerne beibehalten. Dennoch würde eine 256 Punkte FFT ein viel schöneres Bild liefern :) PS: Der Maxim-Stein is schon echt gut, aber leider rauscht er ganz schön, ich weiß nich ob ich was falsch gemacht habe (soviel gibs da ja nich was man falsch amchen könnte), aber die im Datenblatt angegebenen 77dB SNR erreicht meiner mit Sicherheit nicht.
@Benedikt ja so ist es aber wenn nun die fft schon mal funktioniert lässt sich das ganze schnell umbauen !
>Am meisten stören die hohen Frequenzen bei der hiRes FFT. Diese >werden zwar durch die Mittelwertbildung gedämpft, aber sind halt >trotzdem noch sehr deutlich zu sehen. Bei einer 256 Punkte FFT wird das besser, allerdings steigt eben auch der rechnerische Aufwand. Das Problem ist das "downsampling", du reduzierst ja von 22Khz auf 22/4Khz. Wenn du zb. mit 22/4Khz samplest würdest du die gleichen Effekte bei hohen Frequenzen sehen. Bei zb. 11Khz Messfrequenz hat das Downsamlping die fast gleichen Effekte wie ein direktes Sampling mit 22/4Khz. Man kann dies verbessern wenn man statt dem Mittelwert über die 4 Samples eine Interpolation des Mittelwertes über zB. 12 Samples macht. Dabei versucht man also den genaueren zeitlich bezogenen Sample-Wert zu bestimmen. Ein anderer einfacher Trick wäre die Nulldurchgangssynchronisation. Man verschiebt also die 4 Samples um +-3 Samples im Buffer, aber so daß deren erster Durchschnittswert +-0 ergibt. Man synchronisiert also das Downsamling realtiv zu Inputmeßfrequenz. Das würde das Messen einer einzelnen Frequenz verbessern, aber nicht bei einem Frequenzgemisch wie bei Musik. Dein jetziges Verfahren hat also den entscheidenen Vorteil das es schneller als eine 256 Punkte FFT bei 22Khz ist. Im Vergleich benötigt es Sqrt(256 Punkte FFT) * 1.25 an Zeit zu einer vollständigen 256 Punkte FFT. Wenn also 2ms pro 128 FFT = 5*2 = 10ms für einen Duchlauf benötigt wird dann benötigt eine 256 FFT 16 ms. Gruß Hagen
Mhmm, also die Variante mit den beiden Sampling-Frequenzen nacheinander scheint besser zu funktionieren. Im Anhang mal meine aktuelle Version Echt erstaunlich wie schnell der MAX297 auf ein umschalten der Steuerfrequenz reagiert. Einziger Nachteil ist das die niedirg auflösende FFT nun "nur noch" genauso oft berechnet wird wie die hochauflösende. Beide werden jetzt etwas mehr als 30mal pro Sekunde berechnet. Das einzige was mich noch stört ist, dass der AVR 15ms pro Durchgang (ungefähr die Hälfte der Zeit!) damit verbringt auf das Füllen des "langsamen" Buffers zu warten. Ein Teil der Zeit lässt sich dazu verwenden die beiden Ergebnisbuffer zusammenzurechnen (mit pseudo logarithmischem Maßstab), aber danach wird immer noch ne ganze Menge übrig sein. Das rauschen des Tiefpasses hab ich auch etwas vermindert, in dem ich vorm Tiefpass die Amplitude des Signals mit dem integrierten OpAmp verdopple und hinterher wieder mit 2 Widerständen halbiere.
@Tiefpass: Für einen C64-Emulator habe ich den Tiefpass etwa so realisiert (hier ohne Resonanz): Diff:=Sample-TPass; TPass:=TPass+Diff*Faktor; Der Faktor sollte sich im Intervall [0,0;1,0] bewegen, wobei 0,0 alles wegfiltern würde und 1,0 gar nichts.
in welchem preisbereich würde sich ein zb. 10x10 Spec mit einem AVR bewegen? Und wie viel Khz sind schon möglich?
@Paul: Wie oft denn noch: Die Frequenz ist nicht das Problem, mit einem externen ADC sind über 1MHz möglich. Um was es hier geht: Die Auflösung von diesem Frequenzbereich zu vergrößeren, da der Bereich im Moment in 64 Teile zerlegt wird. Der Preis, kommt darauf an wie du das anzeigen willst. Ich sag mal mega8 + Anzeige, das können 10 sein, aber auch 1000 wenn du die Anzeige gerne 10x10m groß hättest...
Bin jetzt so einigermaßen fertig (mit dem Ding und den Nerven) :) Während der AVR auf das Füllen des langsamen Buffers wartet fasse ich die Ergebnisse der beiden FFTs zu einem zusammen. Das resultierende Spektrum hat dann 78 Werte. Alle 3 Spektren werden ca. 30 mal pro Sekunde refreshed. Außerdem habe ich auch die Berechnung der Peakwerte in den FFT AVR verlagert. Das Übertragen der Werte über TWI dauert zwar vermutlich länger als wenn ich sie direkt in der Anzeige-Routine berechnen würde, aber es sparrt Speicher im AVR der das Display managed. Dafür benötigt der FFT AVR aber neben den Buffern für die Peaks und ihre Geschwindigkeiten auch noch temporäre Level-Buffer. Es würde zwar auch ohne gehen, aber dann müsste das ganze direkt im Anschluss an die jeweilige FFT geschehen und könnte nicht bis zu dem Zeitpunkt warten, wo der AVR auf das Füllen des Sample Buffers wartet. Wie auch immer es ist jedenfalls immer noch jede Menge SRAM übrig. Den Sourcecode gibs, wenn ich den TWI Kram noch etwas verbessert habe, man kann noch nicht auswählen, welches Spektrum man nun bekommen möchte... Hab mal nen kleines Video gemacht. Sorry wegen der miesen Qualität und dem leisen Ton, aber mehr gibt meine Digicam nich her, außerdem möchte ich ja nicht von der Musikindustrie verklagt werdenn :) http://www.apetech.de/download/test.avi
Nicht schlecht... Vielleicht klaue ich mir den Code für mein Projekt, aber erst muss ich mal das 32x16 LED Array bauen und mir ein paar MAX 29x besorgen..
könnte einer fürn 32x16 oder 32x12 oder ovn mir aus auch nur 28x12 oder 28x16 LEDs einen schalt plan machen ?
@Matthias: Wie gesagt noch nen bissel Feinschliff dann gibs die neue Version. Du kannst auch den letzten Code nehmen da musst du dann nur selber die Werte zusammenrechnen... @philip: ich nehm 20 pro Stunde, dann können wa nochma drüber reden. Mal ernsthaft: meinst du nich das die Leute hier nichts anderes zu tun haben als dir nen Display nach deinen Wünschen zu entwickeln?
@ape was meinst du mir Feinschliff ? mal eine grundlegende Frage habe ja den Thread mal vor einem Jahren aktiv mitverfolgt nun meine 1. frage auf welcher hardware bassiert denn der spec ? einem Atmel bzw einem externen digital analog Wandler ? reicht nun die Geschwindigkeit die ein Atmel hat bzw die Genauigkeit eines AD wandlers ! wie genau und welche Displays steuerst du an ist der Code in C ? das wäre super denn das beherrsche ich ! Gruß Matthias
mhmm also schon, obwohls ein von vorn durchlesen des Threads auch tun würde ;) Das ganze basiert auf einem mega32, der 2 128 Punkte FFTs durchführt. Die erste mit 5,5kHz Sampling-Frequenz, die zweite mit 22kHz. Die erste liefert ein recht hochaufgelöstes Spektrum des unteren Frequenzbandes (64 Werte; von 0 bis 2,75kHz in 43Hz Schritten), die zweite FFT erzeugt ein wesentlich gröberes Spektrum, das dafür aber bis 11kHz reicht (wieder 64 Werte; von 0 bis 11kHz in 170Hz Schritten). Die beiden Spektren werden dann zu einem dritten zusammengerechnet um ein möglichst breitbandiges Spektrum mit einer vernünftigen Auflösung im unteren Frequenzbereich zu erhalten. Bei der Zusammenfassung der beiden Spektren, werden die 22 ersten Werte des ersten Spektrums direkt kopiert, aus den folgenden 42 Werten wird der größere Wert aus je zweien kopiert. Danach werden wieder 22 Werte aus dem zweiten Spektrum direkt kopiert und von den verbliebenen jewils der größere aus zweien, wobei aber erst beim 16. Wert begonnen wird, da der Bereich davor bereits vom ersten Spektrum abgedeckt wurde. Das resultierende Spektrum sieht dann also ungefähr so aus: Werte 0-21: 0-946Hz; Werte 22-42: 946-2,75kHz; Werte 43-65: 2,75-6,5Hz; Werte 66-78: 6,5-11kHz. Ich hoffe das war jetzt einigermaßen nachvollziehbar :) Diese etwas umständliche Methode hat jedenfalls den Vorteil, dass sie mit 128 Punkte FFTs auskommt. Problem bei der Sache ist aber das während der hochauflösenden FFT keine Frequenzen über 2,75kHz am AD-Wandler liegen dürfen. Daher ist noch ein einstellbarer Tiefpassfilter (z.B. MAX297) notwendig, dessen Trennfrequenz man immer zwischen 2,75 und 11kHz umschaltet. Eine Alternative wäre für jede FFT einen eigenen AD-Wandler Kanal zu verwenden und dann die Tiefpassfilter diskret mit fester Trennfrequenz aufzubauen, diese sollten dann aber auch 8ter Ordnung sein. Zum AD-Wandeln wird jedenfalls der interne ADC verwendet, die Auflösung ist mehr als ausreichend. Ich ziehe von den resultierenden Spektrumwerten sogar immer noch 1 ab, damit das rauschen des MAX297 nicht mehr zu sehen ist. Die drei Spektren werden jedenfalls rund 30 mal pro Sekunde berechnet und lassen sich gemeinsam mit den Peakwerten zu jedem beliebigen Zeitpunkt über das TWI Interface auslesen. Das Video oben zeigt das zusammengefasste Spektrum. Der FFT-Code ist vollständig in Assembler geschrieben. Eine vergleichbare FFT in C ist um Größenordnungen langsamer. Das Auslesen des AVRs über das TWI-Interface und die Ausgabe auf dem Display (128x64 Pixel; KS0108 Chipset) sind aber in C geschrieben. Wie auch immer, für ein Spektrum-Analyzer wie du ihn deinen Fotos nach im Sinn hast wird das ganze wahrscheinlich nicht wirklich brauchbar sein, da das Spektrum halt keinen richtigen logarithmischen Maßstab hat. Als optische Spielerei in einem Verstärker oder auch mit LED-Display an der Wand ist das ganze aber mehr als ausreichend. So ich hoffe damit sind die meisten Fragen beantwortet ich geh jetzt schlafen. Den Sourcecode gibts wenn die Ansteuerung über das TWI-Interface fertig ist -> Schätzungsweise morgen.
So fertig. Jedenfalls erstmal. Im Anhang befinden sich der Quellcode für den FFT AVR, sowie eine kleine C-Library um mit dem Ganzen übers TWI zu kommunizieren und ein kleines Demo Prog, das das zusammengefasste Spektrum auf einem KS0108 LCD ausgibt. Falls jemand Bugs findet immer her damit habs noch nicht sonderlich ausgiebig getestet.
Ist in der ks0108.h defined. Im Moment hängen die 8 Datenlaitungen an PORTC, die steuerpins wie folgt: D/I: PC0 R/W: PC1 EN: PC2 CS1: PC3 CS2: PC4 Das Testprogramm ist fürn mega128, müsste aber auch auf jedem anderen mega laufen, muss man halt nur das makefile anpassen und rebuilden. Ich hab übrigens beim Schaltplan für den FFT AVR den Programmier- und den TWI-Stecker vergessen, aber das sollte ja wohl jeder hinbekommen :) Die TWI-Pullups nicht zu groß wählen, da der Bus mit recht hoher Geschwindigkeit läuft. 3k3 funktionieren bei mir wunderbar.
gingen 10 er auch ? di hab ich grad noc rumfahren aber ich beende für heute evtl morgen abend andere besorgen
10er? es sollte jedenfalls alles vom mega8 an gehen. muss halt nur genug pins für das LCD und ne TWI Schnittstelle haben
ah ok :) fürs TWI? naja probieren kost nichts aber ich schätze die sind zu groß
Man kommt übrigens auch ohne die negative Versorgungsspannung am MAX29x aus. Dafür grounded man V- und legt den GND-Pin über einen Spannungsteiler aus 2 10k Widerständen auf VCC/2. Die Konstruktion mit dem OpAmp um die Amplitude zu erhöhen funktioniert dann zwar nicht mehr ist aber auch gar nicht mehr nötig, da er mit der niedrigeren Spannung weniger rauscht (vielleicht war auch einfach nur meine negative Spannung nicht ganz sauber)
ich habe mal eine frage ! der eigentliche fft ist doch in assembler ? das display dann in c oder verstehe ich da was falsch ?
ja aber FFT und Display laufen ja auch auf 2 verschiedenen AVRs also ist das ja auch gar kein Problem. Wenn man sich die Mühe machen würde die FFT in asm Library umzubauen könnte man das auch direkt in einem C Programm verwenden.
gut das ist mir bewusst also lasse ich den atmega 32 auf jedenfall bestehen und ändere nur den c source um ! auf led s ! ja bald sind ferien da hab ich aber auch nicht wirklich zeit anfang studium !
dumme frage, aber könnte einer mal ne ganze einfache rutine in c posten, mit der man eine frequenz auf LEDs ausgeben kann ? damit ich mir mal ein bild machen kann, und es dann erweitern kann... komme so nicht gnaz klar... währ net wenn hier einer mal was posten würde was er schon hinbekommen hat.... gruß philip
ich habe mal ein VU meter geproggt aber das mit nur EINER frequenz wird schwierig weil man die gesamte fft auseinandernehmen müsste bzw funktionierend wie ein bandpass proggen ich habe nun zwar eine woche ferien aber nicht die zeit die fft auf diverse frequenzen aufzuspalten ! wobei ich mir erst mal intensiv den code anguggen müsste
funzn das mit einer frequent scho gut ? wenn ja schicks mir doch bitte einfach per icq weisst ja wo du mich findest ;)
@philip Willst du ein VU Meter ? Oder warum brauchst du die Anzeige einer Frequenz ? PS: Bald gibt es ein paar Fotos von meinem 32x16 Spektrum Analyser. Die Software ist schon fertig, die Ansteuerung auch, ich warte nur noch auf die Lochrasterplatinen von Reichelt für die LED Matrix: gestern kam die Email: voraussichtlicht ab 25.02.05 lieferbar...
apropos hätte ich noch 16x16 er matritzen ( inkl widerstände und transistoren) alles auf der platine günstig abzugeben ! da ich sie nicht mehr benötige !
>apropos hätte ich noch 16x16 er matritzen ( inkl widerstände und >transistoren) alles auf der platine günstig abzugeben ! da ich sie >nicht mehr benötige ! Hättest du das gesagt, bevor ich mir die 512 LEDs bestellt hätte, wärst du das Ding jetzt warscheinlich los. Vermutlich kommen die LEDs heute, dann kann ich die LED Matrix aufbauen. Diese verhält sich wie ein primitves LCD mit zwei Befehlen: Daten übertragen und Adresszähler resetten. Immerhin ist das Display grafikfähig. Einen wirklichen Plan habe ich noch nicht, kommt aber noch wenn alles läuft. 1/32 Mux ist zu viel, das wird zu dunkel. Daher fahre ich einen 2x 1/16 Mux, d.h. Spalte 1 und 17 sind gleichzeitig an, Zeile 2 und 18 usw. Die 2x 16 Zeilensignale erzeuge ich über 4094 Schieberegister und Konstantstromquellen die je ca. 150mA liefern. Damit kommer ich auf rund 9mA mittleren Strom pro LED. Insgesamt zieht die Schaltung rund 5A wenn alle LEDs an sind. Die Spalten werden über P Kanal MOSFETs geschaltet, angesteuert von einem 4 zu 16 Dekoder. Ein NE555 arbeitet als Impulsausfalldetektor und schaltet nach 5ms ohne Impulse die Ausgangstreiber ab (falls der uC abstürzt geht die gerade aktive LED Spalte bei 150mA sonst schnell in Rauch auf...)
da hätten dann 2 module gereicht... meinem 1. analyzer baute ich auch mit 2 mux auf nur der atmel schaltete .... kein ne555 ja wenn du weiter kommst bitte ich dich mal um einen schaltplan ! wenn sich das machen lässt !
Ich hab mal nochmal nach Filtern geguckt. Es gibt auch von anderen Herstellern Switched Capacitor Filter aber ich hab keine weiteren 8. Ordnung gefunden. Von TI gibts den TLC04. Dieser ist 4. Ordnung und man kann ihn bei Farnell kaufen (Als Student auch in geringen Stückzahlen :)) Und wenn 4th Order nicht reicht könnte man notfalls ja einfach zwei Filter hintereinander hängen.
nein ich brauche nur ein reines UV !! ich brauche nen eagel plan + code für nen atmel mega, das ganze brauche ich zusetzlich fürn kleines neben projekt, ich wills über avr machen, da die ganzen ics dafür mist sind..
Nach 5 Stunden Arbeit (ich hasse LEDs, es ist echt eine Scheißarbeit 512 LEDs anzulöten, die Drähte unterschiedlich lang zu kürzen und die Zeilen und Spalten zu verdrahten) ist ein Teil der LED Anzeige fertig. Leider fehlt mir eine Platine um alles fertig zu bauen (hoffentlich geht das diesmal schneller als beim VS1011: Das war der absolute Negativ Rekord von Reichelt: Über 4 Monate Lieferzeit !). Daher ist nur eine 16x16 Matrixhälfte verdrahtet. @philip http://mitglied.lycos.de/bk4/AVRvu.htm
Hier noch ein kleiner Test: Da ich noch irgendeinen Fehler im Code habe, kann ich im Moment nur die obere Hälfte anzeigen lassen (ca. 2-10kHz) Leider setzt in diesem Bereich auch der Tiefpass der Kamera ein, ich denke man sieht aber deutlich, dass es funktioniert und wirklich gut aussieht (im Vergleich zu einem LCD)
@ komplettes VU ich habe wie gesagt eines in C programmiert ausgerichtet auf einen AT MEGA 8535 filter habe ich mich schon viel umgesehen die für einen studenten auch bezahlbar sind es gab da mal ganz früher 4 fach filter pro ic marke weis ich nicht mehr ich glaube aber von AD wobei das stück 10 euro gekostet hätte.... also von daher lieber selbst einen zusammen bauen @Benedikt dürfte ich dann deinen Code und Plan wenn er fertig ist betrachten ?
das eine UV von der seite ist igenau was ich suche, nur leider ist die softwar net offen, ich sehe dort nur ne hex, keine c oder asm oder bas datei... :( ich hätte gerne was offenen, um es ein wenig umbauen zu können, und ich brauche ein paar mehr kanäle... naja kann ja mehrere avrs nehmen habe 3 mega.. hier liegen...
yo müsste mein raid mobilisieren denn da liegt der code drauf ich habe ja nun ferien da mach ich das mal ! da prinzip beruht auf ablesen des ADC s umrechnen und ausgeben ! in genauen dezibel werten ! wie seiht das mit den db aus bei deinem @Benedikt ??
@benedikt: schick schick aber mir gefällt die LCD Optik besser, nich so aufdringlich :P naja über Geschmack lässt sich ja nich streiten. Hab auch nochmal nen kleines Video über den Frequenzgang gemacht. Diesmal sogar mit Ton, aber leider nach wie vor mieser Bildqualität :/ In der Mitte sieht man den Übergang der beiden FFTs. http://www.apetech.de/download/test.avi Daher im Anhang auch nochmal nen Foto wies mit hoher Auflösung aussieht (Das ganze ist jetzt in meinem Verstärker integriert)
Hallo Benedikt hast du irgendeine Scalierung bei den Led s nach Db ? oder lässt sich die nachträglich programmieren ?
Meinst du bei dem VU Meter ? Ist eigentlich egal, beim Spektrum Analyser ist es genau dasselbe. Ich messe das Signal mit 10bit, mache eine Gleichrichtung und bestimme den Spitzenwert, der verdoppelt wird. Das ergibt einen Bereich von 0-1023. Daraus wird die Wurzel gezogen, was 0-31 ergibt, genau passend für die LEDs. Es ist also eine pseudologarithmische Anzeige. Der LED Balken stimmt genau mit der Anzeige bei mir am PC überein. Also 100% Lautstärke (bei 1khz Sinus) ergibt vollen Ausschlag (31 LEDs). 50% ergibt 15 LED usw. Ich habe mal den Schaltplan der LED Matrix angefügt. Es ist jeweils ein Zeilen und Spaltentreiber eingezeichnet, insgesamt sind es 16 Spalten und 2x 16 Zeilentreiber. Als Spannungsversorgung verwende ich im Moment noch einen 7805, aber wenn ich mehr als 50% der LEDs einschalte fängt alles an zu flackern, da die Spannung zusammenbricht. Enweder verwende ich einen modifizierten LM2574 Schaltregler (der 5A mühelos schafft) oder irgendein billiges Schaltnetzteil von Pollin.
welchen code hast du auf dem µC drauf, der für die Zeilen und Spalten verantwortlich ist lässt sich dieser an ein 28x12 er Analyzer anpassen bzw gibts du ihn heraus ? denn bei meinen Analyzer wäre schon die Matrix ( 2 x 14 x 12 leds fertig )
Hier ist der Code für den LED Displaycontroller. Über den UART werden die Grafikdaten mit 115200Baud empfangen und in den Speicher geschrieben. Jede Spalte belegt 2 Bytes, insgesamt werden also 64Bytes benötigt. Der FFT uC sendet die Daten etwas verschachtelt, und zwar zuerst die oberen 8 LEDs (32x, da 32 Zeilen) und dann die unteren 8 LEDs. Daher wird in der UART Interrupt Routine der Zähler zweimal erhöht. Durch einen externen Interrupt (Sync Signal) wird der Zähler wieder auf 0 gesetzt. Darauf kann man eigentlich verzichten. Im Timer Interrupt werden 2x16bit seriell ausgegeben.
kannst du auch mal musik drüber laufen lassen? mich würde mal interessieren wie schnell das ganze ist, gibt eventull auch eagel layouts ? für 32x16
Ein Layout habe ich nich erstellt, da dieses Doppelseitig ausgefallen wäre (Zeilen und Spalten kreuzen sich), daher doch lieber Lochrasterplatine. Im Anhang ein Video mit Musik. Falls jemand ein anderes Lied wünscht, noch habe ich die Kamera aufgebaut. Die Anzeige ist auf jedenfall schnell genug. Selbst die kürzesten Geräusche erkennt man deutlich.
ich werde mich nun hinsetzen ein layout machen die matrix ist ja schon fertig bei mir ! lasse es bei nem bulgarischen kumpel ätzen ! werde auch den code von 16x16 auf 12x14 ändern da ich eine 12x28 matrix habe / benötige :-)
ich mache nun die front blende für 32x16 LEDs fertig und werde mich dann hinsetzen und in eagel ein layout machen, für das teil, habe nochn paar rück fragen bezüglich des layouts... das werde ich die tage dann mal fragen... wegen der matrix.... wenn ihr wollt lasse ich für euch mit äzen lasse wie Matthias in bulgarien ätzen...
benedikt welche zahlenwerte muss ich verändern um den code von dir auf eine 14 spalten 12 zeilen matrix umzuändern zuvor 16x16 bei dir
vielen lieben dank also 12 led s pro spalte und 28 spalten ! frage lassen sich die frequenzen auch bestimen ? bzw die db werte ? wo ändere ich dies ?
Das Programm ist nur die Anzeige. Die Frequenzen und die Pegel werden auf dem anderen uC bestimmt.
Und hier das FFT Programm (noch als 32er Version mit 0-10kHz Frequenzen) PS: Beim anderen Programm muss im Timer Interrupt die Anzahl auch auf die LED Anzahl begrenzt werden: Timer 0 Interrupt: clr P3.2 inc MuxPos a=MuxPos if a=#LEDs then MuxPos=#0 a=#0 end if
ist nun die ledmuxlog28.a51 auf 28 Spalten gestellt ? da ich immer noch eine 8 bzw 16 lese ? kannst du mir die Stellen zeigen wo dies umgestellt wird eine fft mit 0-20khz gab es doch hier auch mal ?
Die 16 ist falsch, hier muss LEDs stehen Die 8 kommt von den 8bit pro 4094. 28x12 ist nicht möglich, sondern nur 28x16, aber da kannst du ja einfach 4 Pins unbenutzt lassen. 20kHz ist mit einem AVR nur bedingt möglich, da der ADC dies nicht schafft. Mit einem externen ADC sollte aber sogar ein Bereich 0-1MHz möglich sein.
also Timer 0 Interrupt: clr P3.2 inc MuxPos a=MuxPos if a=#16 then MuxPos=#0 a=#0 die Zeile if a=#16 then muss also if a=#LEDs then heissen ? end if rl a setb acc.6 push acc add a, #LEDs r0=a ;Rechte Hälfte inc r0 a= @r0 for r7=#8 was bedeuten die nummer 8 ? da ich ja 2x 14 habe (28) clr Clk rlc a Dat=c nop setb Clk next dec r0 a= @r0 for r7=#8 clr Clk rlc a Dat=c nop setb Clk next pop acc r0=a ;Linke Hälfte inc r0 a= @r0 for r7=#8 clr Clk rlc a Dat=c nop setb Clk next dec r0 a= @r0 for r7=#8 clr Clk rlc a Dat=c nop setb Clk next clr OE a=MuxPos swap a P1=a setb Latch nop clr Latch nop setb OE setb P3.2 reti gruß matthias
was ist der U1 IC auf deinem Schaltbild ? wo gehen die nicht verdrahteten Transistoren hin ? ist die FFT nun bis 20khz oder nur bis 10khz ?
transistoren sind klar nun ... die fft nun auch geht ja nur bis 10 khz ähm wie könnte ich die samplingfrequenz erhöhen (ums doppelte) so dass es mir 22khz anzeigt ?
also 10khz ist sehr übel um das Teil nicht nur als Schaustellstück einzusetzen und die 170hz über 5k bzw unter 5k ne andere Einteilung der Frequenzen ist mir auch viel zu ungenau mein Bandpass Analyzer mit der 1/3 Oct Teilung, festen db Werten nach Studionorm bleibt somit bestehen
jupp, werd meinen nun auch mit bandpässen baue is wohl doch besser.... oder gibts n möglichkeit das teil auf 20-22khz zu bekommen ?
Ich habe es gestern mal gestestet: mega8 @ 18,432MHz, ADC Teiler auf 32, ergibt 44,2kHz Samplerate. Ist zwar außerhalb der Spezifikationen, aber es geht. Das Rauschen ist ein klein wenig höher, aber das Ergebnis ist noch brauchbar. Wenn ich jetzt noch irgendwo einen Switched Capacitor Filter auftreibe und im unteren Bereich die Auflösung erhöhe, dann lasse ich es eventuell sogar auf 44kHz Samplerate.
@Matthias Asselborn Wie steil sind eigentlich die Bandpässe in deinem Spektrum Analyser ? Auf den alten Fotos von der ersten Version sieht man eine Frequenz, die aber fast auf der halben Anzeige mit abfallenden Pegeln erscheint. Dies war eigentlich der Hauptgrund wiso ich mich für FFT entschieden habe: Hier erscheint ein sauberer Sinus auf max 2-3 Balken, aber nicht weiter.
So, jetzt läuft man Analyser mit 0-22kHz Frequenzbereich und 43Hz Auflösung bei niedrigen Frequenzen. Jetzt brauche ich nur noch einen Switched Capacitor Filter oder einen anderen, steilen Tiefpass Filter mit 5 bis 8db, für 2kHz und 20kHz.
das wäre ja dann akzeptabler ! @Benedikt könntest du mir nun mal den fft code überreichen dann baue ich die fft auf und danach das display welchen ad hast du verwendet ? bei meinem bandpass wenn ich eine sinus anlege (beim kalibrieren ) hatte ich einen balken weiter nichts die bilder die du gesehen hast waren halt mit sound ! also nicht nur eine frequenz sondern ein kompletes lied !
Könntest du mal die Schaltung eines Bandpassfilters verraten ? Wenn es bei einem Sinuston wirklich nur ein Balken aufleuchtet, dann muss der Filter ja ziemlich steil sein. Der FFT Code ist jetzt sehr ähnlich dem von ape. Als ADC verwende ich den internen des mega8.
Hier noch ein Video zu der jetztigen Version. Bei den Bässen sieht man gut, dass die Auflösung im unteren Bereich deutlich höher ist als vorher, vor allem wenn die Balken so schön nach links wandlern...
verrate ich gerne ich entnahm ihn dem Spektrum Analyzer der zu meinem Geburtsjahr im Elektor erschienen ist ! es kann aber sein, dass ein paar leds noch flackern wenn ich ein signal draufgebe da jeder günstige sinus generator vor allem die hardware abhängigen vom pc verschieden teils ungenau sind es ist halt schade bei dir dass nur ein paar led balken fpr die tiefen töne verantwortlich sind eine 1/3 oct teilung wäre da angemessener.... z.b. 31,5 40 50 63 80 10 125 usw... da hast du ja nur 40, 80 und 120 von ? verrate du mir mal deinen kompletten schaltplan ! bitte ! inklusive ad verdrahtungen usw... was der u1 ist... das ich das mal nachbauen kann und weiterwentwickeln evtl neue einteilungen usw...
und das die filter ! bitte benedikt mach mir doch mal n schaltplan ! für alles was ich brauche ! den rest krieg ich dann schon selber hin ! aber ich bräuchte mal n schönen plan !
U1 ist ein NE555. Dieser arbeitet als retriggerbares Monoflop, das bei jeder Low-High Flanke am Eingang den Spaltentreiber für etwa 5ms aktiviert. Hängt sich der uC auf, schaltet alles ab. Bei meiner letzten Mux Schaltung sind mir die LEDs halb abgebrannt als das passiert ist... Man lernt eben aus seinen Fehlern. Ich sehe gerade, in dem Plan ist ein Fehler: Die Adressen für den Spaltendekoder IC2 sind nicht an P1.0-P1.3 sondern an P1.4 bis P1.7 angeschlossen, da P1.0 und P1.1 nur Open Collektor sind und ich mir aus Faulheit die Pullups gespart habe. Der Schaltplan mit dem mega8 ist vorläufig. Entweder bekomme ich irgendwo ein MAX29x oder ich werde einen steilen Tiefpass (20db oder steiler) verwenden und diesen an ADC1 anschließen. Die normalen Signale (0-22kHz) gehen dann an ADC0, die LF (0-1,5kHz) an ADC0
Hier der Sinus 10Hz-20kHz Rechts fehlt einiges, da ich nicht ausreichend Platinen da hatte um 32 Spalten aufzubauen. Im Momet habe ich nur 22 Spalten. Die Störungen im unteren Frequenzbereich kommen von der hochohmigen Leitung quer durch mein Zimmer.
@Benedikt: Sieht ja schon mal gut aus. Ich habe diesen Thread nicht gelesen, es sieht aber so aus, als ob Du im höheren Frequenzbereich Aliasing-Effekte hast. Man sieht schön, wie es die hohen Frequenzen reinspiegelt.
Ja, das ist ein Problem bei dem ganzen. Da ich aber keinen Switched Capacitor Filter (MAX29x oder MAX740x) bekomme, muss ich mir demnächst wohl einen steilen 1,5kHz Tiefpass bauen, dann sind die ganzen Störungen weg. Ich sample mit 5,5kS/s, macht also 2,8kHz Bandbreite. 40db Abschwächung reichen mir, also brauchte ich Filter das 1,3kHz weniger als 1db dämpft, und 4,3kHz mit mindestens 40db dämpft. Also etwas mehr als 20db/Oktave sollte reichen. Hat jemand schonmal mit einem elliptischen Tiefpass gearbeitet ? Dieser ist ja im Grenzbereich sehr steil, daher sollte ich mit einem DualOpamp hinkommen ? Oder kennt jemand eine andere (nicht zu komplizierte Schaltung) die den geforderten Übertragungsbereich hat ?
@Benedikt: Wenn Du mit 5,5 kHz samplest, muss der Filter doch bei 2,75k kHZ absolut dicht sein, damit Du keine Aliasing Effekte bekommst?! Da Deine Anforderung im Durchlassbereich ja nicht so kritisch ist, würde dort auch etwas Welligkeit wohl nicht schaden. Also würde ein 4-poliger Tschebyschedd-Filter mit 2dB Welligkeit gerade so hinkommen. Der würde die 40dB gerade so erreichen. Dafür bräuchtest Du einen Dual-Op-Amp, 8 Widerstände und 4 Kodensatoren. Wenn Du ihn steiler haben möchtest, könntest Du mit einem Quad-Op-Amp einen 8-poligen Filter bauen, der käme auf über 80dB (erste Oktave). Hast Du das Buch "Art of Electronic" zu deutsch "Hohe Schule der Elektronik"? Da sind super Entwurfstabellen drin mit denen Du so ein Filter ganz einfach aufbauen kannst.
Ich habe die betreffenden Seiten mal gescannt. Mal sehen ob ich es hier als Anhang reinstellen kann (ist groß)...
Aha, hat also nicht funktioniert. Sag' mal Deine Email-Adresse und ich schicke es Dir per Mail (3MB).
Danke ! (Emailadresse: benedikt83 ät gmx punkt net) Ich bin schon die ganze Zeit am suchen und simulieren, komme aber nicht über ein Filter 4. Ordnung hinaus. Der große Frequenzbereich kommt daher, dass ich nur Frequenzen unterhalb von 1,3kHz verwende. Die Frequenzen oberhalb von 2,8kHz erscheinen gespiegelt, so dass sie bis 2,8kHz + (2,8kHz-1,3kHz)=4,3kHz nicht stören.
Diese Schaltung sollte meine Anforderungen erfüllen: Kaum einen Überschwinger beim Frequenzgang und insgesamt -38db bei den 4,3kHz gegenüber dem DC Pegel. Der Frequenzganz ist bis 1,3kHz annähernd linear.
Naja, das sind ja einfach zwei gleiche Tiefpässe hintereinander. Das sollte auch besser gehen. Einfach nur andere Werte für die Cs und Rs verwenden. Die Bauteilanzahl bleibt gleich. Hast Du meine Mail bekommen? Da ist das doch schön erklärt. Aber wie Du es letztendlich machst, ist Deine Sache.
>Naja, das sind ja einfach zwei gleiche Tiefpässe hintereinander. Das >sollte auch besser gehen. Einfach nur andere Werte für die Cs und Rs >verwenden. Die Bauteilanzahl bleibt gleich. Dann habe ich wohl die Beschreibung nicht so ganz verstanden. Wie berechne ich aus dem K und Fn Wert aus Tabelle 5.2 die Rs und Cs ? Ich habe die Grundschaltung verwendet und so lange in einer Simulation die Werte angepasst, bis ich einen passenden Signalverlauf hatte.
Der Filter könnte noch etwas steiler sein, denn dann könnte ich die Trennfrequenz ein klein wenig höher legen. Man sieht kurz den Amplitudenabfall, ehe auf die 44kS/s FFT Daten umgeschaltet wird. Dann sieht man etwas später die unterste LED Reihe nochmal kurz lang links laufen. Das sind die letzten Reste, die der Tiefpass nicht schafft. Die hohen Frequenzen sind da, wurden aber vom Audiocodec geschluckt. Aber ansonsten bin ich damit jetzt ziemlich zufrieden. Jetzt muss ich nur noch warten bis Reichelt die Platinen liefert, damit ich die fehlenden 160 LEDs rechts anbauen kann. Im Moment geht die Anzeige bis etwa 3,5kHz.
Du willst einen 4-Pol-Tschebyscheff-Filter bauen. Du brauchst zwei OPVs und Widerstände und Kondensatoren wie in Deiner Zeichnung (zwei Sektionen). Seite 314, Abschnitt "Bessel- und Tschebyscheff-Tiefpaßfilter": "Allerdings sehen die RC-Produkte für die einzelnen_ _Sektionen im Vergleich zum Butterworth-Filter anders aus, und sie müssen mit dem Normalisierungsfaktor_ _fn (...) nach RC=1/(2*pi*fn*fc) skalliert werden." Also: Bis 1300 Herz soll der Filter möglichst linear sein, dann soll er anfangen zu sperren. Verwenden wir mal einen 4-Pol-Tschebyscheff-Filter mit 0,5dB Welligkeit. Zwei Sektionen brauchen wir. Die Faktoren fn gibt's in der Tabelle 5.2 auf Seite 313. Fn für die erste Sektion 0,597 und für die zweite Sektion 1,031. Nun die benötigten RC-Produkte für beide Sektionen ausrechnen: 1. Sektion: RC = 1 / (2 pi 0,597 * 1300) = 0,0002051 2. Sektion: RC = 1 / (2 pi 1,031 * 1300) = 0,0001187 Nun müssen wir passenden Kondensatoren und Widerstände "wählen". Da muss man ein wenig improvisieren. Probieren wir mal 100 Kiloohm für die 1. Sektion: R*C=0,0002051 --> C=0,0002051/R = 0,0002051/100000 = 2,051 nF So einen Kondensator gibt's nicht, der nächste in der Nähe wäre 2,2nF. Dann rechnen wir für 2,2 nF mal R aus: R*C=0,0002051 --> R=0,0002051/C = 93,2 Kiloohm. Das sieht schon ganz gut aus. Nächster lieferbarer Widerstand wäre 93,1 Kiloohm (Metallschicht, 1%, E96 Reihe). D.h. die drei Widerstände R1, R2 und R für die erste Sektion wären eben 93,1 Kiloohm. Fehlt nur noch der vierte Widerstand (K-1)R: Rk = (K-1)*R = (1,582 - 1) * 93,2 Kilohm = 54,3 Kiloohm. Der nächste lieferbare Wert wäre 54,9 Kilo oder 53,6 Kiloohm. Da liegen wir ziemlich in der Mitte. Nun haben wir alle Werte für die erste Sektion. Die zweite Sektion geht genau so, nur eben mit anderen Werte für die RC Kombination und für den K-Faktor, der in der zweiten Sektion in diesem Fall 2,66 ist (siehe Tabelle). So weit alles verstanden? Die zweite Sektion musst Du Dir schon selbst ausrechnen. Ich hoffe ich habe keinen Fehler in meiner Berechnungen. Wenn Du die passenden Widerstände nicht hast, wähle einfach die am besten passenden. Allerdings nimmt die Qualität des Filters dann ab, z.B. wird die Steilheit flacher, Welligkeit im Durchlassbereich höher etc. Aber da Du ja eh alles in Spice oder so simulierst, kannst Du die Auswirkungen zwischen theoretischen und realen Werten ja leicht überprüfen. Viel Spaß mit der zweiten Sektion! ;-)
Nochmals Danke ! Jetzt habe ichs verstanden. Ich glaube da werde ich mir erstmal ein kleines Prog schreiben, das mir die ganzen Werte berechnet...
Hab via Google das hier gefunden: http://www.web-ee.com/primers/files/slod006b.pdf Tschebyscheff-Filter sind so um Seite 300. habs mir noch nich näher angesehen wie hilfreich das is die berechnungen sehen auf den ersten Blick recht kompliziert aus :)
Vielleicht hilft euch das ja...? http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en010007&part= Gruß Björn
Ja, das ist genau das richtige. Jetzt ist der Filter so wie ich ihn wollte: Unterhalb von 1,7kHz ist das Signal absolut linear (+/-1db) und bei 4kHz hat es bereits -38db. Man kann problemlos steile Filter bauen, aber die meisten haben einen für solche Anwendungen einen zu großen Übergangsbereich. Interessant ist auch, dass diese Filter eine DC Verstärkung von 1 haben. Die Filter aus dem Buch verwenden dagegen eine höhere Verstärkung um eine Überhöhung kurz vor der Grenzfrequenz zu verursachen. Bei den Filtern aus dem Program laufen die Opamps mit einer Verstärkung von 1, was nicht nur zwei Widerstände spart, sondern auch die Hilfsspannung, beim Betrieb an einer Unipolaren Spannung. Hier wird die Überhöhung durch ungleiche Filterwiderstände und Kondensatoren erreicht. Das ist jetzt meine entgültige Hardware. Jetzt passe ich nur noch die Software ein kleinwenig an, um einen möglichst gleitenden Übergang zwischen den beiden FFTs zu erhalten.
ok dann mach ich mich mal an s werk @hardware ist deine display hardware gleichgeblieben ?
Ja, das Display ist noch gleich. Um das ganze nicht künstlich komplizierter zu machen, würde ich dir empfehlen die 32x16 Version zu bauen, da ich für diese auch Softwareupdates usw. machen werden. Für ein 28x12 Display lässt du dann einfach die oberen 3 und unterste LED Zeile weg (in der untersten habe ich ab und zu kleine Störungen ohne Signal). Ebenso die rechten 4 LED Spalten. Ein interssanter Nebeneffekt des Displays: Durch den UART als Dateneingang kann kan es auch an einen PC hängen und Text oder Grafik anzeigen. In den nächsten Tagen werde ich das komplette Projekt mit Software, Hardware, Beschreibung, Fotos usw. in die Codesammlung stellen.
alles klar ! könntest du mir noch sagen wie das mit den Freuquenzen ist ? wo liegen die nun ? könnte man die an einen 1/3 oct Maßstab anpassen ? welche Werte hast du nun zwischen den einzelnen Led s ? in Volt oder Db !
Die Amplituden Werte für die einzelnen LEDs sind Wurzel aus der Amplitude. Die db Werte kannst du daraus selbst berechnen. Im Bereich unterhalb von etwa 1500Hz sind 43Hz Auflösung möglich, darüber 346Hz. Wenn du mir eine Tabelle erstellst, welche Frequenzen du für jeden Balken haben möchtest (ausgehen von obigem Frequenzraster), dann kann ich versuchen das zu realisieren. Ich fasse dazu immer 1,2,3,4,6 oder 8 Werte zu einem Balken zusammen. Hier mal ein Beispiel, wie ich es im Moment habe: 0-43 43-86 86-129 129-172 172-215 215-301 301-387 387-473 473-602 usw.
1/3oct wäre der Studiostandart der Spectrum Analyzer angefangen mit (32 Band) 20 hz 25 hz 31,5 hz 40 hz 50 hz 63 80 100 125 160 200 250 315 400 500 635 800 1000 1250 1600 2000 2500 3150 4000 5000 6350 8000 10000 12000 16000 20000 22000 somit wäre deine Samplerate von 44khz optimal ausgenützt und du bekommst ein vernünfiges Bild ! für meinen 28 er würde gelten : die letze und ersten Beiden weglassen ) 31,5 hz 40 hz 50 hz 63 80 100 125 160 200 250 315 400 500 635 800 1000 1250 1600 2000 2500 3150 4000 5000 6350 8000 10000 12000 16000 hz wie meinst du das mit dem Frequenzraster ? brauchst ne Formel wie die Werte entstehen ? kein Problem ! unter Terzbänder http://fasae.ibpmw.uni-essen.de/ibpm/studium/Lehre/Schall/Buch/Tabellen.htm#tab01 anbei noch ne Datei http://www.pas-products.com/bilder/ana_3.8.gif
Eine 64Punkt FFT teilt den gemessenen Frequenzbereich in 64 gleiche Bereich. Bei 44kS/s erhält man einen Frequenzbereich bis 22000Hz. Dieser wird in 64 Bereiche unterteilt, also je 346Hz breit. Um eine höhere Auflösung bei den niedrigen Frequenzen zu erziehlen, mache ich noch eine zweite Messung mit 5,5kS/s, was 43Hz Auflösung ergibt. Daher sind die ersten paar Werte wie 31,5Hz 40Hz 50Hz usw. nicht möglich.
du hast doch 8 AD s am Atmel ! wenn du nun 8 mal teilst ? also bei 0 - bis 22khz/8 ( 2,75 khz) dann bei 2,75 - 5,5 5,5 - 8,25 8,25 - 11 11 - 13,75 13,75- 16,5 16,5 - 19,25 19,25- 22 oder ist der atmel da zu lahm ?
die ad s nacheinander auslesen und ausgeben sollte doch möglich sein ?
möglich evtl schon aber die geschwindigkeit geht dann wieder den berg runter ? hmm hierbei frägt es sich das ganze nicht odch mit einem dsp aufzubauen ?!
Mit einem DSP ist das ganze kein Problem, aber ob der soviel billiger wird als ein diskreter Analyser ? So wie du dir das vorstellst mit den 8 ADCs geht es nicht: Der Frequenzbereich beginnt immer bei 0Hz, was ja auch nicht weiter schlimm ist, denn bei höheren Frequenzen reicht ja ein gröberes Frequenzraster. Mit einem entsprechend schnellen uC mit viel Rechenleistung und ausreichend RAM (64kB sollten es schon sein) reicht auch eine einzelne FFT. Am PC erreiche ich 1,5Hz Auflösung bei einem Frequenzbereich von 0-48kHz. Allerdings ist mein Athlon 64 dann voll ausgelastet, wenn er das ganze flüssig darstellen soll...
so ein dsp von z.b. TI liegt bei ca 30 euro welcher preislich im vergleich zu nem atmega128 steht schon klar dass der frequ beriech immer bei 0 anfängt ich dachte halt an mehrere kleine ( 4 stück ) ffts mit genauerer auflösung 10 hz wären optimal ! die durch 4 große bandpassfilter getrennt werden würde der 128 er atmel nicht reichen für mehr power ?
ach herje die TMS320 Serie ist doch nicht so billig ............ aber gibt es denn keine DSPs für ca 30-50 euro ? und nicht gleich 500+
ìch habe vor ein paar Jahren n VU Meter gebaut mit nem ADSP2105 und nem 27C512 da kostete der DSP ca 10-20 DM der dürfte auch von den Pins her reichen
is von Analog Devices lief auf 10 Mhz ich denke diese Serie ist noch erschwinglich !
nun hab ich einen gefunden ! der TI TMS320LF2403APAGA bringt 40 mhz 40 mips (denke das reicht) für 30 euro
10MHz ist aber nicht das schnellste. So viel besser als die FFT mit einem AVR wird das auch nicht... Ich hab gerade den Digikey Katlog hier liegen: TMS320 kostet so 10 bis 200
problem is der hat halt keine ram .... der TMS320VC5402PA hätte für ca 15 euro nur 16k ram auf 40 mhz 40mips aber für 43 euro gäbe es nen 34k ram und 64k ram mit 100 mhz mips für 80 euro
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.