Infrarot Abstandsmessung mit dem Raspberry Pi (Sharp GP2Y0A02YK0F)

Vom Hersteller Sharp gibt es einige Infrarot Abstandssensoren, welche sehr einfach mit dem Raspberry Pi betrieben werden können. Hierbei gibt es verschiedene Abstandsmesser, welche unterschiedliche Distanz Bereiche abdecken. Diese Module funktionieren ähnlich zu Laser Distanzmessgeräten, allerdings mit Infrarot Licht. Dabei wird gebündeltes Licht mit einem Sender ausgestrahlt und durch einem Empfänger anhand des Einstrahlwinkels eine (analoge) Spannung durchgeleitet, womit die Distanz berechnet werden kann.

In diesem Tutorial wird anhand des Distanzsensors GP2Y0A02YK0F gezeigt, wie ein Abstand bestimmt werden kann. Nützlich kann dies z.B. im Auto als Car PC (Rückfahrkamera – Abstand), als Roboter Auto oder auch im Rahmen der Hausautomation.

 

Zubehör – Abstandssensoren

Der IR Sender befindet sich auf der "eingedrückten" Seite (rechts).

Der IR Sender befindet sich auf der „eingedrückten“ Seite (rechts).

Insgesamt hat Sharp einige Distanzmesser im Angebot, wobei individuell geschaut werden sollte, welche für die Aufgabe passend ist. Dieses Tutorial ist auf den Sharp GP2Y0A02YK0F ausgelegt, welcher für Bereiche von 20cm bis 150cm geeignet ist. Entfernungen außerhalb dieses Bereichs werden nicht korrekt gemessen.
Folgende Module stehen zur Auswahl:

Solltest du einen anderen Sensor als den GP2Y0A02YK0F verwenden, so musst du die einzelnen Schritte ggf. anpassen. Die Datenblätter sind auf der Sharp Homepage verfügbar.

Weiterhin brauchst du noch folgendes:

 

 

Funktionsweise des Infrarot Abstandssensors

Dieser IR Sensor braucht eine Eingangsspannung zwischen 4.5V und 5.5V, kann also perfekt mit den 5V des Raspberry Pi’s betrieben werden. Dabei liegt laut Datenblatt eine unterschiedliche Spannung am Daten Pin an, je nach dem, wie weit das vom Sensor gemessene Objekt ist. Dies ist in folgendem Graphen sichtbar:

gp2y0a02yk

Anhand der Spannung kann die Distanz zwischen ca. 15cm und 150cm relativ exakt hergeleitet werden.

 

 

Anschluss des MCP3008

mcp3008-e1397762478714

Da die ausgehende Spannung analog ist, müssen wir sie erst mit einem Analog-Digital Wandler „übersetzen“, sodass wir sie mir dem Raspberry Pi auswerten können. Dies geht am besten mit einem MCP3008 ADC.

Dieser Baustein wird über den SPI Bus des Pi’s angesteuert und hat acht Kanäle, an denen analoge Spannungen übersetzt werden können. Diese werden in 2^20 also 1024 Bereiche (0-1023) aufgeteilt. Wird der MCP3008 an 3.3V angeschlossen, entspricht ein Signal von 1 also 0.00322V (3.22mV). Da der SPI Bus des Raspberry Pi’s auf 3.3V arbeitet, sollte auch nicht mehr Spannung angelegt werden, da sonst die GPIOs beschädigt werden können.

Die ganze Schaltung sieht schematisch folgendermaßen aus:

 

sharp_GP2Y0A02YK0F_Steckplatine

RaspberryPi MCP3008
Pin 1 (3.3V) Pin 16 (VDD)
Pin 1 (3.3V) Pin 15 (VREF)
Pin 6 (GND) Pin 14 (AGND)
Pin 23 (SCLK) Pin 13 (CLK)
Pin 21 (MISO) Pin 12 (DOUT)
Pin 19 (MOSI) Pin 11 (DIN)
Pin 24 (CE0) Pin 10 (CS/SHDN)
Pin 6 (GND) Pin 9 (DGND)

 

