Der Entfernungssensor vom Typ VL53L0X arbeitet mit ausgesendeten Infrarot Laserimpulsen (Klasse 1 Laser) und misst die Zeit, die von einem Objekt reflektierte Lichtimpulse benötigen, bis sie wieder am Empfänger des Sensors eintreffen. Diese Methode bezeichnet man als Lichtlaufzeitverfahren, auch „Time of Flight“ (ToF) genannt. Interessante Informationen zur Funktionsweise gibt es hier. https://de.wikipedia.org/wiki/Elektrooptische_Entfernungsmessung

Die gängigen Breakout-Boards des Sensors für den Arduino benötigen neben einer Stromversorgung nur die beiden I²C zur Kommunikation. Der Sensor arbeitet zwar mit 2.8V statt der 5V des Arduino Uno, fast alle Breakout-Boards verfügen aber über einen integrierten Spannungsregler.

Mit dem Sensor und einem Arduino Uno kann man damit zwar einfach Entfernungen messen – aber wie visualisiert man diese am besten? Meine Anwendungsidee für das Projekt ist eine Einparkhilfe für unsere Garage, die mit einer gut sichtbaren optischen Rückmeldung dafür sorgt, dass genug Platz zwischen Werkbank und Fahrzeug bleibt, um dort noch gut arbeiten zu können.

Natürlich ist so ein Setup aber auch für viele andere Ideen zu verwenden, z.B. als Füllstandsanzeige für Behälter oder als Abstandswarner – in Zeiten von Corona ja nicht die schlechteste Idee.

Den Aufbau des Projektes und den Arduino Sketch habe ich in diesem Video detailliert beschrieben:

Hier der Arduino Sketch, der im Video verwendet wird. Ich habe versucht möglichst gut zu kommentieren, offene Fragen bitte einfach in die Kommentare schreiben:

/* Parkhilfe mit VL53L0X
 * Weitere Infos und Tutorial auf https://www.makerblog.at
 *  
 * Einparkhilfe z.B. zur fixen Montage an der rückseitigen Garagenwand,
 * misst den Abstand zwischen Sensor und Objekt (Auto) und visualisiert die 
 * korrekte Einparkposition mit WS2812B RGB LEDs
 * 
 *  
 * Setup: 
 * 
 * - Arduino Uno
 * 
 * - VL53LX0 Laser Sensor
 *   - Arduino 5V an Sensor VIN
 *   - Arduino GND an Sensor GND
 *   - Arduino A4 an Sensor SDA (I2C Data)
 *   - Arduino A5 an Sensor SCL (I2C Clock)
 * 
 * - WS2812B RGB LED Stripe
 *   - Arduino D6 über 220Ohm Widerstand an LED Data In
 *   - Stromversorgung über Arduino bei wenigen LEDs oder
 *     mit eigener Stromquelle an +/- des LED Stripes
 *     Achtung: Kondensator zwischen 5V und GND
 *     Siehe Tutorials zu WS2812B Neopixel LEDs
 * 
*/

// Libraries für I2C, Sensor und RGB LEDs einbinden. Alle Bibliotheken
// können über den Library Manager der Arduino IDE installiert werden
#include "Wire.h"
#include "VL53L0X.h"
#include "Adafruit_NeoPixel.h"

// Sensorobjekt
VL53L0X distanceSensor;

// Datenpin für den WS2812B LED Streifen
#define LEDPIN 6
#define LEDCOUNT 16

#define RANGESTARTMM 200
#define RANGEENDMM 50

#define ORANGESTARTLED 12
#define REDSTARTLED 16

// LEDs initialisieren
// in diesem Fall 16 LEDs mit den Adressen 0 bis 15
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LEDCOUNT, LEDPIN, NEO_GRB + NEO_KHZ800);

// Standardfarben für die LEDs definieren
uint32_t rgbRed = strip.Color(255,0,0);
uint32_t rgbOrange = strip.Color(255,90,0);
uint32_t rgbGreen = strip.Color(0,255,0);
uint32_t rgbBlack = strip.Color(0,0,0);
uint32_t activeColor = rgbBlack;


void setup()
{
  Serial.begin(9600);
  Wire.begin();

  // Distanzsensor initialisieren und konfigurieren
  distanceSensor.setTimeout(500);
  if (!distanceSensor.init())
  {
    Serial.println("VL53L0X Sensor nicht gefunden! Ablauf angehalten.");
    while (1) {}
  }
  // Sensor auf 10 Messungen pro Sekunde
  distanceSensor.setMeasurementTimingBudget(100000);

  // LED Streifen starten und Helligkeit setzen
  strip.begin();
  strip.setBrightness(100); // Helligkeit 0-255
  strip.show(); 
    
}

