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