Moin Moin,
ich habe heute versucht bei meinem Atmega88 das ADC in Betrieb zu
nehmen. Dazu kommt das Signal an Port PC5 an. Als Takt habe ich 20MHZ
gewählt. Ich benötige allerdings nicht jeden Messwert, den der Atmega
produziert, sondern nur einmal jeden 7. 61. und 446. Dazu habe ich
folgende Funktion geschrieben:
Nun wollte ich wissen wie lange es dauert den Code auszuführen. Der
Simulator im Atmel Studio hat mir dazu 259.755,25 µs ausgegeben. Da ich
allerdings eher mit einer Zeit von 19.981 µs gerechnet habe
(1/(20MHZ/128)*3122=19.981 µs), habe ich noch einen schlankeren
Algorithmus geschrieben:
Dieser benötigt auch 259.831,55 µs.
Meine Frage ist, habe ich einen Fehler gemacht oder ist das Studio nur
nicht in der Lage die Laufzeit ordentlich anzugeben?
Vielen Dank für die Antworten.
@nordman (Gast)
>ich habe heute versucht bei meinem Atmega88 das ADC in Betrieb zu>nehmen. Dazu kommt das Signal an Port PC5 an. Als Takt habe ich 20MHZ>gewählt.
Der Takt ist der CPU bzw. SYSTEMTakt. Dieser wird nochmal per Prescaler
geteilt auf den ADC-Takt.
Von diesem Takt benötigt der ADC 13 Takte, um eine Wandlung auszuführen.
> Ich benötige allerdings nicht jeden Messwert, den der Atmega>produziert, sondern nur einmal jeden 7. 61. und 446.
Warum auch immer.
>Simulator im Atmel Studio hat mir dazu 259.755,25 µs ausgegeben. Da ich>allerdings eher mit einer Zeit von 19.981 µs gerechnet habe>(1/(20MHZ/128)*3122=19.981 µs), habe ich noch einen schlankeren>Algorithmus geschrieben:
Hast du im Simulator 20 MHz CPU-Takt eingestellt?
>Meine Frage ist, habe ich einen Fehler gemacht
Wahrscheinlich.
>oder ist das Studio nur>nicht in der Lage die Laufzeit ordentlich anzugeben?
Doch.
Kleiner Tipp. Man sollte den ADC nach dem Auslesen des Ergebnisses
sofort wieder starten, damit läuft die AD-Wandlung und die Auswertung
des Ergebnisses parallel.
nordman schrieb:> Ich benötige allerdings nicht jeden Messwert, den der Atmega> produziert, sondern nur einmal jeden 7. 61. und 446.> Meine Frage ist, habe ich einen Fehler gemacht
Warum läßt du den ADC überhaupt wandeln, wenn dich die Werte nicht
interessieren?
Da würde man doch eher per Timer-Interrupt oder sonstwie gesteuert zu
den passenden Momenten eine Wandlung anstoßen und gut.
Falk B. schrieb:> Kleiner Tipp. Man sollte den ADC nach dem Auslesen des Ergebnisses> sofort wieder starten, damit läuft die AD-Wandlung und die Auswertung> des Ergebnisses parallel.
Allerdings ist dann auch der gesamplete Wert um eine Wandlung
verschoben.
Rolf M. schrieb:> Allerdings ist dann auch der gesamplete Wert um eine Wandlung> verschoben.
Womit wir wieder zur Timer-gesteuerten Wandlung kommen. Nur jeder 7., 61
und 446. Wert schreit ja gradezu danach.
Rolf M. schrieb:> Allerdings ist dann auch der gesamplete Wert um eine Wandlung> verschoben.
Wenn man das weiß, dann kommt das nicht überraschend und man kann damit
rechnen...
nordman schrieb:> 259.755,25 µs ausgegeben. Da ich> allerdings eher mit einer Zeit von 19.981 µs gerechnet habe> (1/(20MHZ/128)*3122=19.981 µs)
Paßt doch perfekt:
260ms / 13 = 20ms.
Der ADC braucht 13 Takte zum Wandeln.
Peter D. schrieb:> Paßt doch perfekt:> 260ms / 13 = 20ms.> Der ADC braucht 13 Takte zum Wandeln.
Gibt es eine Möglichkeit die Wandelung zu beschleunigen, so dass die
Wandelung etwa 13ms braucht.
Südseeinsulaner schrieb:> Warum läßt du den ADC überhaupt wandeln, wenn dich die Werte nicht> interessieren?>> Da würde man doch eher per Timer-Interrupt oder sonstwie gesteuert zu> den passenden Momenten eine Wandlung anstoßen und gut.
Das war nur mein erster Entwurf. Ich wusste nicht, wie ich das anders
löse. Der µC kann während eigentlich eh nichts nützliches tun. Wie kann
ich denn die Messung per Interrupt steuern?
@ nordman (Gast)
>> Der ADC braucht 13 Takte zum Wandeln.>Gibt es eine Möglichkeit die Wandelung zu beschleunigen, so dass die>Wandelung etwa 13ms braucht.
Mit der passenden Einstellung des Prescalers.
>> Da würde man doch eher per Timer-Interrupt oder sonstwie gesteuert zu>> den passenden Momenten eine Wandlung anstoßen und gut.>Das war nur mein erster Entwurf. Ich wusste nicht, wie ich das anders>löse. Der µC kann während eigentlich eh nichts nützliches tun.
Dann lass es so.
> Wie kann ich denn die Messung per Interrupt steuern?
Mit dem Free running mode zu ADC-interrupt. Siehe Interrupt.
Walter S. schrieb:> nordman schrieb:>> sondern nur einmal jeden 7. 61. und 446.>> darf man erfahren was das werden soll?
Das sind Daten für eine FFT. Ich transformiere 3 Mal. Dadurch spart man
sich eine Menge Stützstellen und man kann trotzdem die Frequenzen von
60-20000 hz nachweisen.
nordman schrieb:> Da ich> allerdings eher mit einer Zeit von 19.981 µs gerechnet habe> (1/(20MHZ/128)*3122=19.981 µs), habe ich noch einen schlankeren> Algorithmus geschrieben:
ich weiß nicht was du da rechnest (3122??), bei mir rechnet sich das so:
20MHz durch den Teiler 128 macht 156 kHz für den ADC,
der braucht mind. 13 Takte also Abtastrate max. 12kHz
das reicht also nicht dafür
nordman schrieb:> Das sind Daten für eine FFT. Ich transformiere 3 Mal. Dadurch spart man> sich eine Menge Stützstellen und man kann trotzdem die Frequenzen von> 60-20000 hz nachweisen.
Aber du kannst natürlich einen anderen Teiler als 128 einstellen (auf
Kosten der Genauigkeit)
nordman schrieb:> Das sind Daten für eine FFT. Ich transformiere 3 Mal. Dadurch spart man> sich eine Menge Stützstellen und man kann trotzdem die Frequenzen von> 60-20000 hz nachweisen.
Wie genau transformierst Du 3 mal?
Hört sich, sagen wir mal, ungewöhnlich an.
nordman schrieb:> Gibt es eine Möglichkeit die Wandelung zu beschleunigen, so dass die> Wandelung etwa 13ms braucht.
ADC-Takt anpassen hilft. Stellst du den z.B. auf 100 kHz ein brauchst du
für eine Wandlung im Freerunning-Mode nur noch 130 µs (erste Wandlung
nicht berücksichtigt).
nordman schrieb:> Das sind Daten für eine FFT. Ich transformiere 3 Mal. Dadurch spart man> sich eine Menge Stützstellen und man kann trotzdem die Frequenzen von> 60-20000 hz nachweisen.
Kannst du da mal genauer erläutern was du da machst? Das könnte
interessant sein. Ich selbst mache auch zur Zeit eine FFT mit dem
Atmega. Bei mir gehts dabei um Detektion von Schwingungen bis 50 kHz. Da
mir 8 bit am ADC dabei genügen kann ich problemlos den ADC mit 1.5 MHz
fahren, dadurch hab ich ne Abtastrate von ~115 kHz.
Karl M. schrieb:> Hallo nordman,>> hast Du auch die mathematische Herleitung für dein Vorhaben parat ?>> Würde mich mal interessieren, wie das geht.
Ich habe mich nicht ganz eindeutig ausgedrückt. Man kann natürlich mit
dieser Methode nicht das gesamte hörbare Spektrum in 60-Hz-Bereiche
unterteilen.
Mir ging es darum eine FFT für Musik zu schreiben. Da das menschliche
Gehör akustische Frequenzen logarithmisch einem Ton der klassichen
Tonleiter zu ordnet, ist es am natürlichsten eine solche
Frequenzeinteilung auch mit der FFT nachzubilden. Die Formel, die Töne
einer Frequenz zu ordnet, ist:
Zum Thema FFT gibt es nun 2 Dinge die man beachten muss:
Zum Einen gilt das WKS-Abtasttheorem. Das besagt, dass die maximal
nachweisbare Frequenz die Hälfte der Abtastrate beträgt.
Zum Anderen gilt die Unschärfe-Relation. Frequenz-Auflösung ≈
1/Zeitfensterbreite
Durch beide Sätze ergeben sich, wenn man ein Spektrum von 60-20000 hz
nachweisen will, mindestens
Stützstellen braucht.
Nun mache ich mir die logarithmische Skala zu nutze. Ich teile das
Spektrum in 3 Bänder von 60-416 hz, 416-2885 hz und 2885-20000 hz.
Das bedeutet, man benötigt lediglich 42 Stützstellen. Natürlich verliert
man bei höheren Frequenzen an Auflösung, aber die Tonleiter ist ohnehin
nicht so feistufig.
Nun transformiert man jede Messung seperat und erhält das gesamte
Spektrum, in dem man die 3 eizelnen Spektren zusammensetzt.
Das ist ein interessanter Ansatz. Wie gesagt, wenn du nur jeden 7., 61.
und 446. ADC- Wert brauchst würde ich den ADC Timergesteuert
realisieren. Überlege mal, wenn du nach deinem Schema vorgehst hast du
446 ADC-Werte und benutzt nur 3 davon, d.h. 443 ADC-Wandlungen hast du
total umsonst gemacht da du die ja eh weg wirfst.
@ Michael Köhler (sylaina)
>Das ist ein interessanter Ansatz.
Eher arge Selbstäuschung.
> Wie gesagt, wenn du nur jeden 7., 61.>und 446. ADC- Wert brauchst
Der OP verwechselt da einiges. Man kann vielleicht bei der FFT nur einen
Teil der Spektrallinien berechnen, weil der Rest physiologisch
uninteressant ist, aber dazu braucht man immer noch ein komplettes,
lückenloses Sample der Audiodaten.
>realisieren. Überlege mal, wenn du nach deinem Schema vorgehst hast du>446 ADC-Werte und benutzt nur 3 davon, d.h. 443 ADC-Wandlungen hast du>total umsonst gemacht da du die ja eh weg wirfst.
Allein bei DER Aussage würde ich verdammt stutzig werden. Wie soll man
aus eine handvoll Samples großartige FFT Informationen gewinnen?
Die Idee finde ich nicht schlecht vom TE. Er will im Prinzip drei FFTs
machen, einmal nur bis 416 Hz geht, einmal bis 2885 Hz und eine bis
20000 Hz. Und er will für jede FFT 14 Stützstellen haben. Also im
Prinzip ist das ja keine FFT sondern eine DFT, für eine FFT bräuchte man
Stützstellenanzahl die eine Potenz zur Basis 2 darstellen, z.B. 16
Stützstellen und nicht 14.
Wie er hier genau darauf kommt dann nur jeden 7. 61. und 446. ADC-Wert
zu benötigen kann ich aktuell auch noch nicht verifizieren. Auch wie er
darauf kommt, dass eine Wandlung etwa 13 ms benötigen soll. Für eine FFT
alleine schon bei 416 Hz wäre das viel zu langsam.
Ich würde entweder drei Arrays anlegen und jedes mit unterschiedlichem
ADC-Takt befüllen lassen oder aber halt nur ein Array anlegen, mit
maximalen ADC-Takt samplen und dann für jede FFT die entsprechenden
Werte aus dem Array picken.
ich lege im Prinzip 3 seperate Arrays an. Die sind nur in einander
verschachtelt. Dadurch spart man Messzeit. Ich benötige kein besonders
detailliertes Spektrum, daher nehme ich 3x8 Datenpunkte auf. Die Dauer
der jeweiligen Messung richtet sich nach der Periodendauer kleinsten
Frequenz. 1/(60hz) = 0,02 s. Bei einer äquidistanten Messung muss ein
Messwert alle 0,0028 s gemacht werden. Dadurch erreicht man eine obere
Frequenzschranke bei 2/0,0028 = 179 hz. Das heißt man benötigt nur alle
0,0028 s einen Messwert und da ich nicht wusste, dass man Messungen
anders timen kann, habe ich einfach sehr viele Messungen gemacht und
alle weggeworfen, die ich nicht benötige. Daher jede 7., 61., 446.
Mir sind aber in meinem ursprüglichen Post einige Fehler unterlaufen. 1.
ich habe nicht bedacht, dass eine Wandelung 13 Takte dauert und ich habe
auch vergessen, dass die Abtastrate doppelt so hoch sein, wie die
höchste Frequenz ist. Daher ergeben die Frequenzen alle keinen Sinn.
Mittlerweile bin ich dazu übergegangen 16-point FFTs zu machen. Der
Prozessor ist schnell genug die Daten in Echtzeit zu verarbeiten.
nordman schrieb:> Mittlerweile bin ich dazu übergegangen 16-point FFTs zu machen. Der> Prozessor ist schnell genug die Daten in Echtzeit zu verarbeiten.
Na dafür ist der locker schnell genug. Ich mach ja gar eine 128er FFT in
Echtzeit. Während er die FFT berechnet werden mittels Interrupt schon
die nächsten Werte gesampelt. Für die FFT braucht mein Atmega328 7,3 ms,
fürs Samplen der 128 Eingangswerte braucht er ~13 ms. Das klappt locker
in Echtzeit.
@ Michael Köhler (sylaina)
>Na dafür ist der locker schnell genug. Ich mach ja gar eine 128er FFT in>Echtzeit.
Bei einer handvoll Hz Samplerate ist das auch keine Kunst ;-)
Michael K. schrieb:> Wie er hier genau darauf kommt dann nur jeden 7. 61. und 446. ADC-Wert> zu benötigen kann ich aktuell auch noch nicht verifizieren.
Scheint mir ziemlich unmöglich. Ich poste hier mal drei gesamplete
Werte:
{ 0, 13, 42 }. Damit darf mir der OP erzählen welche Tasten ich auf
meinem Klavier gedrückt halte.