Benutzer-Werkzeuge

Webseiten-Werkzeuge


raspberry:einparkhilfe

Ultraschallsensor

Folgende Aufgaben sind bei diesem Projekt zu lösen:

  • Mit dem 4-Pin-Ultraschallsensor HC-SR04 wird eine Abstandsmessung realisiert
  • Wie bei einer Einparkhilfe im Auto wird der Abstand mit Leuchtdioden visualisiert

Hinweis: Es werden nicht alle Einzelheiten der Schaltung und der Programmierung beschrieben. In den anderen Artikeln zum Raspberry Pi können die Grundlagen nachgelesen werden.

Abstandsmessung

Im ersten Teil dieses Projektes wird mit einem Ultraschallsensor eine Abstandsmessung durchgeführt. Dabei werden zwei Messergebnisse pro Sekunde ausgegeben.

Hintergrundinformationen

Um die Schaltung und das Programm besser zu verstehen soll geklärt werden, was der Ultraschallsensor genau macht und wie man damit eine Entfernung messen kann.

Im Wesentlichen besteht der Ultraschallsensor aus einem Sender und einem Empfänger. Es wird ein Ultraschallimpuls ausgesendet, der vom nächsten Hindernis reflektiert wird. Das Echo des Impulses wird vom Empfänger registriert. Der Sensor HC-SR04 ist für Schaltungen mit den Raspberry Pi weit verbreitet und relativ einfach zu verwenden. Der HC-SR04 besitzt vier Anschlüsse, zwei für die Spannungsversorgung, einen Trigger- und einen Echo-Anschluss. Nachdem der HC-SR04 ein Triggersignal erhalten hat, wird ein Ultraschallimpuls ausgesendet und gleichzeitig ein 1-Signal an dem Echo-Pin ausgegeben. Sobald der Sensor das Echo des Impulses „hört“ wird aus der 1 am Echo-Pin wieder eine 0.

Um die Entfernung $s$ bestimmen zu können, muss die Zeit $t$ gemessen werden, die vergeht, solange am Echo-Pin eine 1 anliegt. Der Schall breitet sich bei trockener Luft und Zimmertemperatur mit einer Geschwindigkeit $v = 343,2 \frac{m}{s}$ aus1). In einer Sekunde legt der Schall also 343,2 Meter oder 34320 Zentimeter zurück. Wenn wir die Schallgeschwindigkeit mit der gemessenen Zeit (in Sekunden) multiplizieren erhalten wir die Strecke, die der Schall in dieser Zeit zurückgelegt hat. Zu beachten ist allerdings, dass dies die Strecke zum Hindernis HIN und wieder ZURÜCK ist. Da die einfache Entfernung zum Hindernis bestimmt werden soll, wird die Zeit mit der Hälfte der Schallgeschwindigkeit multipliziert.

$$ s = \dfrac{t \cdot v}{2} = \dfrac{t \cdot 34320 \ \tfrac{cm}{s}}{2} $$ $$ s = t \cdot 17160 \ \tfrac{cm}{s} $$

Schaltung

Stromlaufplan mit Ultraschallsensor

Der Ultraschallsensor benötigt eine Betriebsspannung von 5 V, die vom Raspberry Pi (Pin 2) mit dem Vcc-Pin des Moduls verbunden wird. Für den Gnd-Pin am Sensor kann jeder der Masse-Pins (z. B. Pin 6) des Raspberry Pi verwendet werden.

Der Trigger- und der Echo-Anschluss des Sensors werden mit jeweils einem der GPIO-Pins verbunden. Pin 16 (GPIO 23) wird später als Ausgang programmiert, da man dem Sensor darüber das Triggersignal übermittelt und somit die Messung startet.

Die eigentliche Zeitmessung erfolgt mithilfe des Echo-Signals vom Sensor. Pin 18 (GPIO 24) wird später als Eingang programmiert. Unbedingt zu beachten ist, dass am Echo-Pin bei einem 1-Signal die gesamten 5 V der Betriebsspannung anliegen. An die Eingänge des Raspberry Pi dürfen allerdings maximal 3,3 V angelegt werden. Aus diesem Grund wird der Echo-Anschluss des Sensors mit den Widerständen $R_1=10 \ k\Omega$ und $R_2= \ 10 \ k\Omega$ an die Masse angeschlossen. Zwischen den beiden in Reihe liegenden Widerständen kann das Echo-Signal von der GPIO-Schnittstelle des Raspis erfasst werden. Die maximale Spannung beträgt durch den Spannungsteiler nur noch 2,5 V. Für den Spannungsteiler können auch andere Widerstände verwendet werden. Sie sollten dieselben hinreichend großen Nennwerte im $k\Omega$-Bereich haben.

