VL53L0X und VL53L1X – ToF Abstandssensoren

Über den Beitrag

In meiner Reihe über Licht-, Gestik-, Bewegungs- und Abstandssensoren, die ich mit einer Gesamtübersicht abschließen werde, möchte ich diesmal die Abstandssensoren VL53L0X und VL53L1X vorstellen. Dabei handelt es sich um die großen Brüder des VL6180X, über den ich in meinem letzten Beitrag geschrieben habe. Ich werde zunächst auf die Eigenschaften der eigentlichen Sensoren und der Module eingehen. Dann werde ich Bibliotheken vorstellen, mit denen man die Funktionen des VL53L0X und VL53L1X bequem nutzen kann. 

Der größte Unterschied zwischen den drei Sensoren ist ihre Reichweite. Den VL6180X könnt Ihr bis zu Entfernungen von 20 cm einsetzen. Der VL53L0X und VL53L1X haben wesentlich höhere Reichweiten von bis zu 200 bzw. 400 cm. Datenblätter für den VL53L0X und VL53L1X gibt es hier bzw. hier.  

Das Messprinzip

Die Sensoren funktionieren nach dem Time-of-Flight (ToF) Prinzip. Sie besitzen dazu einen IR Laser dessen reflektierte Strahlen hinsichtlich ihrer Flugzeit ausgewertet werden. Bei dem IR Laser handelt es sich um einen Vertical Cavity Surface-Emitting Laser (VCSEL) mit der für den Menschen unsichtbaren Wellenlänge von 940 Nanometer. Das reflektierte Licht wird von einem Photodioden Array detektiert. Dabei verwenden die Sensoren sogenannte Single Photon Avalanche Diodes (SPADs).

VL53L0X und VL53L1X erreichen eine Auflösung in Millimetern. Um einen Millimeter zurückzulegen, benötigt Licht ca. 3.3 x 10-12 Sekunden. Daher ist es erstaunlich, dass ein Massenartikel so etwas auflösen kann. Wenn ein Computer oder Microcontroller in dieser Zeit nur einen einzigen Takt ausführte, entspräche das schon einer Taktfrequenz von 330 GHz. Und mit einem einzelnen Takt hat man ja noch lange keine Rechenoperation durchgeführt. 

Für die, die den letzten Beitrag nicht gelesen haben: wer sich für die Details der Methode interessiert, der kann hier noch einen Artikel dazu lesen oder sich hier auf Wikipedia schlau machen. 

Grundlegende Eigenschaften

VL53L0X und VL53L1X - die blanken Sensoren
Die blanken Sensoren – links: VL53L0X, rechts: VL53L1X

VL53L0X vs VL53L1X – Gemeinsamkeiten

Allgemeines

VL53L0X und VL53L1X sind im Gegensatz zum VL6180X reine Abstandssensoren. Beide vertragen einen Spannungsbereich zwischen 2.6 und 3.5 Volt. Das gilt aber nur für die eigentlichen Bausteine. Bei den Modulen hingegen hängt der Spannungsbereich von der individuellen Ausführung ab. Beide Sensoren haben identische Pinouts. 

Kalibrierung

Beide Sensoren können bezüglich verschiedener Parameter kalibriert werden, die insbesondere dann zum Tragen kommen, wenn man die Teile verbaut. So könnt Ihr z.B. einen Abstandsoffset einstellen.

Verbaut ihr den VL53L0X oder VL53L1X hinter einem Abdeckglas, dann kommt es durch die Reflexion zum sogenannten Cross-Talk Effekt, der zu Fehlern in der Abstandsmessung führt. Deshalb könnt ihr auch diesen Effekt „herauskalibrieren“. Für weitere Kalibrierungen schaut bitte in die Datenblätter. 

Kommunikation und Ansteuerung über APIs

