cancel
Showing results for 
Search instead for 
Did you mean: 

VL53L4CD can't measure distances below 70mm when interfaced with ESP32-S3?

Nithinkr
Associate

I've interfaced the VL53L4CD with ESP32-S3, but I'm unable to get accurate ranging values below 70mm.

I'm using the ESP32-S3 with Arduino IDE.

How can I resolve this issue ?

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

#define SDA_PIN 8
#define SCL_PIN 9

VL53L4CD sensor(&Wire, -1); // -1 = XSHUT not used

void setup() {
 Serial.begin(115200);
 delay(1000);

 Wire.begin(SDA_PIN, SCL_PIN);
 Wire.setClock(400000);

 Serial.println("VL53L4CD Init...");

 if (sensor.begin() != 0) {
  Serial.println("VL53L4CD not detected");
  while (1);
 }

 Serial.println("VL53L4CD detected");

 sensor.VL53L4CD_SetRangeTiming(50, 0); // 50ms timing
 sensor.VL53L4CD_StartRanging();
}

void loop() {
 uint8_t dataReady = 0;
 VL53L4CD_Result_t results;

 sensor.VL53L4CD_CheckForDataReady(&dataReady);

 if (dataReady) {
  sensor.VL53L4CD_GetResult(&results);
  sensor.VL53L4CD_ClearInterrupt();

  Serial.print("Distance: ");
  Serial.print(results.distance_mm);
  Serial.println(" mm");
 }

 delay(20);
}

Edited to apply source code formatting - please see How to insert source code for future reference.

1 ACCEPTED SOLUTION

Accepted Solutions

Hi sir, I have already resolved the issue. Please use the test code below,  you can measure below 70mm using VLl53L4CD ToF SENSOR

Actually ,this example code from ST Electronics

/* Includes ------------------------------------------------------------------*/
#include <Arduino.h>
#include <Wire.h>
#include <vl53l4cd_class.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <stdlib.h>

#define DEV_I2C Wire
#define SerialPort Serial

#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif
#define LedPin LED_BUILTIN

/* Please uncomment the line below if you want also to use the satellites */
//#define SATELLITES_MOUNTED

#define XSHUT_TOP 3

#ifdef SATELLITES_MOUNTED
#define XSHUT_LEFT 6
#define XSHUT_RIGHT 4
#endif

// Components.
VL53L4CD sensor_vl53l4cd_top(&DEV_I2C, XSHUT_TOP);
#ifdef SATELLITES_MOUNTED
VL53L4CD sensor_vl53l4cd_left(&DEV_I2C, XSHUT_LEFT);
VL53L4CD sensor_vl53l4cd_right(&DEV_I2C, XSHUT_RIGHT);
#endif

/* Setup ---------------------------------------------------------------------*/

void setup()
{
// Led.
pinMode(LedPin, OUTPUT);

// Initialize serial for output.
SerialPort.begin(115200);
SerialPort.println("Starting...");

// Initialize I2C bus.
DEV_I2C.begin();

// Configure VL53L4CD top component.
sensor_vl53l4cd_top.begin();

// Switch off VL53L4CD top component.
sensor_vl53l4cd_top.VL53L4CD_Off();

#ifdef SATELLITES_MOUNTED
// Configure (if present) VL53L4CD left component.
sensor_vl53l4cd_left.begin();

//Switch off (if present) VL53L4CD left component.
sensor_vl53l4cd_left.VL53L4CD_Off();

// Configure (if present) VL53L4CD right component.
sensor_vl53l4cd_right.begin();

// Switch off (if present) VL53L4CD right component.
sensor_vl53l4cd_right.VL53L4CD_Off();
#endif

//Initialize all the sensors
sensor_vl53l4cd_top.InitSensor(0x10);
#ifdef SATELLITES_MOUNTED
sensor_vl53l4cd_left.InitSensor(0x12);
sensor_vl53l4cd_right.InitSensor(0x14);
#endif

// Start Measurements
sensor_vl53l4cd_top.VL53L4CD_SetRangeTiming(200, 0);
sensor_vl53l4cd_top.VL53L4CD_StartRanging();
#ifdef SATELLITES_MOUNTED
sensor_vl53l4cd_left.VL53L4CD_SetRangeTiming(200, 0);
sensor_vl53l4cd_left.VL53L4CD_StartRanging();
sensor_vl53l4cd_right.VL53L4CD_SetRangeTiming(200, 0);
sensor_vl53l4cd_right.VL53L4CD_StartRanging();
#endif
}