Der Abstandssensor hat dabei lediglich drei Anschlüsse: Rot (5V), Schwarz (GND) und Gelb, was der Datenpin ist und an den MCP3008 ADC angeschlossen wird. Bei manchen werden dabei eventuell die Alarmglocken läuten und sagen, warum ein 5V Modul direkt angeschlossen wird, obwohl der SPI Bus des Pi’s nicht mehr als 3.3V Input bekommen darf. Im Datenblatt ist angegeben, dass die Ausgangsspannung des Sensors nie über 3V kommt (siehe Graph aus dem Datenblatt). Wer dennoch Angst hat, dass dem Pi etwas zustoßen könnte, der kann davor einen Spannungsteiler mit 2 Widerständen setzen, allerdings nimmt dadurch die Genauigkeit ab und auch meine verwendete Formel müsste neu berechnet werden. In meinen Tests kamen aber nie Spannungen über 2.7V an (GP2Y0A02YK0F). Bei den anderen Sharp Sensoren kann dies evtl. abweichen.

 

 

Software zum Auslesen der Distanz

Um den MCP3008 steuern zu können, muss der SPI-Bus aktiviert werden. Dies geht folgendermaßen:

sudo raspi-config

„8 Advanced Options“ -> „A6 SPI“ -> „Yes“.
Danach musst du den Neustart bestätigen.

In manchen Fällen muss das Modul (spi-bcm2708) auch noch in die /etc/modules Datei eingetragen werden. Dazu einfach

sudo nano /etc/modules

aufrufen und folgende Zeile am Ende hinzufügen (falls Sie nicht vorhanden ist):

Nun kann die spidev Bibliothek installiert werden, falls das noch nicht geschehen ist:

sudo apt-get install git python-dev
git clone git://github.com/doceme/py-spidev
cd py-spidev/
sudo python setup.py install

 

Nachdem nun alle benötigten Pakete installiert sind, können wir das Skript zum messen der Distanz erstellen.

sudo nano ir_distance.py

Das Skript hat folgenden Inhalt:

Führen wir es nun aus (sudo python ir_distance.py), nachdem wir auf ein Objekt zielen, wird der Abstand ausgegeben.

Was passiert hier genau? Zu erst einmal wird der analoge Wert (zwischen 0 und 1023) ausgelesen (Zeile 15). Da wir allerdings die Spannung wissen möchten, wird der Wert durch 1023 dividiert und mit 3.3 (Volt) multipliziert.

Achtung: In diesem Fall wissen wir (laut Datenblatt), dass die Ausgangsspannung nie über ca. 2.8V geht, obwohl wir den Sensor mit 5V versorgen. Andere Module (analog als auch digital) geben oft Signale mit Spannungen zurück, die so hoch wie die angelegte Spannung ist. Sollte man das nicht beachten, kann dies zu Schäden am Raspberry Pi führen.

 

In Zeile 16 des Skripts rechne ich die Spannung in Zentimeter um. Die Formel dazu habe ich hier gefunden und ein wenig angepasst. Dazu habe ich verschiedene Abstände getestet und die Faktoren etwas verändert, sodass die errechnete Distanz möglichst genau zutrifft. Wie ich anfangs erwähnt habe, ist diese Formel nur für den Sharp GP2Y0A02YK0F Sensor. Da die anderen Sensoren analoge Signale im ähnlichen Bereich liefern, muss diese Formel für die entsprechenden Sensoren angepasst werden (falls das jemand macht, würde ich mich freuen, falls er sie hierunter postet).
Alternativ kann man auch zwischen den Bereichen (Datenblatt) interpoliert werden, indem man alle Anhaltspunkte (Volt, Abstand) speichert und den bestimmten Wert ausliest und mittels linearer Interpolation den Abstand zu der gemessenen Spannung errechnet.

