Hallo zusammen. Ich möchte per µC die Schallgeschwindigkeit durch Laufzeitmessung per Lautsprechr und Mikrophon bestimmen. Atmega8, 16Mhz, LS an C5, Taster an B3, Mic an B0(ICP) Leider bekomme ich 1. komplett falsche ergebnisse (Trägheit von Mikrophon und LS würde ich später noch abziehen) 2. Die messung ist komsich: LS und Mic nah zusammen: Zeit groß LS und Mic weiter auseinander: Zeit wird kleiner LS und Mic noch weiter auseinander:Zeit wird noch kleiner LS und Mic noch weiter auseinander:Zeit wird noch kleiner LS und Mic noch weiter auseinander:Zeit nimmt wieder zu LS und Mic noch weiter auseinander:Zeit nimmt noch mehr zu Sieht irgendjemand fehler im code? Wie kann ichs besser machen? Vielen Dank Cu Hurra
Keine Ahnung da ich noch nicht viel mit Timer/Counter gemacht habe aber sollte ICR1 nicht in SIG_INPUT_CAPTURE1 gerettet werden? CLI in SIG_INPUT_CAPTURE1 unterdrückt zwar weiter Interrupts aber ICP1 ist nachwievor aktive und generiert durch Echos etc. weitere Captures... ausm Datenblat: When a change of the logic level (an event) occurs on the Input Capture Pin (ICP1), and this change confirms to the setting of the edge detector, a capture will be triggered. When a capture is triggered, the 16-bit value of the counter (TCNT1) is written to the Input Capture Register (ICR1). The Input Capture Flag (ICF1) is set at the same system clock as the TCNT1 value is copied into ICR1 Register. If enabled (TICIE1 = 1), the Input Capture Flag generates an Input Capture interrupt. The ICF1 Flag is automatically cleared when the interrupt is executed.
Ich würde es folgendermaßen machen (habe mir Deinen Code nicht angesehen). Zunächst überlegst Du Dir, mit welchen Zeiteinheiten Du es zu tun hast. Die hängen von den Strecken ab, die in Deiner Messung auftreten. Nehmen wir als "charakteristische Länge" 1 cm. Die Strecke 1 cm wird von Schall in der Zeit t = s/c = 1E-2 m/(340 m/s) = 29.4 µs durchlaufen. Während 29.4 µs kann ein mit 16 MHz getakteter AVR-µC noch über ca. 200 Instruktionen abarbeiten. Hier sind wir also noch auf der sicheren Seite. Als sinnvolle Zeitbasis können wir 10 µs festsetzen, was einer Streckenauflösung von 3.4 mm entspricht. Das sollte in Ordnung sein. Nun programmierst Du einen Timer so, daß er alle 10 µs "tickt". Das ist easy: TC1 des ATmega8 läßt Du im CTC-Modus laufen (CTC = clear on timer compare). Der Counter läuft mit dem Systemtakt (Prescaler-Wert = 1) von 16 MHz, und sein Compare-Wert muß auf 16 MHz * 10 µs = 160 gesetzt werden. Bei jedem Erreichen von 160 wird die entsprechende ISR "TC1 compare match" aufgerufen, und TC1 automatisch resettet. In dieser ISR wird ein Zähler - die "Uhr" - hochgezählt; ansonsten passiert darin nichts. Ein 8-Bit-Register reicht für die Uhr jedoch nicht aus, weil es maximal bis 255 zählt und Du damit auf die Strecke 255 * 3.4 mm = 867 mm begrenzt wärst. Der Zähler muß also 16-bittig ausgelegt werden, was bedeutet, daß Du zwei Register dafür spendieren mußt. Damit könntest Du dann Entfernungen messen bis max 255^2 * 3.4 mm = 221 m. Ob der 16-bittige Uhrenzähler in der ISR hochgezählt wird oder nicht, wird von einer booleschen Zustandsvariablen "MeasRun" abhängig gemacht. Die ISR sieht damit so aus (UL, UH = die Uhrenregister; _1 = ein Register, das konstant 1 ist; _0 = ein Register, das konstant 0 ist): ;------------------------------------ TC1CompareMatch: (obligatorische Sicherung des SREG) Wenn MeasRun=TRUE dann { add UL, _1 adc UH, _0 } (obligatorische Wiederherstellung des SREG) reti ;------------------------------------ Diese ISR wird also alle 10 µs durchlaufen. Wie der Rest des Programms aussieht, sollte klar sein: Es wird auf einen Tastendruck gewartet. Sobald der auftritt, wird 1. ein Impuls auf den Lautsprecher gegeben, der ein Knack verursacht, und 2. "MeasRun" auf TRUE gesetzt. Anschließend wird gewartet, bis das Mikrofon den Knack registriert. Geschieht dies, wird "MeasRun" wieder auf FALSE gesetzt (damit ist es auch nicht nötig, den Timer zu "deaktivieren"; er kann permanent laufen). Im Uhren-Register-Paar UL:UH steht jetzt direkt die Anzahl der vergangenen 10 µs. Gib den Wert auf Dein LCD aus (nach binär-zu-BCD-Umwandlung; 16 bit = 5 Stellen dezimal), und setz einen Dezimalpunkt an die passende Stelle. Dann bekommst Du nämlich im Display die "echte" Zeit in Millisekunden angezeigt; das war nämlich der Sinn der Sache mit der 10 µs-Zeitbasis. Wenn Du jetzt noch vor jeder Messung den theoretischen Laufzeit-Wert gemäß t = s/c berechnest, dann weißt Du schon vorher, welcher Wert (ungefähr) im Display erscheinen sollte (toll, was?), und falls die Meßwerte völlig daneben sind, kannst Du nach dem Grund dafür suchen.
Korrektur: Wie der Rest des Programms aussieht, sollte klar sein: Es wird auf einen Tastendruck gewartet. Sobald der auftritt, wird 1. ein Impuls auf den Lautsprecher gegeben, der ein Knack verursacht, 2. das Uhren-Register-Paar UH:UL auf Null gesetzt, und 3. "MeasRun" auf TRUE gesetzt.
Hallo Danke an Santa Klaus für deine Ausführungen. Wenn es gar nicht mit "meiner" Methode klappen sollte werde ich mal deinen Weg probieren. Jetzt schauts soweit aus, dass ich mit größerem Abstand auch größere Zeitwerte bekomme. Ich habe ejtzt noch 2 Probleme: 1. Die Trägheit. Bis der Lautsprecher reagiert und bis das Microphon reagiert. Wenn ich Lautsprecher und Mikrophon zu nahe (<5cm) zusammenlege bekomme ich wieder größere Zeiten als bei 5cm. Dort ist wohl vom Lautsprecherbau bedingt ein "Schallloch"). Wenn 2. geöst ist, kann ich ja einfach die Trägheitszeit des Aufbaus ausrechnen. 2. Wie rechne ich meine µC-Schritte richtig in "echte" Zeit um? Mein Timer läuft mit nem Prescaler von 8. Also, ein Timerschritt=8/(1*10^6) richtig? Vielen Dank
Mal so ne Bemerkung von der praktischen Seite: Wenn du das Starten des Zeitstoppens mit einem gleichen Mikrofon direkt am Lautsprecher machen würdest, würde das dann das andere Mikro+Verzögerung ausgleichen. Außerdem kannste damit die Zeit ausschließen, die zur Tonerzeugung notwendig ist (ich weis nich wie lang die ist :)) dave
Hallo nochmal, >1. Die Trägheit. Bis der Lautsprecher reagiert und bis das Microphon >reagiert. Wenn ich Lautsprecher und Mikrophon zu nahe (<5cm) >zusammenlege bekomme ich wieder größere Zeiten als bei 5cm. Dort ist >wohl vom Lautsprecherbau bedingt ein "Schallloch"). ja, das halte ich für möglich. Ich rate Dir generell davon ab, das Mikrofon jemals "ganz dicht" vor den Lautsprecher zu bringen (absolute untere Grenze für den Abstand M-LS sollte der Durchmesser der LS-Membran sein). Über das, was es dort registrieren würde, kannst Du einfach keine vernünftige Annahme machen. Wie Du die Messung "wissenschaftlich korrekt" durchführen kannst, habe ich Dir ja schon geschrieben: Viele Messungen mit unterschiedlichen Abständen machen (z. B. von 1 m bis 5 m in 10-cm-Schritten); aus den Meßpunkten die Ausgleichsgerade berechnen (alternativ nach Augenmaß auf Millimeterpapier zeichnen); Steigung der Ausgleichsgerade = Schallgeschwindigkeit; ihr y-Achsen-Abschnitt = Verzögerungszeit. Das sind die beiden Werte, die Dein Experiment liefert. 2. Wie rechne ich meine µC-Schritte richtig in "echte" Zeit um? >Mein Timer läuft mit nem Prescaler von 8. > >Also, ein Timerschritt=8/(1*10^6) >richtig? Ich denke, Dein µC läuft mit 16 Mhz? Bei 1 MHz dauert ein QUARZtakt 1 µs; bei 16 MHz dauert er 1/16 µs = 0.0625 µs. Bei einem Prescalerwert von 8 dauert ein TIMERtakt dann logischwerweise das 8-fache davon, also 0.5 µs. Das heißt: Wenn Du alle im Display angezeigten Werte halbierst, dann hast Du die Zeiten in der Einheit µs. Gib mal, wenn Du Lust hast, ein paar Meßwerte bekannt. Kommst Du in die Nähe von c = 340 m/s?
Hallo hurra, zum Thema Trägheit: Angenommen, der Lautsprecher hat eine obere Grenzfrequenz von 20kHz. Dann ist die Verzögerung Deiner Flanke größenordnungsmäßig 50us (Kehrwert von 20000Hz), denn so schnell kann die Membran nun mal schwingen. Angenommen, Dein Mikro hat die gleiche Bandbreite, dann verzögert es um den gleichen Wert, und Dein uC merkt absolut nichts von Verzögerungen. mfg Frank PS: Ich hab sowas auch mal gemacht und nur Unsinn gemessen, bis ich gemerkt habe, dass diese Methode im Grunde nur auf dem freien Feld (d.h. ohne störende Reflexionen von Decke, Boden und Wänden) funktioniert. Ich schlage vor, dass Du das Mic.-Signal gleichrichtest und integrierst, bevor Du in den uC-Eingang gehst.
>das Mic.-Signal gleichrichtest und integrierst gleichrichten verstehe ich (um sich keine Gedanken über die Phasenlage des Mic machen zu müssen) aber wozu integrieren? Es wird doch auf die Erste Flanke getriggert >störende Reflexionen von Decke, Boden und Wänden desswegen wird hierfür bevorzugt Ultraschall Piezos genommen, von wegen die bessere Richtwirkung höherer Frequenzen... @hurra versuch mal im Nahbereich die Lautstärke zu Vermindern, vielleicht hast du Übersteuerungseffekte (falls dein Mic ein Inv. Signal liefert). Könntest du wenn alles soweit ist deine erzielte reproduzierbare Genauigkeit berichten?
>Angenommen, Dein Mikro hat die gleiche Bandbreite, dann >verzögert es um den gleichen Wert, und Dein uC merkt absolut nichts von >Verzögerungen. Das verstehe ich nicht. Wenn der LS und das M gleich lange um T verzögern, dann hast Du doch insgesamt die Verzögerung 2 T, weil sich alle Verzögerungen, die irgendwo auftreten, addieren. Die heben sich doch nicht gegenseitig auf?! Und der µC "merkt" sowieso nichts von Verzögerungen - der merkt nur, daß das Signal am Mikrofon-Pin irgendwann von 0 auf 1 wechselt. "Sichtbar" werden die Verzögerungen erst für den Experimentator, wenn er sich die Meßwerte plottet: Die Gesamt-Verzögerungszeit macht sich als Offset der t(s)-Gerade bemerkbar.
An Santa Klaus: >Das verstehe ich nicht. Wenn der LS und das M gleich lange um T >verzögern, dann hast Du doch insgesamt die Verzögerung 2 T, weil sich >alle Verzögerungen, die irgendwo auftreten, addieren. Die heben sich >doch nicht gegenseitig auf?! Du hast Recht, ich hab Unrecht. (Wie ich auf den Unsinn gekommen bin, siehst Du unten) An Kupfer-Michi: >gleichrichten verstehe ich (um sich keine Gedanken über die Phasenlage >des Mic machen zu müssen) aber wozu integrieren? Es wird doch auf die >Erste Flanke getriggert Dein Einwand erinnert mich daran, wie ich das damals gelöst habe. Es ist nicht die erste Flanke, auf die <hurra> triggert, sondern die einzige. Das genau ist das Problem. Eine einzige Flanke transportiert sehr wenig Energie und geht möglicherweise im Rauschen unter. Ich habe schließlich ein kurzes Paket aus vielleicht 100 Schwingungen gesendet und mit zwei Mikrofonen (Start/Stopp der Messung) gearbeitet, deren Signale wie oben beschrieben auch über die Pulslänge integriert wurden. Dann kompensieren sich auch die beiden Verzögerungen bei Start und Stopp tatsächlich. Das ist auch nötig, weil die Integration ja schließlich zusätzlich verzögert. mfg Frank
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.