Table of Contents

Ultraschall-Entfernungsmesser

Notwendiges Wissen: [HW] Controller module, [HW] lcd, [AVR] Counters/Timers, [LIB] Timers, [LIB] Alphanumeric LCD, [LIB] Sensors

Theorie

Ultraschall-Entfernungsmesser SRF04

Ein Ultraschall-Entfernungsmesser bestimmt die Entfernung zu einem Objekt, indem er die Zeit misst, die ein Schall zu einem Objekt hin und zurück benötigt. Die Frequenz des Geräusches liegt im Bereich des Ultraschalls. Dies garantiert, dass die Schallwelle gebündelt gelenkt wird, da sich hochfrequenter Schall weniger in der Umgebnung zerstreut. Ein typischer Ultraschall-Entfernungsmesser besteht aus zwei Membranen. Eine Membran produziert den Schall, die andere empfängt das Echo. Im Grunde besteht er also aus einem Lautsprecher und einem Mikrophon. Der Schallgenerator generiert kurze (wenige Perioden umfassende) Ultraschallimpulse und startet den Timer. Die zweite Membran registriert die Ankunft des Echos und stoppt den Timer. Mit der Zeit des Timers ist es möglich, die zurückgelegte Entfernung des Schalls zu berechnen. Die Entfernung zu einem Objekt entspricht der Hälfte der zurückgelegten Entfernung des Schalls.

Funktionsweise eines Ultraschall-Entfernungsmessers.

Der Ultraschall-Entfernungsmesser findet im täglichen Leben eine Vielzahl von Anwendungsmöglichkeiten. Er wird beispielsweise als Ersatz für Maßbänder auf Baustellen eingesetzt, Autos besitzen Ultraschall-Entfernungsmesser als Parksensoren. Neben der Entfernungsmessung dient er auch dazu, das bloße Vorhandensein eines Objekts im Messbereich zu erkennen, z. B. in der Gefahrenzone einer Arbeitsmaschine. Sind Ultraschalltransmitter und -empfänger getrennt, kann die Fließgeschwindigkeit des Materials zwischen ihnen bestimmt werden, da Schallwellen langsamer aufwärts fließen.

Übung

Das HomeLab enhält einen Devantech SRF04/SRF05 Ultraschall-Entfernungsmesser. Der SRF04/SRF05 ist jedoch nur ein Sensor und gibt keine direkte Information über die Distanz. Neben den Stromversorgungspins besitzt der Sensor auch einen Trigger- und einen Echo-Pin. Ist der Trigger-Pin “high”, generiert der Sensor eine acht Perioden lange 40 kHz Ultraschallwelle. Daraufhin wird der Echo-Pin “high” und bleibt “high”, bis das Echo zurück kommt. Das Echo-Signal gibt also generell die Zeit an, die der Schall benötigt um das Objekt zu erreichen und zum Sensor zurück zu kommen. Die Entfernung zum Objekt ergibt sich daraus, dass die gemessene Zeit mit der Schallgeschwindigkeit multipliziert und dann durch zwei dividiert wird. Der folgende Graph zeigt den Zusammenhang zwischen Zeit und den Signalen des Empfängers, Triggers und des Echos:

Die Signale des SRF04

Um den SRF04/SRF05 mit dem AVR zu nutzen, müssen Trigger- und Echo-Pin an den AVR Pins angeschlossen werden. Zur Zeitmessung, sollte ein 16-Bit Timer genutzt werden, z.B. timer3. Nachfolgend ist eine Funktion dargestellt, die alle Messvorgänge ausführt - sie generiert das Signal des Triggers, startet den Timer, misst die Länge des Echosignals und konvertiert dies zur Entfernung in Centimetern. Die Funktion blockt, das bedeutet sie hält den Prozessor beschäftigt, bis die Messung abgeschlossen ist oder zu lange dauert. Je schneller das Echo ankommt, desto schneller erhält man ein Ergebnis. Falls kein Echo ankommt, wartet die Funktion 36 ms und geht dann auf 0 zurück. Es ist wichtig zwischen den Messungen eine Pause von mindestens 20 ms Pause einzuhalten, um den Soundgenerator komplett zum Stillstand kommen zulassen, so dass die neue Messung nicht durch die alte beeinträchtigt wird. Außerdem sollte darauf geachtet werden, dass die Schallwellen sich nicht gegenseitig stören, wenn verschiedene Ultraschallsensoren gleichzeitig genutzt werden.