Die Kommunikation läuft über I2C. Die voreingestellte I2C Adresse (0x29) könnt ihr über Befehle und nicht wie sonst üblich über Adresspins verändern. Allerdings vergessen beide Sensoren die neue Adresse wieder wenn sie vom Strom getrennt werden. Über geschicktes Nutzen der XSHUT Pins (werden noch besprochen) könnt ihr aber eine Prozedur erstellen, die die Adressänderung bei jedem Einschalten erneut durchführt.

Die Ansteuerung von VL53L0X und VL53L1X ist etwas ungewöhnlich. Denn normalerweise ist man es ja gewohnt Datenblätter mit Registerverzeichnissen zur Verfügung gestellt zu bekommen. Hier hingegen hat sich der Hersteller STMicroelectronics dazu entschieden sogenannte APIs (Application Programming Interfaces) zur Verfügung zu stellen. Ich bin nicht der erste, der sich darüber gewundert hat und auch nicht der einzige, der gerne eine Registerdokumentation gehabt hätte. So gibt es hierzu auch eine Diskussion in der STM Community, einschließlich einer Stellungnahme des Herstellers. 

Die Beschreibung der VL53L0X API findet ihr hier, für den VL53L1X schaut hier

Interrupts

Beide Sensoren haben Interruptfunktionen. Ihr könnt euch über einen Interrupt informieren lassen, wenn ein neuer Messwert vorliegt. Oder ihr stellt ein Level ein oberhalb oder unterhalb dessen ein Interrupt ausgelöst wird. Alternativ könnt ihr auch ein Fenster definieren innerhalb oder außerhalb dessen ein Interrupt ausgelöst wird. 

VL53L0X vs. VL53L1X – Unterschiede

Reichweite

Wie schon erwähnt ist der offensichtlichste Unterschied zwischen dem VL53L0X und VL53L1X die Reichweite. Unter optimalen Bedingungen, d. h. bei guter Reflexion der zu detektierenden Oberfläche und wenig Störlicht, könnt ihr mit dem VL53L0X bis zu zwei Meter erreichen, mit dem VL53L1X hingegen bis zu vier Meter. 

Messprofile

Am VL53L0X könnt ihr diverse Parameter ändern um die Leistung für verschiedene Anwendungsbedingungen zu optimieren. Dazu gehört vor allem die maximale Messzeit (Timing Budget),  aber auch die zulässige Streuung der Ergebnisse, die Laser Pulsperioden und das Minimum der Signalrate. Die Streuung wird als Sigma in mm angegeben, da Störsignale zeitlich versetzt zum Referenzwert detektiert werden und diese Abweichung über die Lichtgeschwindigkeit einer Entfernung entspricht.

Ihr seid relativ frei in der Wahl der Parameter, müsst aber aufpassen, dass die Einstellungen auch harmonieren. Denn im schlechtesten Fall überschreitet ihr immer wieder das Timing Budget ohne dass ein gültiger Messwert vorliegt. Da ist es günstig, dass es in der Beschreibung der API für den VL53L0X vorgefertigte Profile gibt:

Messungsmodi des VL53L0X
Messprofile des VL53L0X

Der VL53L1X kennt die drei Distanzmodi Long, Medium und Short. Für diese Modi sind die Messparameter in der API vordefiniert bzw. verknüpft. Ihr könnt einige der Parameter jedoch ändern um z.B. unter ungünstigen Bedingungen noch Messwerte zu erzeugen. Wie akkurat diese Messergebnisse dann noch sind ist eine andere Frage. 

Die Reichweite hängt je nach Modus unterschiedlich stark vom Umgebungslicht ab. Hier die Werte im Dunkeln / bei starkem Umgebungslicht bei 88% Reflexion und Timing Budget von 100 Millisekunden: 

  • Short: 136 cm / 135 cm
  • Medium: 290 cm / 76 cm
  • Long: 360 cm / 73 cm

Die Auswahl „Long“ beim VL53L1X ist also keine Garantie, dass ihr unter allen Bedingungen wirklich große Reichweiten erreicht! Bei viel Licht erreicht ihr mit „Short“ sogar größere Reichweiten.  

