Forum: Mikrocontroller und Digitale Elektronik Frequenzmessung Audiosignal


von Martin (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich versuche seit ein paar Tagen eine einfache Tonfrequenz, die der PC 
ausgibt, mit einem ATMEGA32 zu erfassen. Der Ton hat jeweils eine feste 
Frequenz (Bereich etwa 200Hz - 20.000Hz), die mein Multimeter auch 
problemlos erkennt.
Nach durchforsten vieler Forenbeiträge habe ich mir zunächst die 
Schaltung im Anhang gebastelt. Der Schaltplan ist mehr schematisch 
gedacht (und übrigens das erste was ich mit Eagle gemacht habe).

Als erstes habe ich Beitrag "Verständnisfrage Audiosignal"
entnommen, wie ich die Ausgangsspannung am Kopfhörerausgang vom 
Gleichspannungsanteil befreie und in den positiven Bereich verschiebe. 
Bei mir sollte die Spannung jetzt um 2.5V schwingen.

Um die Frequenz jetzt zu messen, habe ich versucht den Komparator zu 
nutzen: 2,5V (in Wahrheit etwas mehr, da mit Poti eingestellt) als 
Referenzspannung und mit dem verschobenen Ausgangssignal wird 
verglichen.
Der Komparator ist mit dem Input Capture Interrupt des Timer1 verbunden 
und aus der Zeit zwischen zwei Interrupts soll die Frequenz berechnet 
werden.
Der entsprechende Code ist im Anhang, leicht abgewandelt aus einem 
anderen Forenbeitrag, und soll dies machen: Bei einer Frequenz über 
5000Hz die LED anschalten, ansonsten ausschalten (testhalber..).

Was jetzt allerdings passiert ist Folgendes: Die LED leuchtet bei jeder 
beliebigen Frequenz, wird keine Frequenz ausgegeben leuchtet die Lampe 
nicht.

Hat jemand eine Idee wo der Fehler liegen könnte? Noch irgendwelche 
Register nicht gesetzt? Ab und zu scheint auch mal EndTime=StartTime zu 
sein. Werden manchmal Interrupts derart schnell hintereinander 
ausgeführt, dass sie zur selben Zeit aufgezeichnet werden? Aber auch 
wenn ich nur diesen Fall im Code ausklammere, leuchtet die LED noch bei 
allen Frequenzen.

Vielen Dank für Eure Hilfe
Martin

von MaWin (Gast)


Lesenswert?

> Erg = (NrOverflows * 65536) + EndTime - StartTime;
> Erg = F_CPU / Erg;       // f = 1 / t

Du hast einen 32 bit AVR ?

von m.n. (Gast)


Lesenswert?

Martin schrieb:
> leicht abgewandelt aus einem
> anderen Forenbeitrag,

Nimm mal das Original (Link?) und sieh nach, ob es damit geht.

von Martin (Gast)


Lesenswert?

Hmm wo ist denn das Problem dann? Abgesehen davon, dass selten 
overflow-Interrupts auftreten sollten bei den frequenzen, hat der timer1 
doch 16 bit und es müsste alles in den double passen?

Danke für deine Antwort!
Martin

von Martin (Gast)


Lesenswert?

Der Originallink ist hier:
Beitrag "Input Capture Pin (ICP) auslesen ( Frequenz messen)"
Habe hier gerade kein display um exakt den code zu testen. Da wird 
allerdings auch nicht der Komparator genutzt.

von m.n. (Gast)


Lesenswert?

Die Software vom Original-Link ist etwas schlicht.
Vielleicht kannst Du mit folgedem Beispiel etwas anfangen: 
Beitrag "einfache Drehzahlmessung mit ATmega88"
Die Routinen für die LCD-Anzeige können komplett entfallen, wodurch der 
Code deutlich kompakter wird.
Die Variable 'frequenz' kannst Du direkt verwenden; die Skalierung auf 
U/min passiert erst in der Ausgaberoutine.

von MaWin (Gast)


Lesenswert?

Martin schrieb:
> es müsste alles in den double passen?

Dir fehlen C Grundkenntnisse?

Es wird nicht mit 65536.0 multipliziert, oder 4000000.0 dividiert.

Und man täte das auch besser nicht.

von Martin (Gast)


Lesenswert?

Das habe ich sogar schon probiert, löste das Problem aber leider nicht. 
Aber du hast natürlich recht, die ".0" gehören dran.
Danke!

von Martin (Gast)


Angehängte Dateien:

Lesenswert?

So, ich habe es jetzt nochmal mit dem Code von m.n. probiert.
Die abgewandelte Version befindet sich im Anhang, allerdings sind im 
wesentlichen nur die LCD-Routinen raus.
Ich habe so langsam keine Idee mehr woran es liegen könnte. Der Code 
müsste ja zumindest funktionieren? Beide Interrupt-Routinen werden 
angesprungen.
Die LED leuchtet jedoch bei für mich relativ willkürlichen Frequenzen 
(aber reproduzierbar) und nicht (nur) im abgefragten Frequenzintervall.
Vielleicht ein Fehler in der Schaltung? Am Komparator kommen laut 
Multimeter aber die richtigen Frequenzen an..

Ich werde es am Wochenende mal mit LCD probieren und sehen was da 
ausgegeben wird.

Hat noch jemand eine Idee dazu?

Vielen Dank und viele Grüße
Martin

von m.n. (Gast)


Lesenswert?

Martin schrieb:
> Die LED leuchtet jedoch bei für mich relativ willkürlichen Frequenzen
> (aber reproduzierbar) und nicht (nur) im abgefragten Frequenzintervall.
> Vielleicht ein Fehler in der Schaltung? Am Komparator kommen laut
> Multimeter aber die richtigen Frequenzen an..

Laß die LED doch zunächst blinken, wie es in der ISR(TIMER1_OVF_vect) 
ursprünglich der Fall ist. Bei fortlaufender Messung müßte sie dreimal 
pro Sekunde aufleuchten und anzeigen, dass die Messungen periodisch 
stattfinden.

Nebenbei: hast Du den richtigen Prozessor in der IDE angewählt? An den 
include-Dateien kann man das ja nicht erkennen.

von Martin (Gast)


Lesenswert?

Hallo nochmal und danke für die Antworten,
ich habe es inzwischen mit LCD und LED versucht und folgendes passiert: 
Die LED blinkt in regelmäßigen Abständen und es werden entsprechend die 
Messungen auf dem LCD ausgegeben. Die angezeigten Frequenzen passen 
jedoch nur von etwa 12kHz bis 19kHz. Passen bedeutet hier plus minus 
400Hz.
Bei 20kHz zeigt er dann aber z.b. 23kHz. Unter 12kHz ist nichteinmal ein 
lineares Verhalten zwischen angelegter Frequenz und gemessener Frequenz 
zu beobachten. Z.B. bei 1kHz werden 5kHz angezeigt, bei 2kHz werden 3kHz 
angezeigt.
Das ganze funktioniert nur bei vollaufgedrehtem Lautsprecher, sonst wird 
die Untergrenze (12kHz) höher.
Fällt da noch jemandem was auf? Kann es vielleicht am Kondensator 
liegen, der am Eingang des Signals liegt und den Gleichanteil 
rausfiltert? Habe da einen 1u Kondensator, zu wenig?
Das Multimeter zeigt eine Wechselspanung von 0,3V an, das müsste dem 
Komparator doch als Unterschied genügen? Die Vergleichsspannung liegt 
auf 2,50V und ohne angelegte Frequenz liegt die Signalspannung bei 
2,48V. Bei abgeschalter Frequenz zeigt die Anzeige Werte <25Hz.

Vielen Dank für jede Hilfe und schöne Grüße
Martin

von m.n. (Gast)


Lesenswert?

Du mußt zwischen Signalaufbereitung und Messung unterscheiden.
Sowie ich das sehe, funktioniert die Messung, aber Dein Signal besteht 
nicht aus einer separaten Frequenz.

Als einfachen Test schlage ich vor, das Signal eines 
Sinus/Rechteckgenerators anzulegen und direkt zu messen. Im Grunde 
reicht ein CMOS-Schmitttrigger mit üblicher RC-Beschaltung, wobei R aus 
einem Poti 1M+10k in Reihe die Frequenz in einem gewissen Bereich 
durchstimmbar macht.
Das muß 'saubere' Frequenzen und stabile Anzeigen zur Folge haben.

Als nächstes mußt Du sicherstellen, dass das Audiosignal auch nur aus 
einer Frequenz besteht. (Das hat nichts mit irgendeinem Lautsprecher zu 
tun, der irgendwo voll aufgedreht wird.)
Der Analog-Komparator des ATmega unterscheidet zwar Pegel ab einigen 
10mV, hat aber intern keine Hysterese, die Störungen kleiner Amplitude 
unterdrücken kann.
Hier würde ich zunächst einen Tiefpass vom ANx vorschlagen, der 
überlagertes Rauschen unterdrückt.
Vermutlich hast Du kein Oszilloskope, womit man sofort die Kurvenform am 
Eingang sehen könnte.

von Martin (Gast)


Lesenswert?

Hi,
ich sehe das auch so, dass die Messung funtkioniert, nur das Signal 
vermutlich nicht so ist wie ich es haben möchte.
Ich gebe allerdings tatsächlich softwareseitig am PC nur eine Frequenz 
aus, leider habe ich wirklich kein Oszilloskop, um mir das Signal direkt 
anzusehen.
Wenn ich eine Frequenz von 2kHz ausgebe und mit einem Multimeter an den 
beiden Pins für den Komparator messe, zeigt es exakt 2kHz an. Deshalb 
wundert mich etwas, warum die Mikrocontrollermessung das dann nicht 
ausgibt. Vermutlich wird das im Multimeter noch etwas aufwändiger 
gemacht, also das Signal intern noch weiterbearbeitet?

Mit dem voll aufgedrehten Lautsprecher meinte ich, dass ich die 
Amplitude maximieren muss für die besten Messergebnisse. Wollte mich nur 
nochmal vergewissern, dass der Spannungsunterschied von 0,3V eigentlich 
reichen müsste (,weil es eben bei kleinerer Amplitude deutlich 
schlechter wurde).

Leider habe ich keinen Schmitttrigger oder einen OPV aus dem ich mir 
einen basteln könnte. Vielleicht funktioniert zum Testen ein einfaches 
An- und Ausschalten eines Pins des Mikrocontrollers.


Danke und Viele Grüße
Martin

von Martin (Gast)


Lesenswert?

Hallo nochmal,

der entscheidende Tipp war ein Tiefpass! Ich habe jetzt einfach 
testhalber mal einen Tiefpass aus R=1kOhm und C=10nF vor den Eingang des 
Komparators geschaltet und die Messung funktioniert im Bereich von etwa 
50Hz bis 20kHz, also etwa dem Bereich, den man von einer Soundkarte 
erwartet (einen größeren Bereich kann ich also gar nicht testen).

Vielen Dank für die Hilfe, besonders an m.n.!
Martin

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.