Forum: Mikrocontroller und Digitale Elektronik Falsche Zeiten bei Schallmessung


von hurra (Gast)


Angehängte Dateien:

Lesenswert?

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

von Kupfer Michi (Gast)


Lesenswert?

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.

von Hubert (Gast)


Lesenswert?

Timer-Überlauf würde dazu passen

von Santa Klaus (Gast)


Lesenswert?

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.

von Santa Klaus (Gast)


Lesenswert?

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.

von hurra (Gast)


Angehängte Dateien:

Lesenswert?

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

von dave (Gast)


Lesenswert?

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

von Santa Klaus (Gast)


Lesenswert?

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?

von Frank Simon (Gast)


Lesenswert?

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.

von Kupfer Michi (Gast)


Lesenswert?

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

von Santa Klaus (Gast)


Lesenswert?

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

von Frank Simon (Gast)


Lesenswert?

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