Neben der Wahl des Distanzmodus wird die Reichweite und Genauigkeit des VL53L1X auch durch das Timing Budget beeinflusst. 20 Millisekunden ist die kürzeste Auswahl, die nur im Short Modus funktioniert. Mit 140 Millisekunden können im Dunkeln bei hoher Reflexion die 4 Meter erreicht werden. Im Datenblatt gibt es graphische Darstellungen der Abhängigkeit von Distanz und Wiederholbarkeit vs. Timing Budget. 

Messfrequenz

Beim VL53L0X könnt ihr bezüglich der Messfrequenz folgende Modi einstellen:

  • Single Ranging: einzelne Messung „auf Anfrage“ (polling)
  • Continous Ranging: ist eine Messung beendet, wird sofort die nächste gestartet
  • Timed Ranging: kontinuierliche Messung mit einstellbaren Pausen dazwischen

Bei dem VL53L1X gibt es nur den Continous Mode und den Timed Ranging Mode. 

(De-)Aktivierung der Spads

Der VL53L1X besitzt zur Detektion ein 16 x 16 Spad Array. Standardmäßig sind alle Spads aktiviert. Dadurch entsteht ein Erfassungskegel (FoV = Field of View) mit einer Öffnung von 27°. Durch Deaktivierung eines Teils der Spads lässt sich der Kegel bis auf 15° bei 4 x 4 aktivierten Spads verengen und die Richtung (ROI = Region of Interest) vorgeben. Der VL53L0X kennt diese Optionen nicht. 

VL53L0X und VL53L1X Module

Verschiedene VL53L0X und VL53L1X Module

Preise

VL53L0X Module gibt es z. B. bei Amazon in einer breiten Preisspanne von ca. 7 Euro (einschl. Versand) bis über 20 Euro. VL53L1X Module habe ich nicht unter 16 Euro bei Amazon gesehen (Stand August 2019). Das hängt sicherlich damit zusammen, dass es den Sensor erst seit Anfang 2018 gibt. Der Preis wird sicherlich noch runtergehen.

Eigenschaften

Im Gegensatz zu den blanken Sensoren haben die Module in der Regel Spannungsregulatoren, so dass ihr sie meist zwischen 2.8 und 5.5 Volt betreiben könnt. Prüft dazu die Angaben des Lieferanten.

Die meisten Module haben sechs Ein-/Ausgänge. Neben GND / VCC und SDA/SCL für die I2C Kommunikation sind das XSHUT und GPIO1. Manchmal sind die Bezeichnungen etwas abweichend. XSHUT dient dem Ausschalten des Moduls. Dazu müsst Ihr XSHUT auf LOW setzen. Ein modulinterner Pull-Up Widerstand setzt den Pin auf HIGH, d.h. Ihr könnt ihn einfach unverbunden lassen, wenn ihr die Funktion nicht nutzen wollt. GPIO1 ist der Interruptausgang. Nutzt Ihr keine Interrupts, könnt ihr auch ihn unverbunden lassen. Die Interruptpolarität lässt sich einstellen. 

Beschaltung

Anschluss eines VL53L0X an einen Arduino UNO
Anschluss eines VL53L0X (Modell Adafruit) an einen Arduino UNO

Die Beschaltung der VL53L0X und VL53L1X Module ist identisch. Pull-Up Widerstände für die I2C Leitungen brauchte ich nicht. Das müsst ihr selbst probieren. Pin 3 dient als Interruptpin. Die LED an Pin 13 wird für einen der Beispielsketche benötigt. 

Bibliotheken

