Zum Inhalt springen

Umgebung erfassen

In diesem Kapitel lernen Sie, wie Sie verschiedene Sensoren verwenden können, um die Umgebung Ihres Roboters zu erfassen. Sensoren sind entscheidend, um Ihrem Roboter Informationen über seine Umgebung zu liefern.

Der Ultraschallsensor misst die Entfernung zu einem Objekt, indem er Schallwellen aussendet und die Zeit misst, die diese benötigen, um zum Sensor zurückzukehren.

Der Ultraschallsensor HC-SR04 verwendet Sonar zur Bestimmung der Entfernung zu einem Objekt. Der Sensor funktioniert in einem Bereich von 2cm - 4m, mit einer Genauigkeit von 0,3cm.

Funktionsweise eines Ultraschall Sensors[^1]

  • Der Ultraschallsender (Triggerstift) sendet einen hochfrequenten Ton (40 kHz) aus.
  • Der Schall wandert durch die Luft. Wenn er auf ein Objekt trifft, wird er zum Modul zurückgeworfen.
  • Der Ultraschallempfänger (Echo-Pin) empfängt den reflektierten Schall (Echo).

Unter Berücksichtigung der Geschwindigkeit des Schalls in der Luft und der Laufzeit (Zeit, die seit der Übertragung und dem Empfang des Signals verstrichen ist) können wir die Entfernung zu einem Objekt berechnen. Hier ist die Formel:

Bei 20° ist die Schallgeschwindigkeit in der Luft 343

Wir wissen nun wie der Sensor in der Theorie funktioniert, schauen wir uns nun die Praxis an.

Der HC-SR04 Ultraschallsensor hat vier Pins:

  • VCC: Versorgungsspannung (+5V)
  • TRIGGER: Steuereingang zum Senden des Ultraschallsignals
  • ECHO: Ausgang, der das empfangene Signal zurückgibt
  • GND: Masse

Im folgenden sehen Sie eine mögliche Verdrahtung.

Schaltplan

Ok, verkabelt ist. Nun müssen wir also ein Signal über den TRIGGER Pin senden und am ECHO Pin messen wie lange es dauert bis das Signal zurück kommt. Anschließend noch mit der Formel die Zeit in cm umrechnen und schon haben wir unseren Abstand.

Wir könnten uns nun die Mühe machen, das alles selbst zu programmieren, aber zum Glück hat schon jemand anderes sich für uns die Arbeit gemacht. Im folgenden finden Sie eine Bibliothek (python Datei) welche wir in unser Projekt einbinden können.

hcrs04.py
import machine, time
from machine import Pin
__version__ = '0.2.0'
__author__ = 'Roberto Sánchez'
__license__ = "Apache License 2.0. https://www.apache.org/licenses/LICENSE-2.0"
class HCSR04:
"""
Driver to use the untrasonic sensor HC-SR04.
The sensor range is between 2cm and 4m.
The timeouts received listening to echo pin are converted to OSError('Out of range')
"""
# echo_timeout_us is based in chip range limit (400cm)
def __init__(self, trigger_pin, echo_pin, echo_timeout_us=500*2*30):
"""
trigger_pin: Output pin to send pulses
echo_pin: Readonly pin to measure the distance. The pin should be protected with 1k resistor
echo_timeout_us: Timeout in microseconds to listen to echo pin.
By default is based in sensor limit range (4m)
"""
self.echo_timeout_us = echo_timeout_us
# Init trigger pin (out)
self.trigger = Pin(trigger_pin, mode=Pin.OUT, pull=None)
self.trigger.value(0)
# Init echo pin (in)
self.echo = Pin(echo_pin, mode=Pin.IN, pull=None)
def _send_pulse_and_wait(self):
"""
Send the pulse to trigger and listen on echo pin.
We use the method `machine.time_pulse_us()` to get the microseconds until the echo is received.
"""
self.trigger.value(0) # Stabilize the sensor
time.sleep_us(5)
self.trigger.value(1)
# Send a 10us pulse.
time.sleep_us(10)
self.trigger.value(0)
try:
pulse_time = machine.time_pulse_us(self.echo, 1, self.echo_timeout_us)
return pulse_time
except OSError as ex:
if ex.args[0] == 110: # 110 = ETIMEDOUT
raise OSError('Out of range')
raise ex
def distance_mm(self):
"""
Get the distance in milimeters without floating point operations.
"""
pulse_time = self._send_pulse_and_wait()
# To calculate the distance we get the pulse_time and divide it by 2
# (the pulse walk the distance twice) and by 29.1 becasue
# the sound speed on air (343.2 m/s), that It's equivalent to
# 0.34320 mm/us that is 1mm each 2.91us
# pulse_time // 2 // 2.91 -> pulse_time // 5.82 -> pulse_time * 100 // 582
mm = pulse_time * 100 // 582
return mm
def distance_cm(self):
"""
Get the distance in centimeters with floating point operations.
It returns a float
"""
pulse_time = self._send_pulse_and_wait()
# To calculate the distance we get the pulse_time and divide it by 2
# (the pulse walk the distance twice) and by 29.1 becasue
# the sound speed on air (343.2 m/s), that It's equivalent to
# 0.034320 cm/us that is 1cm each 29.1us
cms = (pulse_time / 2) / 29.1
return cms

Damit wir die Bibliothek nutzen können müssen wir sie zuerst in unser Projekt einbinden. Gehen Sie dazu wie folgt vor.

  1. Öffnen Sie Thonny und stecken Sie den ESP32 an.

  2. Erstellen Sie eine neue Datei und kopieren Sie den kompletten Inhalt der Bibliothek in diese Datei.

  3. Speichern Sie diese Datei unter dem Namen hcsr04.py auf dem Micropython Device.

    Thonny hcsr04 Datei

  4. Danach sollten Sie die neue Datei auf dem Gerät sehen können.