void loop()
{
VL53L4CD_Result_t results;
uint8_t NewDataReady = 0;
char report[128];
uint8_t status;

do {
status = sensor_vl53l4cd_top.VL53L4CD_CheckForDataReady(&NewDataReady);
} while (!NewDataReady);

//Led on
digitalWrite(LedPin, HIGH);

if ((!status) && (NewDataReady != 0)) {
// (Mandatory) Clear HW interrupt to restart measurements
sensor_vl53l4cd_top.VL53L4CD_ClearInterrupt();

// Read measured distance. RangeStatus = 0 means valid data
sensor_vl53l4cd_top.VL53L4CD_GetResult(&results);
snprintf(report, sizeof(report), "VL53L4CD Top: Status = %3u, Distance = %5u mm, Signal = %6u kcps/spad\r\n",
results.range_status,
results.distance_mm,
results.signal_per_spad_kcps);
SerialPort.print(report);
}

digitalWrite(LedPin, LOW);

#ifdef SATELLITES_MOUNTED
NewDataReady = 0;

do {
status = sensor_vl53l4cd_left.VL53L4CD_CheckForDataReady(&NewDataReady);
} while (!NewDataReady);

//Led on
digitalWrite(LedPin, HIGH);

if ((!status) && (NewDataReady != 0)) {
// (Mandatory) Clear HW interrupt to restart measurements
sensor_vl53l4cd_left.VL53L4CD_ClearInterrupt();

// Read measured distance. RangeStatus = 0 means valid data
sensor_vl53l4cd_left.VL53L4CD_GetResult(&results);
snprintf(report, sizeof(report), "VL53L4CD Left: Status = %3u, Distance = %5u mm, Signal = %6u kcps/spad\r\n",
results.range_status,
results.distance_mm,
results.signal_per_spad_kcps);
SerialPort.print(report);
}

digitalWrite(LedPin, LOW);

NewDataReady = 0;

do {
status = sensor_vl53l4cd_right.VL53L4CD_CheckForDataReady(&NewDataReady);
} while (!NewDataReady);

//Led on
digitalWrite(LedPin, HIGH);

if ((!status) && (NewDataReady != 0)) {
// (Mandatory) Clear HW interrupt to restart measurements
sensor_vl53l4cd_right.VL53L4CD_ClearInterrupt();

// Read measured distance. RangeStatus = 0 means valid data
sensor_vl53l4cd_right.VL53L4CD_GetResult(&results);
snprintf(report, sizeof(report), "VL53L4CD Right: Status = %3u, Distance = %5u mm, Signal = %6u kcps/spad\r\n",
results.range_status,
results.distance_mm,
results.signal_per_spad_kcps);
SerialPort.print(report);
}

digitalWrite(LedPin, LOW);
#endif
}

View solution in original post

5 REPLIES 5
Zhiyuan.Han
ST Employee

Hi 

 

From your code, seems you didn't initialize the device correctly, 

Tey to add sensor.VL53L4CD_SensorInit();

Before

 sensor.VL53L4CD_SetRangeTiming(50, 0); // 50ms timing
 sensor.VL53L4CD_StartRanging()

 

Br

Zhiyuan.Han

 


In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
CRV31
Associate

Hi,

I'm encountering the same problem of @Nithinkr  (measure limited to 70mm ?!!) and i'm working on arduino IDE with https://github.com/stm32duino/VL53L4CD Library. 

