Hallo,
ich bin relativ neu im Bereich der Mikroprozessorprogrammierung und
beschäftige mich gerade mit dem Thema der FFT darin. Ich weiß das dieses
Thema schon dutzende male hier im Forum besprochen wurde. Ich habe jetzt
aber auch schon zig Stunden damit verbracht mich einzulesen und die
Funktion zu verstehen. Es sind aber immer noch ein paar Fragen offen und
ich hoffe ihr könnt mir dabei weiter helfen. Es würde mir schon reichen
wenn ihr mir mein angelesenes Basiswissen bestätigen würdet, damit ich
weiß das ich auf dem richtigen Weg bin.
Zu meinem Background:
Ich habe ein kleines Entwicklungsboard (www.minimexle.de) mit einem
ATmega88. Hiermit möchte ich gerne mit dem analogen Eingang und dem ADC
das Signal abtasten, anschließen eine FFT anwenden und dann auf dem LCD
die Amplitude einer bestimmten, im Signal enthaltenen Frequenz,
darstellen.
Mein Basiswissen:
1.
Laut ATmega88 Datenblatt soll man eine Abtastfrequenz von 50kHz-200kHz
am ADC einstellen. Da mein ATmega mit 18.432MHz läuft hab ich also den
größten Frequenzvorteiler von 128 eingestellt. Damit taste ich das
Signal also mit 144kHz ab, richtig?
2.
Mit einer Abtastfrequenz von 144kHz kann ich dann ein Signal bis 72kHz
abtasten. Richtig?
3.
Da die FFT Routine in C nicht sonderlich schnell sein soll, hab ich erst
mal die Bibliothek von elm-chan.org verwendet bevor ich mich selber
daran wage. Dieser verwendet 3 Arrays. Da mein Speicher vom ATmega88 auf
1024 Byte beschränkt ist, muss ich meine FFT Stützpunkte entsprechend
wählen, also:
int16_t capture[FFT_N]; // Wave captureing buffer (Größe: 2Byte)
complex_t bfly_buff[FFT_N]; // FFT buffer (Größe: 4Byte)
uint16_t spektrum[FFT_N/2]; // Spectrum output buffer (Größe: 2Byte)
Das maximal mögliche das ich hier also wählen kann ist eine FFT_N = 128
-> (2Byte * 128 + 4Byte * 128 + 2Byte * 64) = 896 Byte das meine FFT als
Speicher braucht. Richtig?
4.
Mit der 128 Punkt FFT bekomme ich also 64 Spektrumbalken = 64
Koeffizienten (128 Messwerte wobei aber nur die ersten 64 relevant sind
da die restlichen 64 gespiegelt sind) Richtig?
5.
Auflösung = (Abtastrate/2) / (FFT-Länge/2) = 72kHz / 64 = 1.125kHz
-> Jeder Balken im Spektrum ist 1.125kHz voneinander entfernt. Richtig?
-> Schwingung f0 = DC Anteil, f1 = ???, f2 = ??? wie gehts hier weiter?
6.
Da ich wegen dem maximalen Speicher von 1024 Byte auf eine 128er FFT
beschränkt bin frage ich mich ob diese für einen "einfachen Equalizer",
den ich realisieren will, überhaupt ausreicht? Ich weiß, dass wenn ich
die Frequenzauflösung erhöhen will a) eine höhere Abtastfrequenz brauche
b) Einen größeren Zeitausschnitt verwendet muss. Da ich nur Frequenzen
eines MP3 als Eingang unterstützen möchte und diese an das menschliche
Gehör angepasst sind (20Hz-18kHz) müsste es doch mit der relativ hohen
Abtastfrequenz von 144kHz hinkommen oder?
Vielen Dank schon mal für eure Hilfe
Gruß, Uwe
>Laut ATmega88 Datenblatt soll man eine Abtastfrequenz von 50kHz-200kHz>am ADC einstellen. Da mein ATmega mit 18.432MHz läuft hab ich also den>größten Frequenzvorteiler von 128 eingestellt. Damit taste ich das>Signal also mit 144kHz ab, richtig?
Das ist nicht die Abtastfrequenz sondern der Arbeitstakt fuer den ADC.
Um eine Messung zu starten muss du den ADC schon per Software oder mit
einem der internen Timer anstossen. Und 144KHz wirst du da auch nicht
erreichen.
Gruss Helmi
Wenn du 40kHz Abtastfrequenz verwendest, hast du mit gleichem
Speicherbedarf eine höhere Frequenzaufösung. Das sollte für Audio
ausreichen.
Wenn du zudem nur MP3s analysieren willst, empfehle ich dir, den Umweg
über ein Analogsignal zu umgehen und das ganze auf einem PC zu rechnen.
Mit DirectSound ist das gleich in ein Wave transcodiert, das du entweder
live als Spektrum oder Spektrogramm darstellen kannst, oder eben im
Nachhinein auch in Zeitlupe.
Wenn es dir nur um die Grundlagen der FFT geht, ist das auf einem PC
viel schneller ausprobiert und du hast keinerlei Einschränkung bezüglich
der Menge an Arbeitsspeicher.
Hast du eigentlich den Spektrunanalyzer mit Atmega und Grafikdisplay
schon im Internet gefunden? Es gibt da ein veröffentlichtes Projekt. Das
Programm ist komplett in Assembler geschrieben.
Grüße,
Peter
Upps, klar du hast recht. Ist natürlich der ADC-Takt.
Aber was heißt die 144kHz werde ich da nicht erreichen? Wenn ich einen
Takt von 18,432 MHz habe und den größten Teilungsfaktor von 128
einstelle bekomme ich doch den niedriegst möglichen ADC Takt von 144kHz.
Muss ich davon noch was abziehen in der Praxis?
Die anderen Punkte kann mir keiner bestätigen ob die stimmen?
Gruß Uwe
@Peter
> Wenn du 40kHz Abtastfrequenz verwendest, hast du mit gleichem> Speicherbedarf eine höhere Frequenzaufösung. Das sollte für Audio> ausreichen.
Gibt es da vielleicht einen Trick wie ich auf die 40kHz ADC Takt komme
ohne den Quartz auf dem Entwicklungsboard auszutauschen? Wie gesagt
läuft der ATmega88 momentan mit 18.432 MHz und der größte Teilungsfaktor
der angeboten wird ist nun mal nur 128. Folglich ist der kleinste ADC
Takt den ich verwenden kann 144kHz.
> Wenn du zudem nur MP3s analysieren willst, empfehle ich dir, den Umweg> über ein Analogsignal zu umgehen und das ganze auf einem PC zu rechnen.> Mit DirectSound ist das gleich in ein Wave transcodiert, das du entweder> live als Spektrum oder Spektrogramm darstellen kannst, oder eben im> Nachhinein auch in Zeitlupe.>> Wenn es dir nur um die Grundlagen der FFT geht, ist das auf einem PC> viel schneller ausprobiert und du hast keinerlei Einschränkung bezüglich> der Menge an Arbeitsspeicher.
Leider lautet die Aufgabe eine FFT auf dem AVR zu realisieren :-|
> Hast du eigentlich den Spektrunanalyzer mit Atmega und Grafikdisplay> schon im Internet gefunden? Es gibt da ein veröffentlichtes Projekt. Das> Programm ist komplett in Assembler geschrieben.
Ich wollte eigentlich meine schon umfangreiche Funktionsbibliothek nur
noch durch eine FFT erweitern und da kam mir die Bib von elm-chan.org
gerade recht. Vor allem weil auch schon andere hier im Forum darüber
brichtet haben.
> Mit dem größten Teilungsfaktor von 128 hast du eine> Wandlungszeit von ca. 90 µs -> 11 KHz.>> Du rechnest "Falschrum" rum.
Also sorry wenn das jetzt eine dumme Frage sein sollte aber was für
einen Fehler mach ich hier?
Auszug aus dem ATmega88 Datenblatt:
The ADC module contains a prescaler, which generates an acceptable ADC
clock frequency from any CPU frequency above 100 kHz.
• Bits 2:0 – ADPS2:0: ADC Prescaler Select Bits
These bits determine the division factor between the system clock
frequency and the input clock to the ADC.
Sogar hier ist es so beschieben:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#ADC_.28Analog_Digital_Converter.29
DPS2...ADPS0 (ADC Prescaler Select Bits)
Diese Bits bestimmen den Teilungsfaktor zwischen der Taktfrequenz und
dem Eingangstakt des ADC.
Der ADC benötigt einen eigenen Takt, welchen er sich selber aus der
CPU-Taktfreqenz erzeugt. Der ADC-Takt sollte zwischen 50 und 200kHz
sein.
Der Vorteiler muss also so eingestellt werden, dass die CPU-Taktfrequenz
dividiert durch den Teilungsfaktor einen Wert zwischen 50-200kHz ergibt.
Bitte korrigiert mich also falls ich falsch liege.
Moin,
hhmmm äußerst schlecht dass du einen AVR verwenden musst ich würde dir
jetzt glatt einen dsPIC vorschlagen, habe grade selbiges Projekt
vollendet halt mit nem anderen Controller.
Du solltest deinen AVR verrückten Auftraggeber vom dsPIC überzeugen,
damit ist das absolut kein Problem geht ratz fatz.
-> Bitte korrigiert mich also falls ich falsch liege.
Das mach Atmel:
The ADC module contains a prescaler, which generates an acceptable ADC
clock frequency
from any CPU frequency above 100 kHz. The prescaling is set by the ADPS
bits in ADCSRA.
The prescaler starts counting from the moment the ADC is switched on by
setting the ADEN bit
in ADCSRA. The prescaler keeps running for as long as the ADEN bit is
set, and is continuously
reset when ADEN is low.
When initiating a single ended conversion by setting the ADSC bit in
ADCSRA, the conversion
starts at the following rising edge of the ADC clock cycle. A normal
conversion takes 13 ADC
clock cycles. The first conversion after the ADC is switched on (ADEN in
ADCSRA is set) takes
25 ADC clock cycles in order to initialize the analog circuitry.
Dein ADC-clock ist 144 KHz, aber eine Wandlung dauer 13 Zyklen.
144 KHz/13 -> 11 KHz
gruß hans
> Dein ADC-clock ist 144 KHz, aber eine Wandlung dauer 13 Zyklen.> 144 KHz/13 -> 11 KHz
Vielen Dank Hans! Du hast mir die Augen geöffnet. Ich sehe jetzt auch
meinen Denkfehler. Hatte einfach überlesen das eine Wandlung 13 Zyklen
benötigt.
Also: 18.432 MHz CPU-clock/128 Prescaler/13 Zyklen = 11kHz (mit 144kHz
ADC-clock)
Aber nur der Richtigkeit wegen. Was genau bezeichnet man dann als
"Sample Rate" wie es im Datenblatt angegeben wird? Die 144kHz ADC-clock
oder die 11kHz?
Und welchen Wert muss ich für das Nyquist-Abtasttheorem verwenden?
Abtastrate ist ja 144kHz aber Messwerte erhalte ich nur alle 11MHz.
Es wäre auch sehr nett wenn mir jemand zu meiner Frage 4 & 5 was sagen
könnte:
>4.>Mit der 128 Punkt FFT bekomme ich also 64 Spektrumbalken = 64>Koeffizienten (128 Messwerte wobei aber nur die ersten 64 relevant sind>da die restlichen 64 gespiegelt sind) Richtig?>>5.>Auflösung = (Abtastrate/2) / (FFT-Länge/2) = 72kHz / 64 = 1.125kHz>-> Jeder Balken im Spektrum ist 1.125kHz voneinander entfernt. Richtig?>-> Schwingung f0 = DC Anteil, f1 = ???, f2 = ??? wie gehts hier weiter?
Vielen Dank
> Und welchen Wert muss ich für das Nyquist-Abtasttheorem verwenden?> Abtastrate ist ja 144kHz aber Messwerte erhalte ich nur alle 11MHz.
11KHz nicht 11MHz ;-)
Die 11 KHz sind die Samplingfrequenz, du kannst so max. Frequenzen bis
5,5 KHz digitalisieren.
Den ADC-Wandler solltest du ggf im Free-Run Mode laufen lassen und dass
nach jeder Wandlung ein Interupt aufgerufen wird.
Gruß
Roland
Es sind die 11 KHz.
Die Einschränkung mit max. 200 KHz gilt für 10 Bit, damit die
Genauigkeit stimmt. Für 8 Bit (dann Left adjust) kann man auch
schneller werden.
Für Audio bis 20 KHZ sollte man mit mind. 40 KHz rechnen.
->
da du ehr etwas schneller werden solltest wäre der
Vorteiler 32.
die tatsächliche Abtastrate ist dann
@Grubenmensch osKar
Uwe hat ja nicht nach einer Alternative gefragt.
Sonst hätte ich auch einen DSPic empfohlen oder
einen TI-Piccolo.
Für beide gibt es FFT fertig.
Aber er hat einen Mega88!
gruß hans
@hans
Die Idee kam mir auch gerade. Hast du aber Erfahrung damit wenn man auf
die 8 Bit runter geht und die Samplingfrequenz erhöht? Muss ich da mit
Problemen rechnen? Im Datenblatt wird dazu bis auf die Möglichkeit kein
weiterer Satz verloren.
@Grubenmensch osKar
Du hast natürlich vollkommen recht. Man sollte für diesen Zweck auch
spezielle Prozessoren die für diesen Einsatzbereich gedacht sind
verwenden. Leider bin ich wie oben schon beschrieben an den AVR gebunden
um eben auch das Problem mit diesem Typ zu lösen ;-) Hätte ich eine
Wahl würde ich es auch so wie du machen.
Vielen Dank euch beiden aber für die wertvollen Tipps. Jetzt bin ich
schon einen ganzen Schritt weiter.
4.
Mit der 128 Punkt FFT bekomme ich also 64 Spektrumbalken = 64
Koeffizienten (128 Messwerte wobei aber nur die ersten 64 relevant sind
da die restlichen 64 gespiegelt sind) Richtig?
5.
Auflösung = Samplingfrequenz / (FFT-Länge/2) = 22,154kHz / 64 = 346Hz
-> Jeder Balken im Spektrum ist 346Hz voneinander entfernt. Richtig?
-> Schwingung f0 = DC Anteil, f1 = ???, f2 = ??? wie gehts hier weiter?
Wenn ihr mir vielleicht noch bei diesen beiden Punkten helfen könntet
dann bin ich der glücklichste FFT Newbie heute :-)
Hallo Uwe,
auch hier hilft Atmel:
Table 28-7. ADC Characteristics im Datenblatt des Mega88p.
Da siehst du, das die Genauigkeit bei 1 MHz mit Typisch 4,5 LSB
angegeben wird. Da bei 8 Bit jedoch die letzten beiden Bit
sowieso wegfallen, ist bei ca. 500 KHz nur mit dem Springen
des letzten Bits (eigentlich BIT 2) zu rechnen. Das hat
(fast) jeder Wandler.
gruß hans
Hallo Hans,
vielen Dank für den Tipp. Jetzt weiß ich auch warum das Datenblatt 376
Seiten stark ist. In Zukunft weiß ich aber nun wo ich bei solchen
Details nachsehen muss.
Gruß Uwe