Ziel dieses Projektes ist die Realisierung einer Entfernungsmessung mit Ultraschall. Auf das Erläutern eventuell auftauchender Probleme sowie allgemeine Erklärungen wird hier verzichtet, diese Betrachtungen haben bereits hier statt gefunden.

Als Baugruppen werden Standardbauteile verwendet. Als Sender bzw. Empfänger dienen die Module UST-40T bzw. UST-40R, welche man über gängige Elektronik-Versender erhalten kann. Die Frequenzerzeugung für den Sender erfolgt mittels PWM durch einen Mikrocontroller. Die Auswertung des Empfangssignals erfolgt beispielsweise über den AD-Wandler des selben Mikrocontrollers.

VARIANTE 1

Sender

Somit ist der Senderteil an sich einfach, da nur per PWM ein 40kHz-Signal erzeugt werden muss, welches dann auf den Sender gegeben werden kann. Die Signalerzeugung sieht bei mir codetechnisch folgendermaßen aus:

void _40khz_init (void) {
    TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<WGM11);
    TCCR1B = (1<<WGM12) | (1<<WGM13) | (1<<CS10);
    OCR1A = 100;
    ICR1 = 200;
}

Das Funktionsprinzip der obigen Funktion ist im Prinzip identisch mit dem der Funktion zur 36kHz Träger-Erzeugung, welches bereits hier erklärt wurde. Durch "toggeln" (also An- bzw. Ausschalten) des Datenrichtungsregister-Bits für PB1 kann man nun kurze Ultraschall-Impulse senden.

Es gilt jedoch zu experimentieren, wie man die Sendereichweite auf ein ordentliches Maß bringen könnte. Hierzu ergeben sich theoretisch verschiedene Möglichkeiten.

Die Erzeugung des invertierten Signals kann entweder in Software oder über ein Logik-Gatter erfolgen. Geeignet wären beispielsweise NAND oder NOR. Da ich zufällig noch den Schaltkreis MOS4001 herumliegen habe, werde ich diesen verwenden. Hierbei handelt es sich um einen IC, welcher 4 NOR-Gatter mit je zwei Eingängen beinhaltet. Legt man bei einem NOR an beide Eingänge eine '1', so ergibt sich am Ausgang eine '0' und umgekehrt. Schematisch sähe der Anschluss des Senders dann so aus:

Empfänger

Nun zum nicht ganz so einfachen Empfängerteil. Wird ein Signal detektiert, so erhält man an den Klemmen des Empfängers ein relativ schwaches Wechselsignal. Dieses direkt auszuwerten ist nahezu unmöglich, da der AD-Wandler nicht für Wechselwerte geeignet ist sowie das Signal reichlich schwach ist. Es muss also gleichgerichtet werden. Bevor man dies machen kann, muss es verstärkt werden, da über der Gleichrichterdiode sofort wieder etwa 0,7V Flussspannung verloren gehen. Hierfür eignet sich der Schaltkreis TL084. Dieser stellt intern 4 OPVs zur Verfügung.

Nun immer der Reihe nach:

  1. Signalverstärkung und Herausfiltern von Störungen

    Die Signalverstärkung wird über die beiden angeschlossenen Widerstände vorgenommen und ergibt sich zu V = R2/R1. Der Kondensator C2 über R2 bildet einen Tiefpass, der Kondensator vor R1 einen Hochpass. Somit wurde insgesamt ein Bandpass realisiert, welcher mehr oder weniger selektiv das Nutzsignal (mit 40kHz) verstärkt.

    An den nicht invertierenden Eingang wird Vcc/2 gelegt, da ein Wechselsignal verstärkt werden soll und keine +/- 5V zur Verfügung stehen. Das Signal ist nun etwa um den Faktor 14 verstärkt.
     
  2. Erneute Signalverstärkung und Filterung

    Selbes Funktionsprinzip wie oben. Verstärkung des Signals um den Faktor 21.

     
  3. Gleichrichtung und Glättung

    Das nun ausreichend verstärkte Wechselsignal muss zur Auswertung noch gleichgerichtet und geglättet werden. Die Gleichrichtung wird durch eine Diode vorgenommen, die Glättung durch einen Tiefpass.

     
  4. Last but not least ...

    Zuletzt wird das Signal noch auf einen OPV gegeben, welcher als Spannungsfolger geschalten ist. Diese Maßnahme dient lediglich dem Abkoppeln des Signal-Out-Pins von der restlichen Schaltung. Das Signal wird um den Faktor 1 verstärkt.

Eine experimenteller Versuchsaufbau hat nun folgende Daten zutage gefördert. Mit ausgeschaltetem Sender liegt am Ausgang der Empfängerschaltung immer eine Spannung von 1,850V an. Diese ist als Offset zu betrachten. Bewegt man nun den Sender über dem Empfänger, so erhält man einen Minimalwert von 1,35V. Dieser ist aufgrund der Richtungswirkung des Senders (Ultraschallkeule) stark positionsabhängig. Typische Werte am Empfängerausgang sind etwa 1,5-1,7V. Alle gemessenen Werte beziehen auf den ersten Punkt zum Thema Senderaufbau, welcher oben bereits dokumentiert wurde. Eine Zuführung des invertierten Signals brachte leider keine wesentliche Verbesserung.

Nachdem der Aufbau soweit geklärt ist, kann sich jetzt an die Programmierung gemacht werden.

Programmierung

