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:

Messprofile 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 (Modell Adafruit) 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.    

94 thoughts on “VL53L0X und VL53L1X – ToF Abstandssensoren

  1. Guten Abend Wolfgang

    vielen Dank für die sehr verständliche Abhandlung.

    Ich lese in den gestellten Fragen immer wieder über das Reflexionsvermögen. Welche Oberflächen eignen sich den vor allem für die Abstandsmessung? Im Datenblatt des VL53L1X lese ich die Aussage: Smart building and smart lighting (people detection, gesture control). Bedeutet das, dass der Abstand einer sich bewegenden Person mit diesem Sensor während mehreren Sekunden gemessen werden kann?

    1. Hi Christoph,
      diese Module senden infrotes Licht. Es wird gut reflektiert von:
      * Metalle: Deswegen packt man Essen zum Warmhalten gerne in Alufolie. Ihre Elektronenstruktur erlaubt es, dass sie elektromagnetische Strahlung (inklusive IR-Licht) effizient reflektieren.
      * Glänzende Oberflächen: Oberflächen, die glatt und reflektierend sind, wie poliertes Glas (-> Treibhauseffekt) oder Keramik.
      * Spezielle Infrarot-Reflektoren: Bestimmte Materialien und Beschichtungen werden entwickelt, um IR-Strahlung gezielt zu reflektieren, z.B. bei Wärmeschutzfolien.
      Absorbiert infrarotes Licht, „verschluckt“ es also:
      * Dunkle und matte Materialien: Z.B. schwarzes Gewebe oder matte Kunststoffe.
      * Wasser und feuchte Materialien: Wasser absorbiert infrarotes Licht besonders gut.
      * Biologisches Gewebe: u. a. wg. des Wassergehaltes.
      Zu viele Gedanken würde ich mir deswegen aber nicht machen, es sei denn du möchtest ausgesprochen kleine Dinge detektieren oder wirklich an die absolute Reichweitengrenze kommen.

      Zur zweiten Frage: Das minimale Zeitbudget, also die Zeit, nach der eine Messung als „out of range“ abgeschlossen wird, sind 20 ms. Du kannst also eine ganze Menge an Messungen pro Sekunde durchführen.

      VG, Wolfgang

  2. Hallo Wolfgang,

    danke für diesen tollen Beitrag!

    Ich habe da mal eine Frage. Wie groß muss das Target innerhalb der FoV sein, damit es erfasst wird? Konnte im Datenblatt nichts finden (bin allerdings auch nicht ehr geübt im Datenblatt-lesen 🙂

    Liebe Grüße
    TOBi
    TOBi

    1. Hallo TOBi,

      eine gute Frage. Antworten, die so beginnen, bedeuten leider meistens, dass der Gefragte die Antwort nicht weiß! Aber tatsächlich ist die Frage auch nicht so eindeutig zu beantworten, wie du es wahrscheinlich gerne hättest, wie z.B. in Prozent des Erfassungskreises. Die Problematik ist, dass außer Abstand und Größe des erfassenden Objektes auch sein Reflektionsvermögen für Infrarotstrahlung, seine Oberflächenbeschaffenheit und die (Infrarot-)Lichtverhältnisse. Im Datenblatt des VL53L1X gibt es in Abschnitt 3 Testergebnisse für verschiedene Oberflächen mit unterschiedlichem Reflexionsvermögen bei normalen Lichtverhältnissen und im Dunkeln. Die Versuche wurden mit Objekten durchgeführt, die 100 % des FoV abdeckten. Aber die großen Unterschiede in den Ergebnissen zeigen, dass es außer der Größe eben sehr auf die anderen Randbedingungen ankommt.

      VG, Wolfgang

  3. Hallo Wolfgang,

    Du warst warst maßgeblich daran beteiligt das auch ich mich mit Arduino beschäftigt habe. Vielen Dank dafür !

    Da ich besser in Stahlbau bin als in Elektronik habe ich eine Frage:
    Ich möchte den Ausgefahrenen Weg eines Hydraulikzylinders erfassen. Der Sensor steht ihm gegenüber, am Kopf wird als Reflektionsfläche ein Blech oder weißes Kunststoff befestigt.
    Der Sensor funktioniert auf den benötigten 1400mm Hubweg, allerdings streut er mir immer wieder falsche Werte ein, z. B. 8000mm
    Verwendet habe ich Deinen Sketch in Long Range wie Beschrieben, der geht auch wirklich am besten!

    Die Mechanik ist eine Hebebühne mit vier Zylindern, an jeder Ecke einer. Selbstgebaute Servoventile sollen später die Nivellierung regeln.

    Ich hätte gerne Sensoren auf die ich mich besser verlassen kann und die eventuell besser als 3% Fehlerrate laufen. Ich bin mir nicht sicher ob die Meßwerte sauber genug sind wenn ich den VL53L1X nehme.

    Andere Methoden wie z.B. Ultraschall scheiden immer wieder aus weil ich Angst habe das die sich gegenseitig stören werden.

    Reicht der VL53L1X ?? Was wird in einem Entfernungsmesser von z.B. Bosch benutzt den die Maurer haben? Warum zeigen die auch 5X hinter einander den gleichen Wert an?

    1. Hallo Daniel, ich weiß nicht wirklich, was in diesen Bosch Geräten verwendet wird. Die in diesem und anderen Beiträgen verwendeten Sensoren sind die im Hobbybereich üblichen Vertreter, die man zu erschwinglichen Preisen bekommt. Ob man solche Sensoren, wie sie in den Bosch Geräten verwendet werden, als Einzelteil bekommen kann und ob das dann auch in einer Form wäre, die mit einem Mikrocontroller ohne viel Extrabeschaltung steuerbar ist, kann ich leider nicht beantworten. Die eine andere Fehlmessung könntest du per Programm identifizieren und herausnehmen.
      VG, Wolfgang

  4. Hallo,
    ich möchte einen VL53L0X draußen im freien verwenden.
    Wie kann ich den VL53L0X vor Wasser schützen ohne die Messung zu beeinträchtigen?
    Hinter eier Glasscheibe?

    Grüße
    Dirk

    1. Hallo, der Laser des VL53L0X benutzt nahes Infrarot. Glas ist ein weiter Oberbegriff, also kommt es darauf an, was für ein Glas du verwendest. „Normales“ Glas sollte einigermaßen durchlässig sein. Abgesehen von der Sorte ist es auch eine Frage der Dicke. Je dünner, desto besser. Gewisse Abstriche in der Reichweite wirst du machen müssen. Als Alternative kämen noch einige Plastiksorten infrage, z.B. Polyethylen oder Polypropylen. Plastik leidet allerdings auf Dauer unter UV-Strahlung. Ich bin ein Freund des Ausprobierens. Ich würde mir das mal provisorisch zusammenbauen und die Reichweite prüfen.
      VG, Wolfgang

  5. Hallo Wolfgang,

    ich habe heute versucht, einen VL53L1X mit zephyr zum Laufen zu bekommen. Also eine andere Plattform. Was mir bei meinen Test aufgefallen ist, ist das die Wiederholgenauigkeit bei mir relativ schlecht ist, locker 10cm Differenz bei 150cm Abstand.

    Was ist da Deine Erfahrung damit?

    Gruß
    Achim Kraus

    1. Hallo Achim, ist schon etwas her, dass ich die Dinger ausprobiert habe, aber 10 cm erscheint mir auch recht viel. Es könnt aber auch vom zu detektierenden Objekt (Oberflächenstruktur, Einfallwinkel, Material und Größe der Fläche) abhängen. Hast du es mal mit einer Wand probiert? Sind die Werte dann immer noch so wenig reproduzierbar? Und hast du mal mit den Distanzmodi gespielt? Grüße, Wolfgang

      1. Ich messe vom Tisch (mit Erhöhung) gegen eine weiße Decke.
        Gemäß Meterstab 150cm.

        Ich teste mit allen 3 Modes (short, medium, long), und bekomme für jeden Mode grundsätzlich andere Werte.

        Short: 588-537 mm
        Medium: 1294-1274 mm
        Long: 2229-2133 mm

        roi ist 4×4, zentriert.
        Mit 6×6, Long, bekomme ich 2050-1898 mm

        Wenn ich einen zweiten VL53L1X nehme, ist das Ergebnis das selbe.

        Den ST Treiber Code habe ich gerade upgedatet.
        Aber das Ergebnis ist immer noch gleich schlecht.

        Was ich auch sehr irritierend finde:
        Ich Kalibriere auf 15cm.
        Und wenn ich dann messe, bekomme ich 20 cm.

        Bin gespannt , was da noch raus kommt.

        1. Ich habe gerade einen VL53L1X von der Fa. Pimoroni hervorgekramt und getestet (Arduino / Sparkfun Bibliothek). Vom Schreibtisch an die Decke gerichtet. Long Modus, 16 x 16 Spad Array. Damit bekomme ich Ergebnisse von 181,1 – 181,7. Mit 6×6 wird es etwas ungenauer, aber nicht wesentlich. Ich weiß nicht wirklich, woran deine Abweichungen liegen könnten. Ist auch schwierig, dass wir unterschiedliche Plattformen benutzen. Eine Frage habe ich noch: ist vielleicht noch eine Schutzfolie auf dem Modul? Das ist mir schon mal passiert….

          1. > Damit bekomme ich Ergebnisse von 181,1 – 181,7.

            Vielen Dank! Das hilft mir sehr. Das macht Hoffnung, dass der VL53L1X grundsätzlich funktioniert.

            > Schutzfolie

            Diese gelblich Schutzfolie wie oben auf Deinen Bildern?
            Die ist weg.

            Ich denke inzwischen, dass die ST Bibliothek (2.3.3 und 2.4.5) u.U. das Problem ist. Wenn ich von Mode 2 (Medium) auf Mode 3 (Long) umschalte bekomme ich deutlich andere Werte. Wie wenn die ST Bibliothek zwar den Sensor konfiguriert, aber die Auswertung nicht anpasst, oder andersrum. Schade das ST hier nur Code und keine Register Doku liefert.
            Ich lese mir mal die API Doku durch und prüfe, ob das alles passt
            Letztlich werde ich im ST Forum mal fragen müssen.

            Ich habe mir auch einen VL53L0X bestellt, vielleicht funktioniert der besser. Und mal ein anderes VL53L1X Model testen, vielleicht funktioniert das auch besser.

              1. Mit dem VL53L0X und Zephyr funktioniert es wunderbar. Ist aber auch eine andere ST Bibliothek.

                Ich habe mir nun auch ein Arduino UNO R4 Minima und das original VL53L1X-SATEL bestellt, Mal sehen, was damit die Ergebnisse sind.

              2. Inzwischen habe ich neue Ergebnisse:

                – die Tests sind nun mit einem Arduino UNO R4 Minima
                – 2x VL53L1X von Amazon => Messwert schwankt sehr, und Ergebnis wird vom Sensor selber als Fehler markiert.
                – 2x VL53L1X SATEL von eine Distributor => Messwert ist stabil.

                Die Messwerte mit zephyr sind bei den VL53L1X SATEL auch besser.

                Ich denke, defekte Ware.

  6. Hallo Wolfgang,

    Vielen Dank für deine Vielen Beiträge zu Abstandsensoren.

    ich hab da eine speziellere Frage:
    Ich möchte durch ein Doppelverglastes (HR++) Fenster eine „Touch“ Steuerung bauen.
    mein erster Gedanke mit nem MPR121 und ca 10 cm großen Kapazitiven Flächen funktioniert leider nicht, da die 2-4 cm Dicke Glasscheibe wohl mit irgendwas bedampft is und ich so nichts durch bekomme.

    jetzt hab ich zum testen einige Sensoren bestellt:
    VL53L0X
    VL6180X
    APDS 9960
    RCWL-0516

    ich muss damit nur triggern können ob eine Hand in 2-4 cm Glasdicke davor gehalten wird oder nicht.
    und das Ganze 4-5 Mal nebeneinander, (um 4 verschiede Videos triggern zu können, bzw Steuerkreuz plus Aktionstaste).

    Die Sensoren sind gerade alle unterwegs und ich wollte mal vorne weg Fragen ob du noch andere Idee hast, welche Sensoren durch HR++ Glas für meinen speziellen anwendungsfall gehen könnten?

    CrossTalk wäre mir egal, ich muss wie gesagt nur einigermaßen zuverlässig triggern ob nen Finger oder ne Hand von Außen auf dem Sensor ist oder nicht…

    Grüße Flo

    1. Hallo Flo, die ersten drei Vertreter funktionieren mit IR Licht. Je nachdem wie die Scheibe IR Licht absorbiert oder durchlässt wird das mit den dreien funktionieren oder nicht. Ich habe hier noch ein paar weitere Sensoren beschrieben:
      https://wolles-elektronikkiste.de/sensorvergleich
      Allerdings basieren funktionieren die meisten auf IR Basis. Wenn also die drei in deiner Auswahl nicht gehen, werden die Alternativen auf IR auch nicht gehen. Ultraschall wird ziemlich sicher ungeeignet sein, da die Scheibe selbst schon reflektieren wird. Der RCWL-0516 funktioniert vielleicht. Sollte er sogar zu gut funktionieren, sprich zu empfindlich sein, kann man die Empfindlichkeit verringern.
      Lass mal hören, wenn du herumprobiert hast. Das könnte auch für andere interessant sein.
      Viel Erfolg!
      VG. Wolfgang

      1. Hab jetzt den APDS9960 und die beiden VL53L0X und L6180X durch. leider Erfolglos.

        auf den RCWL-0516 warte ich gerade noch, allerdings hab ich da bauart bedingt Angst, dass wenn ich 4 davon mit relativ wenig abstand(10-20) zueinander anbringe, die gegenseitig interferieren…

        UV kommt wohl auch nicht in Frage, das wird das Glas auch nicht durch lassen.

        zum Spaß hab ich mal meinen alten Bosch PLR25 Laserentfernungsmesser probiert. der kommt durch die Scheibe allerdings hab ich keine Ahnung was da genau an Sensor verbaut ist.

        habt ihr noch Ideen für andere Sensoren, die nicht im IR spektrum unterwegs sind, die gehen könnten?

        grüße Flo

        1. Das Messprinzip von Entfernungsmesser Komplettgeräten und dem VL53LOX ist im Grunde dasselbe. Beide senden Laserlicht und messen die Zeit, die das reflektierte Licht benötigt, bis es wieder auf den Sensor trifft. Bei geringen Abständen wird dabei nicht wirklich die Zeit gemessen, sondern indirekt über die Phasenverschiebung ermittelt. Unterschied ist, dass der VL53L0X infrarotes Laserlicht benutzt und kein sichtbares. Außerdem dürfte der Laser in den Komplettgeräten stärker sein.
          Ich könnte mir auch vorstellen, dass sich die RCWL-0516 gegenseitig stören, aber Versuch macht klug! Ansonsten könnte man noch etwas mit simplen Lichtsensoren bauen. Wenn eine Hand vor die Scheibe gehalten wird, dann wird es schnell dunkler. Das ließe sich auswerten. Wenn man mehrere Sensoren benutzt, wäre das auch einigermaßen verlässlich, wenn man die Änderung des Lichteinfalls auf alle Sensoren auswertet. Nur im Dunkeln ist das natürlich keine Lösung.

          1. Habs tatsächlich hinbekommen:

            https://www.exp-tech.de/sensoren/lidar/10253/pololu-digital-distance-sensor-10cm
            hiermit gings am Ende.

            (hatte einen Satz an verschiedenen Seonsoren bestellt)

            Allerdings auch erst seitdem ich den Sensor leicht schräg zum Glas aufstelle.
            Parallel zum Glas ging auch nicht…

            (die Idee mit dem leicht schräg hatte ich auch erst bei den neuesten tests, kann gut sein das einer er ersten getesteten Sensoren auch funktioniert hätte)

            Grüße Flo

            1. Hi Flo,
              cool – Glückwunsch! Freut mich. Und danke, dass du das hier noch einmal teilst. Den Sensor kannte ich noch nicht. Schau ich mir auch gelegentlich mal an. Viel Spaß noch mit deinem Projekt!
              VG, Wolfgang

  7. Guter Artikel, danke.
    Für alle die auch ein TTGO-T-Beam Board verwenden:
    Musste bei mir die Pins setzen:
    // Wire.begin(21,22); // ic2 2for T-Beam pass SDA and SCL GPIO pins
    Wire.begin(2, 13); // ic2 1 for T-Beam pass SDA and SCL GPIO pins

    Und diese Belegung:
    Board – Sensor
    2-> SDA (data)
    13-> SCL (clock)

    Dachte erst Verkabelung der 2 Datenkabel ist egal, bekam aber vorher immer diesen Fehler:

    [ 12860][E][Wire.cpp:513] requestFrom(): i2cRead returned Error 263
    [ 14112][E][Wire.cpp:513] requestFrom(): i2cRead returned Error 263
    Failed to boot VL53L0X

  8. Hallo Ewald
    O- Entschuldigung, da habe ich mich falsch ausgedrückt. Ich möchte ein Programm für Arduino welches ich auf ein Arduino Board übertragen werde, z.B. UNO oder NANO. Dann schließe ich den Sensor an das Board und übertrage das Programm auf das Arduino Board mit den Einstelldaten für den Sensor Z.B. neue Adresse. Nun nehme ich den Sensor ab und verwende diesen mit meiner Steuerung, Programm ist in Bascom geschrieben. Die Entfernung auslesen kann ich, aber leider nichts im Sensor ändern. Meine Experimente den Sensor zu parametrieren endeten damit das ich den Lo Bereich ausgeblendet habe und sich die Adresse von 81 auf 66 änderte. Leider weiß ich nicht warum und konnte es auch nicht rückgängig machen. Nachdem ich Deine tollen Beiträge hier gelesen kann ich mir vorstellen das Du so was schon in der Schieblade liegen hast.
    Ich stelle mir das wie gesagt so vor, das ich ein Board von Arduino nehme, das Programm in dem ich zuvor die benötigten Einstellungen für den VL53L0x vorgenommen habe, auf das Arduino Board übertrage. Nach Programmstart wird der Sensor eingestellt und fertig. Kleine Änderungen (Daten) im Arduino Programm kann ich. Leider ist das auch das einzig was ich über Arduino ausführen kann, Projekt laden, Kleinigkeiten ändern, übertragen.
    Es soll für einen Schüler für ein Projekt (Fahrzeug fährt an einer Kante entlang) eine kleine Steuerung werden.
    Ich hoffe ich habe mich diesmal verständlicher ausgedrückt.
    Falls Du was hast was Du mir zur Verfügung stellen könntest währe es sehr nett.
    Ich nehme an, das Du meine E-Mail sehen kannst. Ich sende Dir gern meine Tel. Nr. vielleicht können wir mal zu besseren Verständnis telefonieren
    Mit freundlichem Gruß
    Dieter

    1. Hallo Wolfgang, ich habes verwechselt und Dich falsch angesprochen. Ich habe einen Bekannten der Ewald heiß, es ist mir einfach so durchgerutscht, entschuldige.
      LG Dieter

      1. Kein Problem – das mit dem „Ewald“ als Vornamen passiert vielen!

        Der VL53L0X vergisst seine Einstellungen, nachdem er vom Strom getrennt wurde. Es nützt also nichts die Einstellungen mit einem Arduino vorzunehmen.

        VG, Wolfgang

        1. Das ist schade, aber ich könnte diese(n) einstellen, mit einem Gold Cap puffern und den Bus dann an meine Steuerung stecken. (Es ist ja Spielzeug was da fahren soll)
          Weiß Du welches Register ich umschreiben muß um eine neue Device Adresse zu setzen? Es geht darum das ich 4 Stück an einem Bus verwenden möchte.
          LG Dieter

          1. Hallo, der Hersteller des V53L0X hat sich (leider) dazu entschieden, den Zugriff nicht wie sonst üblich direkt über Register zuzulassen, sondern über eine API, also eine Software Schnittstelle. Jedenfalls scheint es keine Register Dokumentation zu geben. Die API Beschreibung findet sich hier:

            https://www.st.com/content/ccc/resource/technical/document/user_manual/group0/6b/4e/24/90/d8/05/47/a5/DM00279088/files/DM00279088.pdf/jcr:content/translations/en.DM00279088.pdf

            Wie man die Adresse ändert steht auf Seite 20. Wie man die API über Bascom nutzt, das kann ich dir allerdings nicht sagen.

            VG, Wolfgang

  9. Servus Wolfgang!
    Deine Beiträge sind immer super detailliert und somit für jedermann verständlich.
    Großes Dankeschön an dich!
    Ich versuche gerade mittels VL53L1X (GPIO1 setInterruptPolarityHigh(); ) einen ESP32 mit Deep Sleep (ext0 wake up) zu steuern. Verwende dabei Teile deines „interrupt Sketches“.
    Funktion: Wenn der VL53L1X innerhalb (35, 500, 3) eine Messung hat -> GPIO1 = High, soll der ESP32 aufwachen und mittels MQTT den Messwert senden / außerhalb soll der ESP32 schlafen 😴
    Leider habe ich anscheinend ein Timing-Problem. Entweder der ESP32 wacht nicht auf, oder es wird permanent gemessen, egal ob innerhalb oder außerhalb des Messbereiches.
    Hast du eine Idee, woran das liegen kann?
    Danke!

    1. Hallo Helmut, als Erstes würde ich prüfen, ob das Problem beim Liefern des Interrupt-Signals oder beim Einrichten des Deep Sleep Modus liegt. Das könntest du tun, indem du den ESP32 nicht über das Interrupt-Signal weckst, sondern direkt ein HIGH-Signal an den GPIO0 anlegst. Wenn er dann reproduzierbar aufwacht, ist das Problem „auf der Lieferseite“. Wenn nicht, dann ist irgendetwas falsch auf der Empfängerseite, d.h. der Deep Sleep nicht richtig eingerichtet. Und hast du mal einen Pull-Down Widerstand an GPIO0 angelegt (z.B. 10 kOhm)? VG, Wolfgang

  10. Hallo. kann jemand mir helfen?

    Ich habe solches Problem 2xVL53L0X aus Aliexpress und 1xMPU6050 und Arduino Mega. Alleine die Sensore mit den Bord arbeiten top, aber zusammen in einem Sketch, kommt Verlansammerung des Prozes, sogar stop und das meistens bei Winkelmessung von Gyroskope in MPU6050. Idee?
    Ich nutze Adafruit_VL53L0X und Jeff Rolberg library für IMU sensor. Die Sensoren nehemen Strom von Arduino. keine Pullup wiederstande, direkte verbindung zu pin 20 und 21.

    1. Hallo, eine sehr spezielle Frage. Bei zwei Bibliotheken ist die Fehlersuche natürlich schwierig, besonders weil die VL530X Bibliothek ziemlich komplex ist. Ich kann nur raten. Fragst du die Sensoren in fester Reihenfolge hintereinander ab und ist für die VL530X der Single Measurement Mode eingestellt? Wenn ich das richtig sehe dann ist die Abfrage mit der Funktion rangingTest() im Single Mode. Eine Messung mit mit dem VL530X nimmt im Default Mode 30 Millisekunden in Anspruch. Bei zwei VL530X sind das schon 60 Millisekunden. Dann kannst du nur alle 60 Millisekunden den MPU6050 abfragen. Im Continuous Mode musst du nicht auf das Ergebnis warten, das geht schneller.
      Du könntest mir deinen Sketch mal zusenden (wolfgang.ewald@wolles-elektronikkiste.de). Dann schaue ich mal rein. Ich verspreche aber lieber nichts – ich kann nicht viel Zeit investieren.

  11. Hallo,
    ich möchte mir für meine Gartenzisterne eine Niveaumessung mit dem v53l1x bauen. Dazu hab ich mir den Code „VL53L1X_Interrupt_Example.ino“ kopiert und im Prinzip funktioniert es auch. Aber ich vermute, dass der Messkegel zu breit ist. Am Ende des Codes werden die Werte von ROIX und ROIY ausgelesen (16×16). Wie müsste die Weiterführung des Codes sein, um neue Werte für X und Y (z.B. 8×8) zu setzen. Mein bescheidenes Programmierwissen gibt das nicht her. Für Hilfe wäre ich sehr dankbar. Beste Grüße.

    1. Hallo Ludwig, für die Einstellung der Spads gibt es die Funktion setROI(roix, roiy). Für 8×8 also setROI(8,8). Die Funktion kommt ins Setup. Ich hatte Probleme, wenn ich unter 11×11 gegangen bin. Und wahrscheinlich wird die Reichweite geringer. Viel Erfolg & viele Grüße, Wolfgang

      1. Hallo Wolfgang,
        danke erstmal für die schnelle Info. Wenn ich jetzt z.B. „setROI(11,11);“ ins setup schreibe kommt die Fehlermeldung „’setROI‘ was not declared in this scope“. Hab schon rumprobiert, komm aber nicht zu einer Lösung. In der Lib wird die Funktion mit „void setROI(uint16_t x, uint16_t y); “ angegeben. Was muss ich tun, um den Code zum Laufen zu bringen? Am Ursprungs-Code hab ich bis auf Einfügen von setROI… nichts verändert. Gruß Ludwig

        1. Du musst noch den Objektnamen davor setzen, also distanceSensor.setROI(11,11). Dann sollte es gehen.

  12. Hallo!
    Ich habe hier eine sehr spezielle Frage / Anwendung zu dem VL53L0X:
    Ich benutze in einer Anwendung 2 VL53L0X gleichzeitig. Damit das geht, vergebe ich jedem Sensor eine eigene Adresse. Das geht auch ganz gut mit den Beispielen von Pololu oder Adufruit. Jedoch ist die Anwendung batteriebetrieben, und ich messe nur alle 15min. Dazwischen ist der uC (LoRaWAN Heltec cubecell) im Deep Sleep Mode. In der Zeit möchte ich die Spannung von den Sensoren wegnehmen und den XShut-Pin auf Low setzen (sonst benötigt der Sensor teilw. Strom), um eine maximale Batterielebensdauer zu erreichen.
    Jedoch nach dem Aufwecken und initialisieren (Adressen wieder neu vergeben etc.) der Sensoren (bei Adafruit geht das über die Funktion „setID“) klappt das nicht mehr. Die Sensoren gehen in Fehler. Erst ein Neustart / Reset bringt alles wieder zum laufen. Nach dem Deep Sleep wieder das Gleiche 🙁
    Was kann da das Problem sein? So viel kann man da doch nicht falsch machen, oder? Nach dem Deep Sleep schalte ich wieder die Spannung für die Sensoren zu warte bis diese stabil anliegt. Dann mache ich die Initialisierung der Sensoren…Für Tipps wäre ich dankbar.
    Beste Grüße
    Martin

    1. Hallo Martin,

      aus der Ferne und bei einem µC den ich noch nicht ausprobiert habe ist das mit der Fehleranalyse nicht so einfach.

      Vom Prinzip her sehe ich das so wie du: wenn die VL53L0X abschaltest und vom Strom trennst, dann sollten sie im Prinzip mit derselben Prozedur wieder initialisierbar sein wie beim frischen Start.

      Vielleicht findest du hier noch einen Hinweis:
      https://learn.adafruit.com/adafruit-vl53l0x-micro-lidar-distance-sensor-breakout/arduino-code

      Bekommst du denn eine Fehlermeldung beim erneuten Initialisieren? Die SetID Funktion aus den Adafruit Beispielen sollte ja „Failed to boot first VL53L0X“ liefern, wenn das nicht funktioniert.

      Du könntest auch mal die Initialisierung mit lox1.begin(LOX1_ADDRESS, true) vornehmen. Das True schaltet die Debug Funktion der Bibliothek an und du bekommst mehr Meldungen.

      Oder es ist irgendetwas auf der µC Seite. Vielleicht mag er nicht, dass irgendwelche Variablen nochmal initialisiert werden?

      VG, Wolfgang

      1. Hallo Wolfgang,

        ja, ich bekomme die Fehlermeldung „Failed to boot first VL53L0X“.
        Die Debug-Funktion habe ich mal aktiviert. Wenn ich die Spannung nicht wegnehme läuft alles sauber durch (auch das mehrmalige initialisieren der Variablen ist kein Problem) und die Debug-Meldung sieht wie folgt aus:
        VL53L0X Info:
        Device Name: VL53L0X ES1 or later, Type: VL53L0X, ID: VL53L0CBV0DH/1$1
        Rev Major: 1, Minor: 1
        VL53L0X: StaticInit
        VL53L0X: PerformRefSpadManagement
        refSpadCount = 4, isApertureSpads = 0
        VL53L0X: PerformRefCalibration
        VL53L0X: SetDeviceMode

        Wenn ich zwischendurch die Spannung komplett wegschalte (VCC = 0V UND XShut auf Low) erhalte ich folgende Fehlermeldung aus dem Debug heraus:

        VL53L0X Info:
        Device Name: VL53L0X ES1 or later, Type: VL53L0X, ID: 
        Rev Major: 1, Minor: 15
        Error expected cut 1.1 but found 1,15
        VL53L0X Error: -5
        Failed to boot first VL53L0X

        Aber wer kann jetzt damit was anfangen?
        Ich werde nochmal lesen, ob unter dem Link von Dir etwas zu finden ist…
        Ansonsten bin ich natürlich dankbar für weitere Hinweise!

        Beste Grüße
        Martin

        1. Ich habe ein bisschen in der Bibliothek gewühlt und das zum Error -5 gefunden:

          #define VL53L0X_ERROR_NOT_SUPPORTED ((VL53L0X_Error)-5)
          /*!< Function is not supported in current mode or configuration */ Auch nicht wirklich hilfreich. Und Rev Major / Rev Minor haben irgendetwas mit der Sensor Version zu tun. Aber da ja alles funktioniert, wenn du die Sensoren frisch startest, glaube ich nicht, dass da das Problem liegt. Tut mir leid, ich glaube ich kann die da aus der Ferne wenig helfen.

        2. Hallo Martin

          ich nutzte zwar nicht den Deep Sleep oder schalte die VCC der Sensoren ganz weg, jedoch hatte ich einige Mühe zwei Sensoren mit der VL53L0X Pololu Bibliothek (1.3.0) zum laufen zu bringen.
          Ich habe dann die SetID Funktion aus der Adafruit Bibliothek übernommen und vor und nach der Initialisierung einen I2C Scan gemacht um die Adressen zu kontrollieren.

          Als alles funktionierte, habe ich den I2C Scan rausgenommen und promt ließ sich einer der beiden Sensoren nicht mehr Initialisieren.
          Mit der Funktion Wire.setClock(100000) nach Wire.begin ging es dann plötzlich wieder.
          Vielleicht hilft dir das ja weiter.

          Gruß
          Robert

  13. Doch noch mal eine Frage …
    Vielleicht muss ich mit dem SPAD Array experimentieren, damit das Ganze für meinen Anwendungsfall funktioniert. Scheinbar geht das nur mit der original API oder der Bibliothek von SparkFun. Mit welchem VL53L1X Sensor hast Du die SparkFun lib ausprobieren können?

    Danke Peter

    1. Die Sparkfun Bibliothek hat mit den oben abgebildeten Sensoren funktioniert, also Pimoroni und Melopero. Das mit den Spads hat auch funktioniert, aber das habe ich mit jedem Modul ausprobiert. Ich gehe davon aus, dass das nicht modulabhängig ist.

      1. Verrückte Sache:
        1) Libraries von Github (SparkFun_VL53L1X_Arduino_Library, 1.2.9)
        Wire oder auch I2C Scanner findet den Sensor, die SparkFun Routine begin() schlägt fehl. Auch ein Ändern der Adresse im Quellcode von Default 0x52 auf 0x29 führt nicht zum Erfolg.
        2) Libraries von PlatformIO (SparkFun VL53L1X 4m Laser Distance Sensor, 1.2.9)
        funktioniert – die andere I2C Adresse interessiert scheinbar nicht

  14. Wie hoch ist der tatsächliche, ggf. genau bestimmte, Energiebedarf? Wichtig für stand alone IoT solar Anwendungen iV mit LoRaWAN Datenübertragung?

    Hat das mal wer bestimmt?

    Danke

    gerhard

    1. Ich habe es nicht nachgemessen, aber der Strombedarf hängt auch davon ab, wieviel man wirklich misst und welche Parameter man einstellt. In den Datenblättern steht ein bisschen was dazu. Für beide Module gilt, dass sie im Standby Modus wenige Mikroampere verbrauchen. Für den aktiven Zustand werden in den Datenblättern Beispiele genannt, die um die 20 mA liegen. Aber man muss ja für die meisten Anwendungen nicht ständig messen.

      1. Danke.
        Ja das stimmt. Ich möchte eine Präsenzdetektion durchführen, die nicht zeitkritisch ist und daher nur wenige Male tägliche durchgeführt werden wird.

        Dieses Modul werde ich mir mal genauer ansehen.

        Ps: Schöne Schreibe!

  15. Hallo,

    ich benötige einen Laser Entfernungsmesser mit dem man kleine Entfernungen messen kann.
    Die Entfernung beträgt max. 30 mm.
    Der Sensor sollte eine hohe Messgenauigkeit bieten. Am besten wenn dieser sogar im 0,5 mm Bereich messen könnte. Gibt es überhaupt einen solchen Sensor?

    1. Am ehesten ginge wohl noch der VL6180x mit knapp 20 cm Reichweite. 0,5 mm könnte damit vielleict gehen. Bestimmt gibt es solche Sensoren, aber wahrscheinlich nicht im Arduino/Hobby/Consumer Bereich.

    2. Fertiger Sensor wird schwierig zu bekommen sein.
      Für sehr kleine Auflösungen, kann ein CD/DVD Lesekopf verbastelt werden, sogar als Rastermikroskop im µm Bereich. Es stand mal auf der RAPP Instruments Seite. Seitdem es bei Franzis das Buch gibt, Steht es nicht mehr im web.
      Wenn es nicht unbedingt Laser sein muss, für Bereiche bis 1cm, werden in der Industrei gerne kapazitive, induktive oder tastende Sensoren benutzt.
      Ein tastender Sensor wäre z.B. der BL-Touch aus dem 3D Druck.

  16. Hallo Danke für den Beitrag, aber bei mir ist das alles sehr ungenau. Gibt es eine art der Kalibrierung? Denn ich habe auf Din A4 länge gemessen, aber angezeigt wird mir 333. Müsste aber 24. Hat jemand eine Idee? Ich habe auch 2 verschiedene laser Probiert. Immer selbe ergebnis.

    1. Erst nochmal ein paar Rückfragen:
      1) Welchen der beiden Sensoren benutzt du?
      2) 333 statt 24? Das wäre ja nicht ungenau, sondern komplett daneben. mm?
      3) Was misst du für ein Objekt? Ist es vielleicht zu klein?
      4) Wenn du möchtest kannst du mir mal deinen Sketch zuschicken.

  17. Hallo liebe Tüftler,
    Ich habe eine etwas ungewöhnliche Anwendung für den VL53L0X:
    Ich brauche nicht den absoluten Abstand sondern letztlich von drei dieser Sensoren möglichst genau (< +/- 0,1mm) den Unterschied. Eine Messdauer zum Mitteln der Messwerte von etwa 8-15s wäre vertretbar.
    Temperaturdrift spielt also keine Rolle, da die Messung wie gesagt nicht absolut erfolgen muss und alle Sensoren gleichzeitig messen können.
    Das muss nicht mit einer Library gehen, zur Not auch drei microcontroller oder drei I2C-Channels – es geht also zunächst nur um die tatsächliche Auflösung der Messwerte.
    Ziel ist es mit drei Sensoren den Winkel eines geeignet reflektierenden Gegenstandes gegenüber den drei Sensoren möglichst genau zu erfassen.
    Kommt man irgendwie an die Sensorrohdaten anstatt auf mm gerundete Werte?
    Ich habe mir die Pololu- und Adafruit Library angeschaut aber durch diese API-Geschichte habe ich noch nicht gefunden wo ich das ggfs abgreifen könnte.
    Bisher messe ich ein paar tausend Messwerte in mm und bilde den Durchschnitt, jedoch geht hier durch die mir unbekannte Rundung auf mm eines jeden Einzel-Messwerts natürlich Genauigkeit flöten.
    Es ist schon klar dass das nicht viel ist, denn 3 Prozent auf z.b. 29mm (in etwa das Minimum) sind bereits 0,87mm (falls die 3 Prozent Toleranz überhaupt auf den jeweils gemessenen Abstand zu beziehen sind).
    Ich suche also nach einer Lösung die Rundung auf ganze mm zu umgehen.
    Gerne auch andere Sensoren vorschlagen.

    Details:
    benötigtes FoV: 1 Grad würde genügen
    Zielabstand: je Sensor fester Wert +/- 3mm, 2 Sensoren haben 50 +/-3 mm und einer 100 +/-3mm Abstand vom Target)
    Target ist immer das selbe Material
    Keine Helligkeitseinflüsse (bzw können unterbunden werden)
    Temperaturdrift nicht relevant
    Korrektheit des absoluten Abstandes nicht relevant
    Regelmäßige Kalibrierung der Sensoren zueinander auf Referenzfläche zulässig

    Hat jemand Tipps?

    1. Hallo,

      ich bin über diese API Lösung auch nicht besonders glücklich. Wie man da an die Rohdaten herausziehen kann, vermag ich leider nicht zu sagen. Im Bereich von mm genau zu messen wird aber sicherlich nicht einfach. Da braucht man auch geeignete Gegenstände. Am besten plan und groß. Viel mehr fällt mir leider nicht ein. Vielleicht hat ja jemand anderes noch eine Idee.

  18. Hallo,

    ich hätte eine Frage bzgl. VL53LX Tofs. Ich würde diese gerne mit dem Raspi benutzen. Die Pimoroni Lib VL53L1X für multiple I2Cs funktioniert leider nicht zuverlässig bzgl. der Messwerte. Ich habe es auch schon mit der Adafruit I2C Mux sowie den 8086 Mux versucht. Leider ohne Erfolg. Mein Problem ist, dass ich für den Rest meines Projektes schon alles in Python auf Raspi habe. Deshalb meine Frage, gibt es ToFs, die sich auf verschiedene I2C Adressen (hart) stellen lassen, die ähnliche oder gleiche Eigenschaften haben wie die VL53L1X ToF family. Ich benötige zuverlässige Messungen in der Nahdistanz (10-50 cm) die ich dann via Python / Raspi ansprechen bzw. auserten kann.
    Suche bisher leider vergeblich und wäre dankbar für jeden Tipp.

    1. Hi Peter, außer den VL53LX kenne ich nur noch den VL6180X, der nach dem TOF Prinzip funktioniert. Der hat allerdings nur eine Reichweite von 20cm. Muss es denn unbedingt ein TOF Sensor sein? Hinsichtlich der Genauigkeit habe ich mit den guten alten Ultraschallsensoren auch keine schlechten Erfahrungen gemacht.

      Andererseits verstehe ich aber auch nicht was das Problem bei zwei Sensoren sein soll. Sofern man es bewerkstelligen kann, beiden eine unterschiedliche Adresse zu geben, sollte man sie getrennt ansprechen können. Hat das denn funktioniert? Auch für Python gibt es I2C Adressscanner, damit solltest du das prüfen können. Und hast du Pullups in die I2C Leitungen eingebaut?

      1. Hi Ewald,

        Ultraschall habe ich schon probiert. Selbst die teuren Teil von PIBorg versagen leider kläglich wenn Hochglanz Metallfüßen :-(. Das Problem mit der VL531lx Lib von Pimoroni ist, dass es zwei funmktioniert, allerdings die Lib wohl nicht sauber arbeitet bzgl. der getrennten i2c-Busse. Ich bekomme manchmal auf beiden Tofs dieselben Werte oder eine mißt völligen Quatsch bei z.B. 40 cm 4 m usw. Pullups bringen auch nichts. Es gibt wohl eine experimentell VL531lx, die bekomme ich aber nicht zum Laufen (wobei ich hier wohl nicht der einzige bin). Die Experimental Version ist eine Github Fork und diese installiert sich wohl nicht richtig? Eine Nachfrage beim Autor ist seit Wochen leider unbeantwortet. Mit einem Arduino Uno läuft es einwandfrei, allerdings benutze ich einen PiBorg Motorcontroller und das ist alles Python. Ich habe schon überlegt den Ardunio mit dem Raspi zu koppeln, aber dann benötige noch eine weitere Stromquelle :-(, was auch nicht ideal ist. Ich überlege, ob ich die SDC/SDA Leitung per Relais physikalisch umschalten könnte, so dass aus Software-Sicht immer zum Zeitpunkt des messen, ein ToF aktiv ist wäre. Ich benötige nur 2, das ginge dann vielleicht.
        Trotzdem danke für deine Antwort.
        Schönen Sonntag

        1. Getrennt ansteuern ginge wohl auch. Ich würde dann aber einfach einen Transistor als Schalter nehmen. Ich hoffe du bekommst die Geschichte noch ans Laufen.

    1. Hallo, ich gehe davon aus, du beziehst dich auf den VL53L0X, denn soweit ich weiß, hat Adafruit keinen VL53L1X im Programm und keine Bibliothek dazu. Ich hatte versucht, in der VL53L0X Bibliothek die Interruptfunktion zu finden, leider vergeblich. Entweder ist die Funktion gut versteckt oder nicht implementiert. Ich hätte schon längst selber eine Bibliothek geschrieben, aber der Zugang zu dem VL53L0X über die API, also nicht wie gewohnt über direkten Registerzugriff, ist recht gewöhnungsbedürftig. Abgesehen vom Preis würde ich immer zum VL53L1X greifen und die sehr komfortable Sparkfun Bibliothek benutzen.

  19. Hi Wolfgang,
    vielen Dank für diesen und auch die anderen Beiträge.
    Ich teste gerade den L0 und L1 Sensor.
    Der L0 funktioniert recht gut mit den verschiedenen Libraries (Adafruit, Pololu), wenn auch mit einer kleinen Unlinearität.
    Der L1 macht „Probleme“ – er misst nur Mist. Bis 50 cm mit einem ordentlichen Offset und darüber gar nicht mehr. Egal mit welcher Library (SF, Pololu) und welchem Beispielprogramm (SF, Pololu, Wolles). Der Messaufbau und Randparameter sind dieselben wie beim Test des L0.
    Irgend eine Idee?
    Grüße,
    Rally

    1. Hi Rally, auf die Entfernung schwer zu sagen. Ich denke mal laut vor mich hin: da du ja den L0 zum Laufen bekommen hast, sollte bei der Schaltung alles stimmen. Hast du Pullup Widerstände für die I2C Leitungen verwendet? Ich hatte ja geschrieben ich brauchte keine. Als ich gestern wegen einer anderen Anfrage nochmal probiert hatte, brauchte ich dann doch welche. Allerdings würde ich dann eher erwarten, dass gar nichts geht. Welchen L1 benutzt du? Vielleicht kannst du mir den Link zur Bezugsquelle schicken, dann könnte ich nochmal schauen, ob mir da etwas auffällt.

      1. Hi Wolfgang,

        es ist ein original Pololu, bestellt via großem Internet-Händler. Also eher unauffällig.
        Habe es an einem nackigen Uno getestet ohne Pullups, sollte aber wie gesagt zu Busfehlern führen und nicht zu Messfehlern. Hatte verschiedene Lichtverhältnisse und mit und ohne Interrupt getestet. Werd es trotzdem nochmals mit Widerständen versuchen und berichten.

        1. …die Lösung war einfach, wenn man lesen kann:
          „Are you getting weird readings? Be sure the vacuum tape has been removed from the sensor.“ steht als Kommentar im Header der Sparkfun Beispiele.
          Kaum so getan funktioniert es 🙂

  20. Ich habe einen CJMCU 402 mit dem VL53LOX erworben, der offenbar chinesischer Produktion ist. Der I2C Scanner zeigt die Adresse 0x4C und nicht 0x29. Die angeführten Bibliotheken gehen damit nicht. Was kann man da tun? Ich habe keine große Ahnung von der Programmierung.

    1. Hallo Christian, ich musste ein bisschen „wühlen“ um die Antwort zu finden. Ich gehe davon aus, dass du die die Pololu Bibliothek verwendest. Dann kannst du die Adresse leider nicht im Sketch einstellen, sondern nur in der Bibliothek. Das ist wirklich unschön, normalerweise sollte man so etwas von außen einstellen können. Aber keine Sorge, es ist nicht schwer: 1) Gehe in das libraries Verzeichnis und dort in das Verzeichnis VL53L0X. 2) Öffne die Datei VL53L0X.cpp mit einem Texteditor (z.B. notepad++). 3) In Zeile 13 (jedenfalls ist es in meiner Version Zeile 13) findest du den Eintrag:

      #define ADDRESS_DEFAULT 0b0101001

      4) Ersetze sie durch

      #define ADDRESS_DEFAULT 0x4C

      Speichere die Datei. Dann sollte es gehen. Eine Rückmeldung ob es geklappt hat würde mich freuen.

      1. Hallo Wolfgang, leider hat es nicht geklappt. Ich bekomme immer noch die Fehlermeldung in dem Sketch Single von Pololu

        Failed to detect and initialize sensor!

        Habe das auch noch mal mit dem I2C Scanner überprüft und der liefert die Antwort 0x4C, also müsste der Sensor ansprechbar sein. Auf dem deutschen Markt gibt es fast nur noch den CJMCU 402, aber man findet nirgends eine brauchbare Beschreibung. Der Sensor ist auch nicht beschriftet, nur das Breakout Board.

        1. Ich war der Meinung du hättest einen VL53L0X und war ganz darauf fixiert dafür die Anpassung der I2C-Adresse zu finden. Jetzt habe ich aber nochmal nach dem CJMCU-402 geschaut. Der hat anscheinend überhaupt nichts mit dem VL53L0X zu tun außer dem Messprinzip. Nach einer kleinen Recherche bin ich auf diese Bibliothek gestoßen:
          https://github.com/sparkfun/SparkFun_RFD77402_Arduino_Library
          Sie könnte mit deinem Modul funktionieren. Zumindest stimmt auch schon mal die I2C Adresse.

          1. Lieber Wolfgang,
            das ist ja großartig, wie Du das herausgefunden hast, so schnell, und ich habe schon tagelang daran gewurzelt. Da ich keinerlei Beschreibung gefunden hatte und auch nicht wusste, dass es zu dem VL53L0X noch eine Alternative gibt und auch keine Beschriftung auf dem Chip ist. Das ist das Ergebnis des Beispiels BasicReadings
            distance: 1098mm
            distance: 1085mm
            distance: 1079mm
            distance: 1075mm
            distance: 1093mm
            distance: 1088mm
            Der Chip geht auch bis zwei Meter.
            Gaaanz großen Dank!!!
            Bitte publiziere das auch entsprechend, dass nicht noch mehr Leute auf dem Schlauch stehen.

      2. Hallo Wolfgang,

        sehr schöne Erläuterungen…
        Ich habe ein ähnliches Problem. Mit einem I2C Scanner wird mein VL53L1X unter 0x29 gefunden.
        Sowohl die Pololu lib als auch die SparkFun lib lassen das Setzen einer Adresse zu (Pololu = setAddress()).
        ich habe also mit
        Wire.begin();
        sensor.setAddress(I2C); // I2C = 29

        mein Glück versucht. Leider wird er nicht erkannt.
        Idee?

        1. Zunächst schreibst du 0x29, weiter unten I2C = 29. Hast du vielleicht einfach vergessen, die I2C Adresse als Hexadezimal anzugeben oder in Dezimal umzurechnen (0x29 = 41)? Es wäre schon komisch, wenn beide Bibliotheken einen Fehler hätten.

          1. Oops!

            Super Danke! War etwas durcheinander, weil „0b0101001“ = 29. Bekomme jetzt Timeout vom Sensor, aber immerhin wird er schon mal erkannt.

            Danke noch mal!
            Peter

          2. Ja, seltsam. Habe jetzt gelesen, dass der VL53L1X eine hard coded I2C HEX-Adresse 0x29 hat. Jetzt wird er auch im default modus erkannt. Brauchte wohl einen kleinen „Anstubser“.
            Leider bekommen ich als Messergebnis immer nur 0. Habe schon verschiedene Libs und Lib-Versionen getestet (Pololu, SparkFun, QTRobot).
            Auch der Tausch (habe zufällig noch einen zweites breakout eines anderen Herstellers) führte zu nichts … Messwerte = 0.
            Wo könnte ich noch dran „schrauben“, um dem Problem auf die Spur zu kommen.

            Gruß Peter

            1. Hast du denn mal einfach die unveränderten Beispielsketche der Bibliotheken verwendet? Die sollten auf jeden Fall funktionieren.

              Und ja, die Standardadresse ist 0x29. Man kann per Software eine andere Adresse einstellen, die wird aber vergessen wenn man die Stromversorgung trennt. Wenn man zwei Sensoren hat, kann man einen über xshut ausknippsen, bei dem anderen stellt man die neue Adresse ein, schaltet dann den zweiten ein und hat so beide mit unterschiedlichen Adressen ansteuern.

              1. Ich verwende die Sensoren nicht parallel. Zufälligerweise habe ich zwei verschiedene zum Testen (QCRobot und Pimoroni). Erst habe ich den ersten getestet. Nachdem da nichts passierte, habe ich den zweiten ausprobiert. Der erste könnte ja defekt sein. Beide werden jeweils am I2C-Bus erkannt. Ja, ich verwende natürlich erst mal die Beispiel-Sketche. Aber egal welche, die Werte sind immer 0. Dumme Frage: sollte da nicht irgendwas leuchten? Ich meine im Netz mal ein Foto gesehen zu haben…

                Danke für Deine Geduld – Peter

                1. Wirklich merkwürdig. Ich habe gerade nochmal 2 Module mit dem unveränderten Sparkfun Beispielsketch Example1_ReadDistance laufen lassen und alles funktioniert. Leuchten tun meine Module übrigens auch nicht. Wenn man den Sketch nicht verändert, dann kan man eigentlich nichts verkehrt machen.

                  1. bin am Ende meines Lateins. Habe mir gerade ein original Pololu-Breakout bestellt….
                    In Arbeit hatte ich jetzt das VL53L1X-Breakouts von Pimoroni und cqrobot. SparkFun lib schlägt komplett fehl. Es sei denn, man ändert das setup von xxx.begin() auf xxx.init(), wie SparkFun es in seinem eigene guide vorsieht. Danach passiert allerdings nichts mehr.
                    Die anderen libs von Pololu, cqrobot, oder auch die original api von STM scheinen zu laufen, liefern aber Werte 0. Verzichte ich auf Messungen und frage nur Chip-Infos ab (ID, etc.) kommt ebenfalls 0.
                    Ich verwende allerdings keinen Arduino, sondern ein Feather M0 RF69HCW 433 MHz board. Daran kann es eigentlich nicht liegen. Mit dem board habe ich schon diversen Sensoren über I2C betrieben.
                    Ich bin mal gespannt, wie das Ergebnis mit dem original Pololu board aussieht.

                    Danke nochmal für Deine Hilfe.

                  2. Fehler gefunden!
                    Ich nutze boards in Batteriebetrieb unter Verwendung von deep sleep modi. Dazu versorge ich die Sensoren über das Hochschalten einzelner „Daten Pins“. Der VL53L1X braucht für den Betrieb laut Doku 20mA, je nach Konfiguration bis zu 40 mA. Die Datenpins meines boards sind auf 10mA begrenzt.

  21. Vielen Dank für diese sehr umfassende und vor allem lesbare und verständliche Zusammenfassung.

  22. Shouldn’t line 24 be:
    attachInterrupt ( digitalPinToInterrupt ( INTERRUPT_PIN ) , blink, FALLING )

    1. Hi J.S., I can’t see the difference to what I have written!? Maybe it’s too late in the evening for me 🙂

      1. Hallo Wolfgang
        Mit interesse habe ich Deine Beträge gelesen. Leider kann ich mit Arduino nicht umgehen, ich programmiere mit Bascom.
        Da ich den VL53L0X gerne einsetzen würde stelle ich mir vor eine Software für Arduino zu laden zu compilieren und an den Sensor über eine UNO Board zu senden. Einstellung der Parameter nur in der Software.
        Kannst Du da eine Lösung anbieten, für nicht Arduino Profis?
        Vielen Dank
        Mit freundlichem Gruß
        Dieter Brusch

        1. Hallo Dieter,

          Mit Bascom kenne ich mich wiederum nicht aus. Ich kann nur mit Arduino/C++ weiterhelfen. Du schreibst, du willst die Software an den Sensor schicken? Der Sensor kann kein Programm speichern. Man kann lediglich seine Register einstellen und auslesen. Und das machen ja die Beispielprgramme, die ich hier vorgestellt habe. Oder habe ich dich irgendwie falsch verstanden?

          VG, Wolfgang

          1. Hallo Wolfgang
            Vielen Dank für Deine Mühe. Ich hoffte auf diesem Weg ein passendes Programm zu bekommen.
            Die Lib. habe ich mir bereits geladen, ich bekomme nur das Einrichten der IDE nicht so richtig hin.
            Ich habe mich auf der VHS für Arduino angemeldet, und schreibe mir das Prog. dann selber.
            Mit freundlichem Gruß
            Dieter

Schreibe einen Kommentar

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