void loop()
{
  // Entfernung in mm lesen
  int dist = distanceSensor.readRangeSingleMillimeters();
  // Falls TIMEOUT dann Fehler seriell ausgeben und dist auf 0 setzen
  if (distanceSensor.timeoutOccurred()) { 
    Serial.println("TIMEOUT");
    dist = 0;
  }

  int lastPixel = 0;

  // Sensorbereich in mm in Anzahl der LEDs umwandeln, im Beispiel
  // den Bereich von 50mm bis 200mm auf die LEDs 16 bis 0 mappen
  // D.h. bei bei dist=200 ist lastPixel = 0, bei dist=50 ist
  // lastPixel = 16 und der Wertebereich dazwischen wird ebenfalls
  // richtig umgerechnet.
  // ACHTUNG: eine Range von 50-200mm ist zum Testen auf dem Schreibtisch,
  // in der Garage passen Werte zwischen 500 und 2000mm besser :)
  // Mit den Konstanten ersetzt heisst diese Zeile
  // lastPixel = map(dist, 50, 200, 15, 0);
  
  lastPixel = map(dist, RANGEENDMM, RANGESTARTMM, LEDCOUNT-1, 0);

  // Zur Kontrolle Ausgabe der Distanz und der ermittelten LED
  // am seriellen Monitor
  Serial.print("dist = ");
  Serial.print(dist);
  Serial.print(" => ");
  Serial.print("lastPixel = ");
  Serial.println(lastPixel);

  // Alle LEDs löschen (= auf schwarz setzen)
  for (int i=0; i< LEDCOUNT; i++) {
    strip.setPixelColor(i, rgbBlack);    
  }

  // Entsprechend der Anzahl der aktiven LEDs ändert
  // ändert sich auch die Farbe aller LEDs
  if (lastPixel >= REDSTARTLED) {
    activeColor = rgbRed;
  } else if (lastPixel >= ORANGESTARTLED) {
    activeColor = rgbOrange;
  } else if (lastPixel >= 0) {
    activeColor = rgbGreen;
  } else {
    activeColor = rgbBlack;
  }

  // Wenn lastPixel >= LEDCOUNT dann auf LEDCOUNT-1 setzen
  if (lastPixel >= LEDCOUNT) {
    lastPixel = LEDCOUNT-1;
  }

  // Nummerierung der LEDs beginnt bei 0!
  for (int i=0; i<= lastPixel; i++) {
      strip.setPixelColor(i, activeColor);    
  }

  // LEDs aktualisieren
  strip.show();

}

Für dieses einfache Umsetzung gibt es natürlich zahlreiche Optimierungsmöglichkeiten. Naheliegend wäre auch eine Anpassung für die gängigeren und günstigeren Ultraschallsensoren vom Typ HC-SR04.

NeoPixel Ringe mit WS2812B LEDs gibt es mittlerweile von vielen Herstellern, eine Übersicht findet gibt es hier: https://amzn.to/36lkr4d

Tagged on:         

3 thoughts on “Arduino Einparkhilfe mit VL53L0X IR Laser Entfernungssensor und WS2812B NeoPixels

  • 3. Dezember 2020 at 14:21
    Permalink

    Ich habe das Projekt mit einem Ultraschallsensor der obigen Art (HC-SR04) umgesetzt, und ich wollte wissen, wie man die LEDs alle auf schwarz setzen kann, wenn 5 Sekunden lang keine Änderung der gemessenen Entfernung passiert. LG Jack

    Reply
  • 26. September 2021 at 11:42
    Permalink

    Hallo,
    Danke für das tolle Video und ein tolles Projekt.
    Hab es auch nachgebaut und Funktioniert, Danke!
    Eine Frage hab ich noch: Wenn ich die Range auf 500 -2000 mm änder reicht es diese werte zu ändern ?
    #define RANGESTARTMM 2000
    #define RANGEENDMM 500
    oder muss ich noch was ändern?
    Mit freundlichen Grüßen
    H.Maier

    Reply
  • 13. April 2023 at 16:49
    Permalink

    Echt interessant, danke für den Beitrag. Das Feedback des Sensors scheint aber etwas lahm zu sein, liegt es an der Methode distanceSensor.readRangeSingleMillimeters()?
    Oder ist da noch irgendwo eine künstliche Pause drin?

    Reply

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Time limit is exhausted. Please reload the CAPTCHA.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.