Ich habe einige Bibliotheken für die Sensoren ausprobiert. Leider habe ich für den VL53L0X keine Bibliothek gefunden, mit der ich voll zufrieden war. Insbesondere waren die Interruptfunktionen nicht implementiert. Die Abstandsmessung selbst funktioniert aber z. B. mit der Bibliothek von Adafruit oder mit der von Pololu. Bei der Adafruit Bibliothek wird ein Beispielsketch für den Betrieb von zwei VL53L0X mitgeliefert. Die Prozedur wird zudem hier im Learning Bereich von Adafruit beschrieben. Insgesamt gefiel mir aber die Bibliothek von Pololu besser. 

Für den VL53L1X ist die Bibliothek von Sparkfun mein Favorit, denn in ihr sind alle aus meiner Sicht wichtigen Funktionen implementiert worden. Ihr bekommt sie hier auf Github oder ihr sucht sie über die Bibliotheksverwaltung der Arduino IDE.

Steuerung des VL53L0X mit der Pololu Bibliothek

Der von Pololu mitgelieferte Beispielsketch für Einzelmessungen hat die weiter oben genannten Messprofile aus dem User Manual der VL53L0X API implementiert. Die Voreinstellung ist der Default Mode. Wollt ihr in den Long Range, High Speed oder High Accuracy Modus, dann müsst ihr lediglich die entsprechenden „#define“ Zeilen entkommentieren. Ihr könnt auch noch die Bedingungen für diese Modi ändern. Allerdings – wie schon vorher erwähnt – muss das natürlich alles zusammenpassen. 

/* This example shows how to get single-shot range
 measurements from the VL53L0X. The sensor can optionally be
 configured with different ranging profiles, as described in
 the VL53L0X API user manual, to get better performance for
 a certain application. This code is based on the four
 "SingleRanging" examples in the VL53L0X API.

 The range readings are in units of mm. */

#include <Wire.h>
#include <VL53L0X.h>

VL53L0X sensor;

// Uncomment this line to use long range mode. This
// increases the sensitivity of the sensor and extends its
// potential range, but increases the likelihood of getting
// an inaccurate reading because of reflections from objects
// other than the intended target. It works best in dark
// conditions.

//#define LONG_RANGE

// Uncomment ONE of these two lines to get
// - higher speed at the cost of lower accuracy OR
// - higher accuracy at the cost of lower speed

//#define HIGH_SPEED
//#define HIGH_ACCURACY

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

  sensor.init();
  sensor.setTimeout(500);

#if defined LONG_RANGE
  // lower the return signal rate limit (default is 0.25 MCPS)
  sensor.setSignalRateLimit(0.1);
  // increase laser pulse periods (defaults are 14 and 10 PCLKs)
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
#endif

#if defined HIGH_SPEED
  // reduce timing budget to 20 ms (default is about 33 ms)
  sensor.setMeasurementTimingBudget(20000);
#elif defined HIGH_ACCURACY
  // increase timing budget to 200 ms
  sensor.setMeasurementTimingBudget(200000);
#endif
}

void loop()
{
  Serial.print(sensor.readRangeSingleMillimeters());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }

  Serial.println();
}

 

Zu der Bibliothek gibt es auch noch einen Beispielsketch für den Continous Modus. Der macht aber eigentlich nur in Verbindung mit Interrupts wirklich Sinn. Und die sind anscheinend in der Bibliothek nicht implementiert. 

/* This example shows how to use continuous mode to take
range measurements with the VL53L0X. It is based on
vl53l0x_ContinuousRanging_Example.c from the VL53L0X API.

The range readings are in units of mm. */

#include <Wire.h>
#include <VL53L0X.h>

VL53L0X sensor;

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

  sensor.init();
  sensor.setTimeout(500);

  // Start continuous back-to-back mode (take readings as
  // fast as possible).  To use continuous timed mode
  // instead, provide a desired inter-measurement period in
  // ms (e.g. sensor.startContinuous(100)).
  sensor.startContinuous();
}

void loop()
{
  Serial.print(sensor.readRangeContinuousMillimeters());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }

  Serial.println();
}

 