Programmierung

Abstandsmessung mit Ultraschallsensor: abstand.py

#! /usr/bin/env python
import time				
import RPi.GPIO as GPIO			# GPIO-Bibliothek
GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.OUT)		# GPIO 23 (Pin 16) als Ausgang
GPIO.setup(24, GPIO.IN)			# GPIO 24 (Pin 18) als Eingang
try:
   while True:
      GPIO.output(23, 1)		# Trigger einschalten fuer ...
      time.sleep(0.00001)		# ... 10 Mikrosekunden
      GPIO.output(23, 0)		# Trigger ausschalten
      while GPIO.input(24) == 0:	# Auf Echo des Einschaltens warten
         pass
      start = time.time()		# Zeit des Einschalt-Echos merken
      while GPIO.input(24) == 1:	# Auf Echo des Ausschaltens warten
         pass
      ende = time.time()		# Zeit des Ausschalt-Echos merken
      abstand = (ende - start) * 17160	# Abstand in cm berechnen
      print "Abstand:", abstand , "cm"
      time.sleep(0.5)			# 2 Abstaende pro Sekunde
except KeyboardInterrupt:
   GPIO.cleanup()

Wie bereits beschrieben werden in dem Beispiel GPIO 23 als Ausgang und GPIO 24 als Eingang verwendet und dementsprechend programmiert (Zeile 5 und 6).

Der Ausgangs-Pin GPIO 23 wird verwendet, um das Trigger-Signal zu erzeugen und damit die Messung zu starten. Als Trigger-Signal wartet das Sensor-Modul auf einen mindestens 10 Mikrosekunden anhaltenden 1-Impuls am Trigger-Pin. Um dieses Signal zu erzeugen, wird der Trigger für 0,00001 Sekunde eingeschaltet und anschließend wieder ausgeschaltet.

Der Ultraschallsensor sendet den Ultraschallimpuls nicht sofort aus, sondern wartet noch einige Mikrosekunden. Sobald das Modul den Ultraschallimpuls sendet, wird eine 1 an den Echo-Pin angelegt. In einer while-Schleife (Zeile 12 und 13) wartet das Programm auf das 1-Signal. Genau genommen tut das Programm nichts (pass), solange noch eine 0 an GPIO 24 erkannt wird. Anschließend wird die Schleife beendet und die Startzeit gespeichert (Zeile 14). Mit time.time() erhält man die Systemzeit in Sekunden seit 1970 als Dezimalzahl mit einer sehr hohen Genauigkeit. Auch Zeitunterschiede von wenigen Mikrosekunden können damit erfasst werden.

Wenn der Ultraschallimpuls von einem Hindernis reflektiert und das Echo vom Sensor erfasst wird, wechselt der Zustand am Echo-Pin des Sensors von 1 auf 0. Daher wird in einer zweiten Schleife (Zeile 15 und 16) auf diesen Signalwechsel gewartet und anschließend die Endzeit gespeichert (Zeile 17).

Mit den Variablen start und ende kann nun berechnet werden, in welcher Zeit der Ultraschallimpuls den Weg zum Hindernis und zurück zum Sensor zurückgelegt hat. Dafür wird in Zeile 18 die Differenz zwischen den beiden Werten berechnet (stop - start). Entsprechend der oben genannten Formel wird daraus dann der Abstand zum Hindernis in Zentimeter berechnet und in Zeile 19 ausgegeben. Es folgt eine Wartezeit von 0,5 Sekunden (Zeile 20), weshalb insgesamt etwa 2 Messungen pro Sekunde durchgeführt werden. Der Ultraschallsensor kann maximal 50 Messungen pro Sekunde durchführen.

Einparkhilfe

Eine Einparkhilfe in einem Auto misst den Abstand zwischen Auto und Hindernis. Je näher das Auto dem Hindernis kommt, umso mehr Leuchtdioden leuchten und umso eindringlicher werden akustische Signale. Wie die Visualisierung mithilfe der Leuchtdioden realisiert werden kann, wird im folgenden Abschnitt beschrieben.