#define ULTRASONIC_SPEED_OF_SOUND 33000 // cm/s
 
//
// Sofortige Ultraschall-Entfernungsmessung
//
unsigned short ultrasonic_instant_measure(pin trigger, pin echo)
{	
	// Pin-Setup
	pin_setup_output(trigger);
	pin_setup_input_with_pullup(echo);
 
	// Timer 3 auf den normalen Modus setzen
	// mit der Periode des F_CPU / 8
	timer3_init_normal(TIMER3_PRESCALE_8);
 
	// Erzeugung des Aulöse-Impulses
	pin_set(trigger);
 
	// Timer zurücksetzen
	timer3_overflow_flag_clear();
	timer3_set_value(0);	
 
	// ~10 us warte
	while (timer3_get_value() < 18) {}
 
	// Auslöse-Impuls beenden
	pin_clear(trigger);
 
	// Warten auf den Echo-Start
	while (!pin_get_value(echo))
	{
		// Timeout ?
		if (timer3_overflow_flag_is_set())
		{
			return 0;
		}
	}
 
	// Timer erneut zurücksetzen
	timer3_set_value(0);
 
	// Warten auf Beendigung des Echos	
	while (pin_get_value(echo))
	{
		// Timeout ?
		if (timer3_overflow_flag_is_set())
		{
			return 0;
		}
	}
 
	// Konvertierung von Zeit in Entfernung:
	//   Entfernung = Timer * (1 / (F_CPU / 8)) * Geschwindigkeit / 2
	return (unsigned long)timer3_get_value() *
		ULTRASONIC_SPEED_OF_SOUND / (F_CPU / 4);
}

Die gegebene Funktion erlaubt dem Nutzer den Echo-und den Trigger-Pin so zu wählen, dass der Sensor dort angeschlossen werden kann wo es am günstigesten ist und genug Platz vorhanden ist. Zusätzlich erlaubt dies, die Funktion auch außerhalb von HomeLab zu nutzen. Die dargestellte Funktion ist bereits in der HomeLab Library enthalten und muss somit nicht geschrieben werden. Es gibt noch eine Sache zu beachten: Die Funktion in der Library ist streng an die Taktrate des Controller-Moduls von HomeLab gekoppelt. Die Taktrate beträgt 14,7456 MHz, wenn die Funktion mit anderen Taktraten genutzt wird, liefert sie falsche Ergebnisse. Um die Funktion mit anderen Taktraten zu nutzen sollte sie manuell programmiert werden. Der folgende Code demonstriert die Nutzung des SRF04/SRF05 Ultraschall-Entfernungsmessers mit der HomeLab Library:

//
// Beispielprogramm für den Ultraschall-Entfernungsmesser des HomeLab
// Die Entfernungsmessung wirkt blockierend.
//
#include <stdio.h>
#include <homelab/pin.h>
#include <homelab/delay.h>
#include <homelab/module/sensors.h>
#include <homelab/module/lcd_alpha.h>
 
//
// Pins des Ultraschallsensors
//
pin pin_trigger = PIN(G, 1);
pin pin_echo    = PIN(G, 0);
 
//
// Hauptprogramm
//
int main(void)
{ 		 
	unsigned short distance;
	char text[16];	
 
	// Initialisierung des LCD
	lcd_alpha_init(LCD_ALPHA_DISP_ON);
 
	// Löschen des LCD
	lcd_alpha_clear();
 
	// Name des Programms
	lcd_alpha_write_string("Ultra sound");
 
	// Kleine Unterbrechung
	sw_delay_ms(100);
 
 	// Endlosschleife.
	while (true)
	{
		// Messen
		distance = ultrasonic_measure(pin_trigger, pin_echo);
 
		// War die Messung erfolgreich?
		if (distance > 0)
		{			
			// Konvertierung von Entfernung in Text.
			sprintf(text, "%d cm   ", distance);
		}
		// Sind während der Messung Fehler aufgetreten?
		else
		{
			// Text des Fehlers.
			sprintf(text, "Error    ");
		}			
 
		// Darstellung des Textes am Anfang der zweiten Zeile des LCD
		lcd_alpha_goto_xy(0, 1);
		lcd_alpha_write_string(text);
 
		// Kleine Unterbrechung.
		sw_delay_ms(500);
	}
}