Als nächsten Schritt müssen wir die Bibliothek in unsere main.py einbinden.

main.py
from hcsr04 import HCSR04

Anschließend können wir ein Objekt der Klasse HCSR04 erzeugen.

main.py
from hcsr04 import HCSR04
sensor = HCSR04(trigger_pin=26, echo_pin=25, echo_timeout_us=20000)

Das Objekt speichern wir in der Variablen sensor. Der Konstruktor benötigt 3 Argumente. Die Pin-Nummer, welche mit dem TRIGGER verbunden ist. Die Pin-Nummer, welche mit dem ECHO verbunden ist. Sowie eine Zeit nachdem die Messung abgebrochen wird.

Dann können wir in unserer Endlosschleife die Methode distance_cm() aufrufen, welche uns die gemessene Distanz in cm zurück liefert.

distance = sensor.distance_cm()

Ein Blick in die Bibliothek verrät uns das es auch eine Methode distance_mm() gibt, welche die Distanz in mm zurück gibt.

Hier sehen Sie nochmal die komplette main.py auf einen Blick.

main.py
from hcsr04 import HCSR04
from time import sleep
sensor = HCSR04(trigger_pin=26, echo_pin=25, echo_timeout_us=20000)
while True:
distance = sensor.distance_cm()
print('Distance:', distance, 'cm')
sleep(1)
  1. Bauen Sie die Schaltung auf.

    Schaltplan Hinweis: Die weiteren Aufgaben sind nur bedingt im Simulator ausführbar.

    Start Lab in Wokwi

    Praktische Aufgabe Hinweis: Bitte den Aufbau wieder so abgeben.

  2. Probieren Sie verschiedene Messungen indem Sie den Abstand mit ihrer Hand verändern.

  3. Überprüfen Sie mit einem Lineal ob die Messungen (abzüglich Messfehler und Genauigkeit) stimmen.

  4. Lassen Sie je nach Abstand zum Sensor eine LED leuchten. Bsp: < 8cm LED aus. > 8cm LED an.

  • Abstände werden korrekt gemessen.
  • LED leuchtet abhängig von der Entfernung.

Infrarotsensor Sharp GP2Y0A51SK0F (Distanzmessung)

Abschnitt betitelt „Infrarotsensor Sharp GP2Y0A51SK0F (Distanzmessung)“

Das GP2Y0A51SK0F von Sharp ist ein analoger Infrarot-Abstandssensor, der sich ideal zur kurzreichweitigen Entfernungsmessung eignet (2–15cm).

Der Sensor sendet einen Infrarotstrahl aus, der von einem Objekt reflektiert wird. Ein integrierter Phototransistor empfängt das reflektierte Licht und wandelt es in ein elektrisches Signal um. Die Intensität des empfangenen Signals variiert je nach Entfernung des Objekts zum Sensor.

Die analoge Spannung des Sensors kann über einen ADC (Analog-Digital-Wandler) eingelesen und in eine Entfernung umgerechnet werden. Dank seiner geringen Größe und schnellen Reaktionszeit ist der Sensor besonders gut für Robotik- oder Hindernisvermeidungsanwendungen geeignet.

Der Sharp GP2Y0A51SK0F hat drei Pins:

  • VCC: Versorgungsspannung (+5V)
  • GND: Masse
  • VOUT: Analoger Ausgang (Spannung proportional zur Entfernung)

Um den analogen Ausgang des Sensors zu lesen, verwenden wir den ADC (Analog-Digital-Wandler) des ESP32. Anschließend können wir die gemessene Spannung in eine Entfernung umrechnen.

  1. Ergänzen Sie die Schaltung auf um den Infrarotsensor. Verbinden Sie VCC mit 5V, GND mit GND und VOUT mit einem ADC-fähigen Pin.

    Nutzen Sie dazu den vorgefertigten Aufbau. Praktische Aufgabe

  2. Nutzen Sie den ADC um die erzeugte Spannung des Moduls einzulesen.

  3. Recherchieren Sie im Datenblatt wie die eingelesenen Werte in eine Entfernung umgerechnet werden können.

  • Abstände werden korrekt gemessen.
  • Aufbau + Code auf Ausgangszustand zurückgesetzt.
Mögliche Lösung
main.py
from machine import ADC, Pin
import time
# ADC initialisieren (z.B. GPIO 34 beim ESP32)
adc = ADC(Pin(34))
def calc_distance(uv):
# convert microvolts to distance in cm
if uv < 400_000 or uv > 2_800_000:
return None # außerhalb des Messbereichs
elif uv < 500_000:
return 15
elif uv < 700_000:
return 10
elif uv < 1_400_000:
return 5
elif uv < 2_800_000:
return 2
while True:
raw = adc.read_uv()
dist = calc_distance(raw)
print(f"Distance: {dist}")
time.sleep(0.5)

Die Umrechung ist eine vereinfachte Näherung basierend auf typischen Werten aus dem Datenblatt. Für genauere Messungen empfiehlt sich eine individuelle Kalibrierung.

Time of Flight (ToF) Sensor VL53L0X (Laser Distanzmessung)

Abschnitt betitelt „Time of Flight (ToF) Sensor VL53L0X (Laser Distanzmessung)“

coming soon…

  1. Was ist der Hauptvorteil eines Ultraschallsensors gegenüber einem Infrarotsensor?

  2. Was könnte ein Problem bei der Verwendung eines Infrarotsensors sein?