Schaltung

Stromlaufplan der Einparkhilfe

Die Beschaltung des Ultraschallsensors erfolgt genauso, wie bei der bereits beschriebenen Abstandsmessung. Es werden lediglich die Leuchtdioden und Vorwiderstände ergänzt.

Für die Visualisierung des Abstandes sollen sechs Leuchtdioden verwendet werden. Jede der Leuchtdioden wird mit einem Vorwiderstand $R_{3\dots 8} = 330 \ \Omega$ betrieben. Bei der Auswahl des Vorwiderstandes hat man, wie im Hallo Welt-Projekt beschrieben, einen gewissen Spielraum. Die Spannung erhalten die Leuchtdioden von den Pins 7, 29, 31, 26, 24 und 21, was den GPIO-Pins 4 bis 9 entspricht. Die Kathoden der Dioden werden mit der Masse verbunden.

Programmierung

Einparkhilfe: einparkhilfe.py

#! /usr/bin/env python
import time				
import RPi.GPIO as GPIO			# GPIO-Bibliothek
GPIO.setmode(GPIO.BCM)
GPIO.setup(4, GPIO.OUT)			# GPIO 4 (Pin 7): LED rot
GPIO.setup(5, GPIO.OUT)			# GPIO 5 (Pin 29): LED rot
GPIO.setup(6, GPIO.OUT)			# GPIO 6 (Pin 31): LED gelb
GPIO.setup(7, GPIO.OUT)			# GPIO 7 (Pin 26): LED gelb
GPIO.setup(8, GPIO.OUT)			# GPIO 8 (Pin 24): LED gruen
GPIO.setup(9, GPIO.OUT)			# GPIO 9 (Pin 21): LED gruen
GPIO.setup(23, GPIO.OUT)		# GPIO 23 (Pin 16): Trigger
GPIO.setup(24, GPIO.IN)			# GPIO 24 (Pin 18): Echo
try:
   while True:
      GPIO.output(23, 1)
      time.sleep(0.00001)		# 10 Mikrosekunden Trigger
      GPIO.output(23, 0)
      while GPIO.input(24) == 0:
         pass
      start = time.time()		# Echo Startzeit
      while GPIO.input(24) == 1:
         pass
      ende = time.time()		# Echo Endzeit
      abstand = (ende - start) * 17160	# Abstand berechnen
      GPIO.output(4, abstand < 10.0)	# LEDs Einschalten ...
      GPIO.output(5, abstand < 15.0)	# ... falls der Abstand ...
      GPIO.output(6, abstand < 20.0)	# ... einen bestimmten Wert ...
      GPIO.output(7, abstand < 25.0)	# ... unterschreitet.
      GPIO.output(8, abstand < 30.0)
      GPIO.output(9, abstand < 35.0)
      time.sleep(0.1)			# 10 Messungen pro Sekunde
except KeyboardInterrupt:
   GPIO.cleanup()

Zunächst müssen alle für die LEDs verwendeten GPIO-Pins als Ausgang programmiert werden (Zeile 5 bis 10). Abstandsmessung und -berechnung erfolgt genauso wie bereits beschrieben (Zeile 15 bis 24).

Auf die Ausgabe des Abstandes wird in diesem Programm verzichtet. Die LEDs werden den Abstand anzeigen. Bei einem Abstand von 35 Zentimetern zum Hindernis soll die erste LED leuchten. Rückt das Hindernis näher, so leuchtet alle 5 Zentimeter eine LED mehr auf. Bei einem Abstand, kleiner als 10 Zentimeter, leuchten also alle 6 Dioden.

Um die einzelnen LEDs ein- bzw. auszuschalten übergibt man der Funktion GPIO.output() einen booleschen Wert (0 oder 1 bzw. False oder True). Die Bedingung, die erfüllt sein muss, damit die Diode leuchtet, kann also direkt übergeben werden. Beispielsweise leuchtet die letzte Diode, wenn die Bedingung abstand < 35.0 erfüllt ist. Solch eine Bedingung wurde für jede der sechs Leuchtdioden formuliert (Zeile 25 bis 30). Die Steuerung der Leuchtdioden kann auch mithilfe von Verzweigungen programmiert werden.

Einparkhilfe
raspberry/einparkhilfe.txt · Zuletzt geändert: 2015/12/26 18:13 von gum