Steuerung des VL53L1X mit der Sparkfun Bibliothek

Als Einstieg in die Sparkfun Bibliothek empfehle ich den Beispielsketch „Example2_SetDistanceMode.ino“. Die Bibliothek hat die Distance Modes „Short“ (bis 1.3 Meter) und „Long“ (bis 4 Meter) implementiert. Ansonsten werden in dem Sketch keine weiteren Einstellmöglichkeiten aufgezeigt. 

/*
  Reading distance from the laser based VL53L1X
  By: Nathan Seidle
  Revised by: Andy England
  SparkFun Electronics
  Date: April 4th, 2018
  License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).

  SparkFun labored with love to create this code. Feel like supporting open source hardware? 
  Buy a board from SparkFun! https://www.sparkfun.com/products/14667

  This example prints the distance to an object.

  Are you getting weird readings? Be sure the vacuum tape has been removed from the sensor.
*/

#include <Wire.h>
#include "SparkFun_VL53L1X.h"

//Optional interrupt and shutdown pins.
#define SHUTDOWN_PIN 2
#define INTERRUPT_PIN 3

SFEVL53L1X distanceSensor;
//Uncomment the following line to use the optional shutdown and interrupt pins.
//SFEVL53L1X distanceSensor(Wire, SHUTDOWN_PIN, INTERRUPT_PIN);

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

  Serial.begin(9600);
  Serial.println("VL53L1X Qwiic Test");

  if (distanceSensor.begin() == true)
  {
    Serial.println("Sensor online!");
  }
  
  distanceSensor.setDistanceModeShort();
  //distanceSensor.setDistanceModeLong();
}

void loop(void)
{
  distanceSensor.startRanging(); //Write configuration bytes to initiate measurement

  int distance = distanceSensor.getDistance(); //Get the result of the measurement from the sensor

  distanceSensor.stopRanging();

  Serial.print("Distance(mm): ");
  Serial.print(distance);

  float distanceInches = distance * 0.0393701;
  float distanceFeet = distanceInches / 12.0;

  Serial.print("\tDistance(ft): ");
  Serial.print(distanceFeet, 2);

  Serial.println();
}

 

Einen guten Überblick über die in der Bibliothek implementierten Einstellmöglichkeiten bekommt ihr, wenn ihr Euch die öffentlichen Funktionen der Bibliotheksdatei Sparkfun_VL53L1X anschaut. Diese sind sehr gut kommentiert: 

