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