Ich habe früher oder später vor ein solches Modul an die Innenseite der Heckscheibe meines Autos zu befestigen und damit einen Distanzmesser beim rückwärts einparken zu haben – falls jemand noch nicht weiß, was er damit anstellen kann 😉

24 Kommentare

  1. Hallo, und guten Tag,
    meine Frage zum GP2Y0A02YK0F:
    würde sich dieser Sensor auch als „Lichtschranke“ im Außenbereich eignen ?
    D.h. wenn sich ein Objekt in einem Abstand von ca. 0,5 m an dem Sensor vorbei bewegt, sollte ein Signal ausgelöst werden.
    Eine originale Lichtschranke möchte ich nicht verwenden.

    b.r. Harry

    Antworten
    • Ja das sollte funktionieren. Allerdings müsstest du dann dauerhaft die Distanz abfragen oder den analogen Wert zu einem „Trigger“ umbauen (sodass ab einer bestimmten Spannung bspw. ein Transisotr/Relais öffnet und Strom an einen GPIO Pin gelegt wird, welchem du ein Event zuweist).

      Antworten
  2. Vielen Dank für die freundliche Info.
    In diesem Zusammenhang stellt sich mir die Frage, wie man die Auslösung des Sensors zeitlich erfassen und auslesen könnte (Python). Wäre es vielleicht möglich für dieses Vorhaben ein kleines Tutorial einzurichten?

    br. Harry.S

    Antworten
    • Die einfachere Methode wäre alle X ms die Spannung zu messen und damit die Entfernung berechnen (wie hier im Tutorial mit einer zusätzlichen Schleife). Die andere Methode wäre u.U. etwas komplizierter, da weniger Programmierung dazu nötig ist, dafür mehr Messungen. Wenn auch noch andere daran Interesse haben, könnte ich in Zukunft dazu auch ein Tutorial machen.

      Antworten
  3. Hallo Felix,
    vielen Dank für Deine Nachricht.
    Vielleicht habe ich mich etwas missverständlich ausgedrückt.
    Ich möchte lediglich den Zeitpunkt dokumentieren, an dem der Sensor ausgelöst hat –
    die Zeitangabe in eine Datei schreiben und diese bei Bedarf auslesen.
    b.r. Harry

    Antworten
    • Naja den Zeitpunkt kannst du einfach mit time.time() feststellen und in eine Datei schreiben ist auch nicht so schwer. Oder wo liegt das Problem genau?
      LG, Felix

      Antworten
  4. Hallo Zusammen!
    Ich würde gerne einen zweiten und am liebesten noch einen dritten Infrarot Sensor dieser Art an meinen Pi betreiben. Hab aber leider keine Ahnung wie ich das am besten mache … gibt es iwo möglichkeiten sich drüber zu informieren oder ist eventuell mal ein weiteres How-To dieser Art geplant?

    Antworten
    • Nunja, der MCP3008 hat 8 analoge Channels, d.h. du kannst mit einem Modul bis zu 8 analoge Sensoren auslesen. Ist im Prinzip das gleiche wie in diesem Tutorial, nur dass eben ein anderer Channel (statt CH0) ausgelesen ausgelesen werden muss (woran der zweite Sensor hängt).

      Antworten
  5. Hallo Felix,
    vielleicht magst Du mir einen Hinweis zu folgendem Problem geben:
    Der Abstand zwischen dem Sensor und dem MCP3008 beträgt 18 Meter!
    Aufgrund des Spannungsverlustes (Verbindungskabel = 3 X 1) ist die Sensor- Ausgangsspannung am MCP3008 zu gering.
    Wie könnte ich die Spannung auf einen brauchbaren Wert erhöhen?
    b.r. Harry

    Antworten
    • Hallo Harry,
      also ich würde wenn dann den MCP3008 möglichst nahe zum Sensor stellen, da der Sapnnungsabfall bei analogen Werten zu falschen Messungen führt. Kannst du dickere Leitungen verwenden oder ggf. eine externe Stromversorgung für den MCP3008? Du müsstest mal den Widerstand des Kabels messen um festzustellen, wie hoch der Verlust sein wird (bis zu einem gewissen Wert ist das digitale Signal weiterhin auslesbar).

      Antworten
  6. Hallo Felix,
    da die Leitung bereits verlegt ist und auch die anderen Gegebenheiten kaum zu verändern sind, werde ich wohl auf den PIR – Bewegungsmelder zurückgreifen müssen.
    Ist Dir vielleicht bekannt, ob dieser Sensor auch Bewegungen unter 3 Meter erfassen kann?

    b.r. Harry

    Antworten
    • Hey Harry,
      der PIR kann definitiv Bewegungen, die in weniger als 3m Abstand stattfinden wahrnehmen. Das Problem des Sensors werden eher weite Entfernungen sein.
      LG, Felix

      Antworten
  7. Hallo,
    gib´s die möglichkeit die Schaltung umzubauen sodass man in einer Abstand von 50 m ein bewegendes Objekt detektiert? Oder hätten Sie Vorschläge wie man so ewtas it Rasp PI bauen kann?

    vielen Dank

    Antworten
    • Die Sharp Module können je nach Modell, leider nur einen Abstand von maximal 10m erkennen. Es gibt einige Laser-Messer, die aber etwas teurer sind. Man müsste ein solches Gerät aufschrauben und die Datenpins anklemmen, um so auch am Raspberry Pi den Abstand auslesen zu können.

      Antworten
  8. Hi,

    ich wollte kurz fragen ob schon jemand eine brauchbare Formel für den GP2Y0A41SK0F (4-30cm) hat, hatte versucht das ergebnis des anderen um ein 5tel zu reduzieren, da die reichweite ja auch jeweils das 5 fache ist, jedoch bringt das leider gar nix 🙁

    mit der formel selbst kann ich leider aufgrund fehlender mathematikkenntisse nichts anfangen 🙁

    lg
    Harald

    Antworten
  9. Hi;

    ich habe das System mit dem GP2Y0A21 mit dem Ziel gebaut, dadurch eine Lichtschrank zu erhalten. Nach der Verkabelung habe ich im ersten Schritt einfach den Abstand auslesen wollen und auch wenn die Formel sicher nicht für diesen Typ korrekt ist, so müsste das Ergebnis ja dennoch immer gleich sein. Dies ist leider nicht der Fall. Die Ergebnisse weichen bei jeder Messung leider ab. Da sie aber alle im Ergebnis um die 6000cm liegen und ich ja im Prinzip nur eine Lichtschranke brauche, war mir dies erst einmal egal. Ich wollte dann den „Alarm“ einfach auslösen, wenn der Wert auf unter 3000 fällt. Die Endlosschleife läuft, jedoch wird der Alarm auch so sehr oft ausgelöst ohne dass etwas in die Schranke kommt. Umso häufiger ich den Wert auslese, um so größer sind die Schwankungen. Kann mir vielleicht jemand sagen, wie ich dieses Problem in den Griff bekomme?

    Vielen Dank

    Deniver

    Antworten
    • Schau dir mal nur die reinen analogen Werte an (0-1023) und prüfe, ob der abgebildete Wert laut Datenblatt mit dem Abstand übereinstimmt. Es könnte natürlich auch sein, dass der Sensor einen Fehler hat.

      Antworten
  10. Hi, ich würde gerne den Füllstans meines Heizöltanks messen. Der Ultraschallsensor ist aufgrund der Form meiner Tanks ungeeignet. Denkst Du das würde per Infrarot gehen? Oder wird da auch durch einen Kegel gemessen? Und kann das Teil Flüssigkeit also Öl messen?

    Danke

    Antworten
    • Sollte tendentiell funktionieren, aber ich weiß nicht, ob die Oberfläche von Öl dafür geeignet ist. Im Zweifel würde ich es einfach mal ausprobieren 🙂

      Antworten
  11. Hi Felix,

    ich habe mir das mal nachgebaut. Leider werden mir immer 301.4cm angezeigt wenn ich das skript auslese. Ich habe schon beim Sharp Sensor nachgemessen und der funktioniert. Die Spannung am Analogausgang verändert sich je nach Abstand. Den MCP3008 hatte ich erst genau andersrum angeschlossen und daher einen Defekt in Verdacht. Aber den habe ich nun ausgetauscht und das gleiche Resultat. Ich habe als Bauchgefühl das Skript im Verdacht, irgendwas stimmt da wohl nicht wenn er immer nur einen statischen Abstand ausgibt. Aber ich komme nicht drauf was die Ursache genau ist. Kannst du mir da behilflich sein?

    Antworten
    • Ich habe das Ganze nun mal mit der Adafruit Libary ausprobiert.

      https://learn.adafruit.com/raspberry-pi-analog-to-digital-converters/mcp3008

      Dort bekomme ich auf auf Channel 1 auch entsprechende Werte dort wo der Sensor angeschlossen ist (den Channel habe ich in deinem Skript schon geändert). Allerdings auch auf den anderen Channels.

      Reading MCP3008 values, press Ctrl-C to quit…
      | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
      ———————————————————
      | 0 | 483 | 0 | 0 | 0 | 0 | 0 | 0 |
      | 1 | 479 | 0 | 6 | 8 | 11 | 19 | 46 |
      | 199 | 480 | 240 | 279 | 280 | 284 | 288 | 280 |
      | 273 | 483 | 275 | 213 | 212 | 202 | 197 | 157 |
      | 0 | 480 | 0 | 0 | 0 | 0 | 0 | 0 |
      | 18 | 473 | 14 | 19 | 24 | 32 | 49 | 94 |
      | 287 | 476 | 288 | 232 | 227 | 230 | 223 | 201 |
      | 200 | 491 | 229 | 44 | 0 | 0 | 0 | 0 |
      | 0 | 481 | 0 | 0 | 5 | 8 | 17 | 43 |
      | 292 | 482 | 293 | 279 | 279 | 283 | 285 | 274 |
      | 257 | 484 | 261 | 196 | 183 | 176 | 162 | 111 |
      | 0 | 475 | 0 | 0 | 0 | 0 | 0 | 0 |
      | 68 | 482 | 197 | 280 | 283 | 282 | 287 | 281 |
      | 282 | 478 | 271 | 208 | 196 | 190 | 176 | 133 |
      | 0 | 482 | 0 | 0 | 0 | 0 | 0 | 0 |
      | 51 | 477 | 24 | 34 | 137 | 283 | 291 | 284 |
      | 277 | 483 | 281 | 223 | 213 | 208 | 201 | 170 |

      Nun frage ich mich warum kommt auf den ungenutzten Channels was an und weshalb liest dein Skript das nicht korrekt aus.

      Antworten
      • An den ungenutzen Channeln ist keine (positive oder negative) Spannung, daher wird diese zufällig festgelegt. Das selbe Verhalten haben die GPIOs wenn du sie ausließt, ohne dass sie an etwas angeschlossen sind.

    • Hallo Dirk,
      hast du die Ursache des Problems damals gefunden? Ich habe nämlich aktuell das gleiche Problem mit 301.44 cm, obwohl der Entfernungsmesser die richtige Spannung ausgibt und alles richtig verdrahtet ist.
      Vielen Dank im Voraus!

      Antworten

Hinterlasse einen Kommentar

Deine Email Adresse wird nicht veröffentlicht.

Blog abonnieren

Abonniere Raspberry Pi Tutorials, um kein Tutorial mehr zu verpassen!