bool init(); //Deprecated version of begin
  bool begin(); //Initialization of sensor
  bool checkID(); //Check the ID of the sensor, returns true if ID is correct
  void sensorOn(); //Toggles shutdown pin to turn sensor on and off
    void sensorOff(); //Toggles shutdown pin to turn sensor on and off
  VL53L1X_Version_t getSoftwareVersion(); //Get's the current ST software version
  void setI2CAddress(uint8_t addr); //Set the I2C address
  int getI2CAddress(); //Get the I2C address
  void clearInterrupt(); // Clear the interrupt flag
  void setInterruptPolarityHigh(); //Set the polarity of an active interrupt to High
  void setInterruptPolarityLow(); //Set the polarity of an active interrupt to Low
  uint8_t getInterruptPolarity(); //get the current interrupt polarity
  void startRanging(); //Begins taking measurements
  void stopRanging(); //Stops taking measurements
  bool checkForDataReady(); //Checks the to see if data is ready
  void setTimingBudgetInMs(uint16_t timingBudget); //Set the timing budget for a measurement
  uint16_t getTimingBudgetInMs(); //Get the timing budget for a measurement
  void setDistanceModeLong(); //Set to 4M range
  void setDistanceModeShort(); //Set to 1.3M range
  uint8_t getDistanceMode(); //Get the distance mode, returns 1 for short and 2 for long
  void setIntermeasurementPeriod(uint16_t intermeasurement); //Set time between measurements in ms
  uint16_t getIntermeasurementPeriod(); //Get time between measurements in ms
  bool checkBootState(); //Check if the VL53L1X has been initialized
  uint16_t getSensorID(); //Get the sensor ID
  uint16_t getDistance(); //Returns distance
  uint16_t getSignalPerSpad(); //Returns the average signal rate per SPAD (The sensitive pads that detect light, the VL53L1X has a 16x16 array of these) in kcps/SPAD, or kilo counts per second per SPAD.
  uint16_t getAmbientPerSpad(); //Returns the ambient noise when not measuring a signal in kcps/SPAD.
  uint16_t getSignalRate(); //Returns the signal rate in kcps. All SPADs combined.
  uint16_t getSpadNb(); //Returns the current number of enabled SPADs
  uint16_t getAmbientRate(); // Returns the total ambinet rate in kcps. All SPADs combined.
  uint8_t getRangeStatus(); //Returns the range status, which can be any of the following. 0 = no error, 1 = signal fail, 2 = sigma fail, 7 = wrapped target fail
  void setOffset(int16_t offset); //Manually set an offset in mm
  int16_t getOffset(); //Get the current offset in mm
  void setXTalk(uint16_t xTalk); //Manually set the value of crosstalk in counts per second (cps), which is interference from any sort of window in front of your sensor.
  uint16_t getXTalk(); //Returns the current crosstalk value in cps.
  void setDistanceThreshold(uint16_t lowThresh, uint16_t hiThresh, uint8_t window);//Set bounds for the interrupt. lowThresh and hiThresh are the bounds of your interrupt while window decides when the interrupt should fire. The options for window are shown below.
  //0: Interrupt triggered on measured distance below lowThresh.
  //1: Interrupt triggered on measured distance above hiThresh.
  //2: Interrupt triggered on measured distance outside of bounds.
  //3: Interrupt triggered on measured distance inside of bounds.
  uint16_t getDistanceThresholdWindow(); //Returns distance threshold window option
  uint16_t getDistanceThresholdLow(); //Returns lower bound in mm.
  uint16_t getDistanceThresholdHigh(); //Returns upper bound in mm
  void setROI(uint16_t x, uint16_t y); //Set the height and width of the ROI in SPADs, lowest possible option is 4. ROI is always centered.
  uint16_t getROIX(); //Returns the width of the ROI in SPADs
  uint16_t getROIY(); //Returns the height of the ROI in SPADs
  void setSignalThreshold(uint16_t signalThreshold); //Programs the necessary threshold to trigger a measurement. Default is 1024 kcps.
  uint16_t getSignalThreshold(); //Returns the signal threshold in kcps
  void setSigmaThreshold(uint16_t sigmaThreshold); //Programs a new sigma threshold in mm. (default=15 mm)
  uint16_t getSigmaThreshold(); //Returns the current sigma threshold.
  void startTemperatureUpdate(); //Recalibrates the sensor for temperature changes. Run this any time the temperature has changed by more than 8°C
  void calibrateOffset(uint16_t targetDistanceInMm); //Autocalibrate the offset by placing a target a known distance away from the sensor and passing this known distance into the function.
  void calibrateXTalk(uint16_t targetDis

 

Ich habe dann noch einen eigenen Sketch geschrieben, in dem ich ein Interruptfenster definiert habe. Bei Erfassung eines Abstandes innerhalb der Limits wird ein Interrupt ausgelöst, die LED an Pin 13 leuchtet auf und es wird eine Meldung auf dem seriellen Monitor ausgegeben. Dazu habe ich dem Sketch noch eine Funktion spendiert, die zu Beginn einige der Einstellungen des VL53L1X auf dem seriellen Monitor ausgibt. 

#include <ComponentObject.h>
#include <RangeSensor.h>
#include <SparkFun_VL53L1X.h>
#include <vl53l1x_class.h>
#include <vl53l1_error_codes.h>


#include <Wire.h>
#include "SparkFun_VL53L1X.h"

//Optional interrupt and shutdown pins.
#define SHUTDOWN_PIN 2
#define INTERRUPT_PIN 3
volatile bool event = false;
byte ledPin = 13;

//SFEVL53L1X distanceSensor;
//Uncomment the following line to use the optional shutdown and interrupt pins.
SFEVL53L1X distanceSensor(Wire, SHUTDOWN_PIN, INTERRUPT_PIN);

void setup() {
  Wire.begin();
  distanceSensor.sensorOn();
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), blink, FALLING);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  Serial.println("Interrupt Test");

  if (distanceSensor.begin() == true) {
    Serial.println("Sensor online!");
  }

  distanceSensor.setInterruptPolarityLow();
  distanceSensor.setDistanceThreshold(300, 1000, 3);
  showSettings();
  delay(2000); // um Zeit zu haben die Settings zu sehen
  distanceSensor.startRanging();
  event = false;
  distanceSensor.clearInterrupt();

}