Nachdem Sender und Empfänger nebeneinander auf einer oder mehrerer Platinen angeordnet wurden, kann man sich nun an die Ultraschalldistanzmessung begeben. Zu beachten ist lediglich, dass sich die beiden Gehäuse nicht berühren. Man kann zusätzlich noch etwas Plaste, Metall, o.ä. zwischen ihnen befestigen, um ein direktes Übersprechen möglichst zu verhindern.

Wie die Erzeugung des 40kHz-Signals erfolgt wurde oben bereits angegeben. Nun muss ein kurzer Schallimpuls erzeugt werden. Dieser sollte in etwa 2-3ms lang sein und kann mittels Timer oder delay-Schleife gesteuert werden. Das Prinzip ist trivial, da man einfach den entsprechenden Pin als Ausgang deklariert, kurz wartet und ihn dann wieder als Eingang definiert.
Da alle Operationen von einem MC ausgeführt werden sollen und der Empfänger die Laufzeit des Signals soundso exakt bestimmen muss, wird ein Timerinterrupt verwendet. Es wird Timer0 verwendet.
Die Schallgeschwindigkeit beträgt bei Raumtemperatur etwa 344 m/s. Bei einer Pulslänge von 2ms hat die Spitze der Schallwelle bei Beendigung des Impulses bereits 0,68m zurück gelegt. Somit ist der Sensor nur für Distanzen größer 35-40cm geeignet. Sollen geringere Distanzen ausgewertet werden, muss der Schallimpuls entsprechend kürzer gestaltet werden. Je kürzer dieser allerdings gemacht wird, desto größer sollte die Sendeleistung sein, wenn man noch etwas zum Auswerten haben möchte.

Ich habe das ganze mal testweise implementiert und es stellte sich die gewünschte Funktionalität ein. Allerdings sind die Messwerte mit einem gewissen Rauschen unterlegt, so dass sich eine Mehrfachmessung und/oder Mittelwertbildung empfiehlt. Hier nun der Sourcecode.

Das Programm macht im wesentlichen folgendes:

Bei auf dem Schreibtisch liegendem Sensor ergab sich für einen Schallimpuls Richtung Decke das folgende Bild:

Nimmt man Datenpunkt 250 als Mitte des Echos an, so ergibt sich eine Signallaufzeit von 250*(1/(8MHz/256))= 8ms. Dies entspricht einer Distanz von s = 0,5*v*t = 0,5*340*0,008 = 1,36m. Addiert man nun noch die 2ms des Impulses dazu (es wird ja erst nach dessen Aussenden mit der Abtastung begonnen), so ergibt sich eine Distanz von 1,7m, welches im Prinzip der exakte Wert ist.

Für einen Impuls von 1ms Länge ergibt sich das folgende Bild:

Man sieht, dass das Echo nun nur noch 1ms lang ist, eine Auswertung kann aber noch vorgenommen werden.

Als Mögliche Verbesserungen fallen mir diverse Punkte ein. Beispielsweise könnte man eine feinere Abtastung des empfangenen Signals vornehmen. Dann muss angefangen werden, zwischen Echos und dem real reflektierten Signal zu unterscheiden. Auch kann man sicherlich an der Schaltung (Verstärkungen) und dem allgemeinen Layout noch Optimierungen vornehmen.
Sobald ich entsprechende Fortschritte gemacht habe, werden diese natürlich hier veröffentlicht.

VARIANTE 2

Alternativ habe ich noch eine zweite Variante zur Distanzmessung anzubieten. Diese basiert nicht auf einer dauernden AD-Wandlung des empfangenen Signals sondern ähnelt mehr einem Schwellwert-Schalter.

Das Signal wird zunächst mit Hilfe von zwei Verstärkerstufen (OPVs) verstärkt. Danach folgt ein dritter OPV, dessen Widerstand am Eingang als Poti realisiert ist(50K). Der Widerstand im Rückkopplungszweig hat einen Wert von 50k. Es lässt sich somit eine Verstärkung zwischen 1 und 50 einstellen. Der Ausgang des 3. OPV geht direkt auf die Basis eines npn-Transistors. Zusätzlich wird noch mittels eines weiteren Potentiometers eine Offsetspannung auf die Basis gegeben, um das Umschalten zu unterstützen. Kommen als zu der Offsetspannung noch die Signalspitzen, so schaltet dieser durch. Diesen Vorgang kann man mittels eines angeschlossenen Mikrocontrollers detektieren.
Wiederum ergibt sich die Distanz aus der Zeit zwischen dem Senden des Impulses und dem Schalten des Transistors.

Die Senderoutine kann im Prinzip komplett von Variante 1 übernommen werden.

Mit dem Start der Senderoutine wird gleichzeitig ein Timer gestartet, in welchem eine Zählvariable inkrementiert wird. Trifft der Impuls ein (Erkennung bspw. durch externen Interrupt), so kann der Timer gestoppt werden und die Zählvariable ausgewertet werden. Ihre Größe ist ein direktes Maß für die Distanz. Überschreitet sie einen bestimmten Wert, so kann die Messung als gescheitert betrachtet werden und der Zähler muss zurück gesetzt werden.
Natürlich können mehrere Interrupts auftreten, für deren Auswertung es wieder einen geeigneten Algorithmus zu finden gilt.

Eine simple Implementierung ohne weitere Auswertealgorithmen kann man hier bekommen.

 

Zurück zur Startseite.