Please find attach my init code and library default registers value (Except the API is there a documentation about registers ? :( 

Is there a way to solve this issue ? 

Thank you for your help.

 

  this->sensorOpt.begin();
  this->sensorOpt.InitSensor();

  uint8_t st = this->sensorOpt.VL53L4CD_SetRangeTiming(50, 0);
  if (st) { snprintf(report, sizeof(report), "SetRangeTiming failed (%u)\r\n", st); this->pDebugManagerRef->print(report); return; }
  this->pDebugManagerRef->print("SetRangeTiming 50ms of budget and 0ms of inter\r\n");

  this->sensorOpt.VL53L4CD_StartRanging();
  this->pDebugManagerRef->print("VL53L5CX OK\r\n")

 

static const uint8_t VL53L4CD_DEFAULT_CONFIGURATION[] = {
  0x12, /* 0x2d : set bit 2 and 5 to 1 for fast plus mode (1MHz I2C),
   else don't touch */
  0x00, /* 0x2e : bit 0 if I2C pulled up at 1.8V, else set bit 0 to 1
   (pull up at AVDD) */
  0x00, /* 0x2f : bit 0 if GPIO pulled up at 1.8V, else set bit 0 to 1
  (pull up at AVDD) */
  0x11, /* 0x30 : set bit 4 to 0 for active high interrupt and 1 for active low
  (bits 3:0 must be 0x1), use SetInterruptPolarity() */
  0x02, /* 0x31 : bit 1 = interrupt depending on the polarity,
  use CheckForDataReady() */
  0x00, /* 0x32 : not user-modifiable */
  0x02, /* 0x33 : not user-modifiable */
  0x08, /* 0x34 : not user-modifiable */
  0x00, /* 0x35 : not user-modifiable */
  0x08, /* 0x36 : not user-modifiable */
  0x10, /* 0x37 : not user-modifiable */
  0x01, /* 0x38 : not user-modifiable */
  0x01, /* 0x39 : not user-modifiable */
  0x00, /* 0x3a : not user-modifiable */
  0x00, /* 0x3b : not user-modifiable */
  0x00, /* 0x3c : not user-modifiable */
  0x00, /* 0x3d : not user-modifiable */
  0xff, /* 0x3e : not user-modifiable */
  0x00, /* 0x3f : not user-modifiable */
  0x0F, /* 0x40 : not user-modifiable */
  0x00, /* 0x41 : not user-modifiable */
  0x00, /* 0x42 : not user-modifiable */
  0x00, /* 0x43 : not user-modifiable */
  0x00, /* 0x44 : not user-modifiable */
  0x00, /* 0x45 : not user-modifiable */
  0x20, /* 0x46 : interrupt configuration 0->level low detection, 1-> level high,
  2-> Out of window, 3->In window, 0x20-> New sample ready , TBC */
  0x0b, /* 0x47 : not user-modifiable */
  0x00, /* 0x48 : not user-modifiable */
  0x00, /* 0x49 : not user-modifiable */
  0x02, /* 0x4a : not user-modifiable */
  0x14, /* 0x4b : not user-modifiable */
  0x21, /* 0x4c : not user-modifiable */
  0x00, /* 0x4d : not user-modifiable */
  0x00, /* 0x4e : not user-modifiable */
  0x05, /* 0x4f : not user-modifiable */
  0x00, /* 0x50 : not user-modifiable */
  0x00, /* 0x51 : not user-modifiable */
  0x00, /* 0x52 : not user-modifiable */
  0x00, /* 0x53 : not user-modifiable */
  0xc8, /* 0x54 : not user-modifiable */
  0x00, /* 0x55 : not user-modifiable */
  0x00, /* 0x56 : not user-modifiable */
  0x38, /* 0x57 : not user-modifiable */
  0xff, /* 0x58 : not user-modifiable */
  0x01, /* 0x59 : not user-modifiable */
  0x00, /* 0x5a : not user-modifiable */
  0x08, /* 0x5b : not user-modifiable */
  0x00, /* 0x5c : not user-modifiable */
  0x00, /* 0x5d : not user-modifiable */
  0x01, /* 0x5e : not user-modifiable */
  0xcc, /* 0x5f : not user-modifiable */
  0x07, /* 0x60 : not user-modifiable */
  0x01, /* 0x61 : not user-modifiable */
  0xf1, /* 0x62 : not user-modifiable */
  0x05, /* 0x63 : not user-modifiable */
  0x00, /* 0x64 : Sigma threshold MSB (mm in 14.2 format for MSB+LSB),
   use SetSigmaThreshold(), default value 90 mm  */
  0xa0, /* 0x65 : Sigma threshold LSB */
  0x00, /* 0x66 : Min count Rate MSB (MCPS in 9.7 format for MSB+LSB),
   use SetSignalThreshold() */
  0x80, /* 0x67 : Min count Rate LSB */
  0x08, /* 0x68 : not user-modifiable */
  0x38, /* 0x69 : not user-modifiable */
  0x00, /* 0x6a : not user-modifiable */
  0x00, /* 0x6b : not user-modifiable */
  0x00, /* 0x6c : Intermeasurement period MSB, 32 bits register,
   use SetIntermeasurementInMs() */
  0x00, /* 0x6d : Intermeasurement period */
  0x0f, /* 0x6e : Intermeasurement period */
  0x89, /* 0x6f : Intermeasurement period LSB */
  0x00, /* 0x70 : not user-modifiable */
  0x00, /* 0x71 : not user-modifiable */
  0x00, /* 0x72 : distance threshold high MSB (in mm, MSB+LSB),
   use SetD:tanceThreshold() */
  0x00, /* 0x73 : distance threshold high LSB */
  0x00, /* 0x74 : distance threshold low MSB ( in mm, MSB+LSB),
   use SetD:tanceThreshold() */
  0x00, /* 0x75 : distance threshold low LSB */
  0x00, /* 0x76 : not user-modifiable */
  0x01, /* 0x77 : not user-modifiable */
  0x07, /* 0x78 : not user-modifiable */
  0x05, /* 0x79 : not user-modifiable */
  0x06, /* 0x7a : not user-modifiable */
  0x06, /* 0x7b : not user-modifiable */
  0x00, /* 0x7c : not user-modifiable */
  0x00, /* 0x7d : not user-modifiable */
  0x02, /* 0x7e : not user-modifiable */
  0xc7, /* 0x7f : not user-modifiable */
  0xff, /* 0x80 : not user-modifiable */
  0x9B, /* 0x81 : not user-modifiable */
  0x00, /* 0x82 : not user-modifiable */
  0x00, /* 0x83 : not user-modifiable */
  0x00, /* 0x84 : not user-modifiable */
  0x01, /* 0x85 : not user-modifiable */
  0x00, /* 0x86 : clear interrupt, use ClearInterrupt() */
  0x00  /* 0x87 : start ranging, use StartRanging() or StopRanging(),
   If you want an automatic start after VL53L4CD_init() call,
    put 0x40 in location 0x87 */
};

 

Darin WINTERTON
ST Employee

When you are streaming, can you read register 0x3F.  The driver writes this to a value of 0x00, but if this is reading a value of 8D, this would give a distance of 70mm when the target is below 70mm.  

If this is the case, before issuing a start command, write to register 0x3F a value of 0x00.  This should solve this issue.

Hi sir, I have already resolved the issue. Please use the test code below,  you can measure below 70mm using VLl53L4CD ToF SENSOR

Actually ,this example code from ST Electronics

/* Includes ------------------------------------------------------------------*/
#include <Arduino.h>
#include <Wire.h>
#include <vl53l4cd_class.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <stdlib.h>

#define DEV_I2C Wire
#define SerialPort Serial

#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif
#define LedPin LED_BUILTIN

/* Please uncomment the line below if you want also to use the satellites */
//#define SATELLITES_MOUNTED

#define XSHUT_TOP 3

#ifdef SATELLITES_MOUNTED
#define XSHUT_LEFT 6
#define XSHUT_RIGHT 4
#endif

// Components.
VL53L4CD sensor_vl53l4cd_top(&DEV_I2C, XSHUT_TOP);
#ifdef SATELLITES_MOUNTED
VL53L4CD sensor_vl53l4cd_left(&DEV_I2C, XSHUT_LEFT);
VL53L4CD sensor_vl53l4cd_right(&DEV_I2C, XSHUT_RIGHT);
#endif

/* Setup ---------------------------------------------------------------------*/

void setup()
{
// Led.
pinMode(LedPin, OUTPUT);

// Initialize serial for output.
SerialPort.begin(115200);
SerialPort.println("Starting...");

// Initialize I2C bus.
DEV_I2C.begin();

// Configure VL53L4CD top component.
sensor_vl53l4cd_top.begin();

// Switch off VL53L4CD top component.
sensor_vl53l4cd_top.VL53L4CD_Off();

#ifdef SATELLITES_MOUNTED
// Configure (if present) VL53L4CD left component.
sensor_vl53l4cd_left.begin();

//Switch off (if present) VL53L4CD left component.
sensor_vl53l4cd_left.VL53L4CD_Off();

// Configure (if present) VL53L4CD right component.
sensor_vl53l4cd_right.begin();

// Switch off (if present) VL53L4CD right component.
sensor_vl53l4cd_right.VL53L4CD_Off();
#endif

//Initialize all the sensors
sensor_vl53l4cd_top.InitSensor(0x10);
#ifdef SATELLITES_MOUNTED
sensor_vl53l4cd_left.InitSensor(0x12);
sensor_vl53l4cd_right.InitSensor(0x14);
#endif

// Start Measurements
sensor_vl53l4cd_top.VL53L4CD_SetRangeTiming(200, 0);
sensor_vl53l4cd_top.VL53L4CD_StartRanging();
#ifdef SATELLITES_MOUNTED
sensor_vl53l4cd_left.VL53L4CD_SetRangeTiming(200, 0);
sensor_vl53l4cd_left.VL53L4CD_StartRanging();
sensor_vl53l4cd_right.VL53L4CD_SetRangeTiming(200, 0);
sensor_vl53l4cd_right.VL53L4CD_StartRanging();
#endif
}

void loop()
{
VL53L4CD_Result_t results;
uint8_t NewDataReady = 0;
char report[128];
uint8_t status;

do {
status = sensor_vl53l4cd_top.VL53L4CD_CheckForDataReady(&NewDataReady);
} while (!NewDataReady);

//Led on
digitalWrite(LedPin, HIGH);

if ((!status) && (NewDataReady != 0)) {
// (Mandatory) Clear HW interrupt to restart measurements
sensor_vl53l4cd_top.VL53L4CD_ClearInterrupt();

// Read measured distance. RangeStatus = 0 means valid data
sensor_vl53l4cd_top.VL53L4CD_GetResult(&results);
snprintf(report, sizeof(report), "VL53L4CD Top: Status = %3u, Distance = %5u mm, Signal = %6u kcps/spad\r\n",
results.range_status,
results.distance_mm,
results.signal_per_spad_kcps);
SerialPort.print(report);
}

digitalWrite(LedPin, LOW);

#ifdef SATELLITES_MOUNTED
NewDataReady = 0;

do {
status = sensor_vl53l4cd_left.VL53L4CD_CheckForDataReady(&NewDataReady);
} while (!NewDataReady);

//Led on
digitalWrite(LedPin, HIGH);

if ((!status) && (NewDataReady != 0)) {
// (Mandatory) Clear HW interrupt to restart measurements
sensor_vl53l4cd_left.VL53L4CD_ClearInterrupt();

// Read measured distance. RangeStatus = 0 means valid data
sensor_vl53l4cd_left.VL53L4CD_GetResult(&results);
snprintf(report, sizeof(report), "VL53L4CD Left: Status = %3u, Distance = %5u mm, Signal = %6u kcps/spad\r\n",
results.range_status,
results.distance_mm,
results.signal_per_spad_kcps);
SerialPort.print(report);
}

digitalWrite(LedPin, LOW);

NewDataReady = 0;

do {
status = sensor_vl53l4cd_right.VL53L4CD_CheckForDataReady(&NewDataReady);
} while (!NewDataReady);

//Led on
digitalWrite(LedPin, HIGH);

if ((!status) && (NewDataReady != 0)) {
// (Mandatory) Clear HW interrupt to restart measurements
sensor_vl53l4cd_right.VL53L4CD_ClearInterrupt();

// Read measured distance. RangeStatus = 0 means valid data
sensor_vl53l4cd_right.VL53L4CD_GetResult(&results);
snprintf(report, sizeof(report), "VL53L4CD Right: Status = %3u, Distance = %5u mm, Signal = %6u kcps/spad\r\n",
results.range_status,
results.distance_mm,
results.signal_per_spad_kcps);
SerialPort.print(report);
}

digitalWrite(LedPin, LOW);
#endif
}

Hi @Nithinkr , @Darin WINTERTON , 

Many thanks for your help, by taking the code of @Nithinkr , i found my problem -> I was looping the measurements with xshut (VL53L4CD_Off() method), a delay and  without calling InitSensor each time (just doing VL53L4CD_On() and VL53L4CD_StartRanging()).

Too bad that xShut behaviour is not clearly described in datasheet about data persistence etc... but it's solved :)