void loop(void) {
  if (event) {
    int distance = distanceSensor.getDistance();
    Serial.print("Interrupt! Current distance: ");
    Serial.println(distance);
    digitalWrite(ledPin, HIGH);
    delay(500);
    digitalWrite(ledPin, LOW);
    event = false;
    distanceSensor.clearInterrupt();
  }
}

void blink() {
  event = true;
}

void showSettings() {
  Serial.print("Interrupt polarity is: ");
  byte interruptPolarity = distanceSensor.getInterruptPolarity();
  if (interruptPolarity == 0) {
    Serial.println("Low");
  }
  if (interruptPolarity == 1) {
    Serial.println("High");
  }
  Serial.print("Offset [mm]: ");
  unsigned int offset = distanceSensor.getOffset();
  Serial.println(offset);
  Serial.print("Distance Mode: ");
  byte distMode = distanceSensor.getDistanceMode();
  if (distMode == 1) {
    Serial.println("Short Mode");
  }
  else if (distMode == 2) {
    Serial.println("Long Mode");
  }
  unsigned int timingBudget = distanceSensor.getTimingBudgetInMs();
  Serial.print("Timing Budget: ");
  Serial.println(timingBudget);

  unsigned int interMeasurementPeriod = distanceSensor.getIntermeasurementPeriod();
  Serial.print("Inter Measurement Period [ms]: ");
  Serial.println(interMeasurementPeriod);

  unsigned int spads = distanceSensor.getROIX();
  Serial.print("Active Spad Array, x: ");
  Serial.print(spads);
  spads = distanceSensor.getROIY();
  Serial.print(", y: ");
  Serial.println(spads);
}

 

Festgestellte Probleme

Die meisten Funktionen funktionieren wunderbar, trotzdem habe ich ein paar kleinere Probleme festgestellt:

  • Ändert man die I2C Adresse mit setI2CAddress(), dann wird daraus eine um ein Bit verschobene Adresse. Intern wird anscheinend das Read/Write Bit zugefügt. 
  • Das Spad Array konnte ich nur auf minimal 11 x 11 reduzieren. Da drunter gab es keine vernünftigen Ergebnisse mehr – egal was ich sonst noch eingestellt habe 
  • Ab und zu macht der VL53L1X nach Änderungen von Einstellungen nicht das was er soll. Dann hilft es ihn zwischenzeitlich kurz vom Strom zu nehmen. Das gilt übrigens auch für den VL53L0X.

Danksagung

Das Männchen auf dem Beitragsbild stammt von Peggy und Marco Lachmann-Anke auf Pixabay. Von Holger Langmaier stammt das Maßband, auch auf Pixabay. Das Fritzing Schema des VL53L0X stammt von Adafruit auf Github. Dann gilt mein Dank natürlich Pololu und Sparkfun für die Bibliotheken.    

2 thoughts on “VL53L0X und VL53L1X – ToF Abstandssensoren

Schreibe einen Kommentar

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