Forum: Digitale Signalverarbeitung / DSP / Machine Learning FFT mit ATmega88


von Uwe (Gast)


Lesenswert?

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

von Helmut L. (helmi1)


Lesenswert?

>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

von Peter D. (pdiener) Benutzerseite


Lesenswert?

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

von Uwe (Gast)


Lesenswert?

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

von Uwe S. (masabuana)


Lesenswert?

@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.

von hans (Gast)


Lesenswert?

Mit dem größten Teilungsfaktor von 128 hast du eine
Wandlungszeit von ca. 90 µs -> 11 KHz.

Du rechnest "Falschrum" rum.

gruß hans

von Uwe S. (masabuana)


Lesenswert?

> 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.

von Grubenmensch osKar (Gast)


Lesenswert?

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.

von hans (Gast)


Lesenswert?

-> 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

von Uwe S. (masabuana)


Lesenswert?

> 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

von Roland Praml (Gast)


Lesenswert?

> 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

von hans (Gast)


Lesenswert?

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

deine AD-Frequen 576 KHz.

gruß hans

von Grubenmensch osKar (Gast)


Lesenswert?

Mein Vorschlag den AVR links liegen zu lassen ist wohl auf Granit 
gestoßen schade eigentlich.

von hans (Gast)


Lesenswert?

@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

von Uwe S. (masabuana)


Lesenswert?

@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.

von Uwe S. (masabuana)


Lesenswert?

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 :-)

von hans (Gast)


Lesenswert?

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

von hans (Gast)


Lesenswert?

Hallo Uwe,

zu 4 und 5 gab es mal einen Tread (muste erst suchen)

Beitrag "FFT: die "N"s und die Frequenzen"

Ich hoffe der Newbie ist jetzt glücklich ;-)

gruß hans

von Uwe S. (masabuana)


Lesenswert?

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

von Uwe S. (masabuana)


Lesenswert?

> Ich hoffe der Newbie ist jetzt glücklich ;-)

Überglücklich! Danke für die tolle Hilfe.

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
Noch kein Account? Hier anmelden.