I’ve been using VL53L5CX for a couple of weeks now in my office but once I moved to install on site I discovered that beyond about 2500mm the VL53L5CX does not provide consistent or reliable measurements. Around 3000mm the ranges that are returned vary wildly by about 300-500mm. Ranges less than 2500mm are consistent to within 10mm.
I have about a 10’ ceiling where the sensor is installed, pointing directly down at a concrete floor. In my code if I ignore results beyond 2500mm I can pretty reliably track a person as they walk through the 8x8 grid.
However, because the range is limited it cannot track a person as the enter the edge of the grid.
The sensor advertises a 4000mm range, but I’ve yet to see a measurement higher than about 3300mm.
I have also noticed (which another forum post mentions) the VL53L5CX will return 0 or the last known read when out of range. I am able to easily filter this out by ignoring any value that is the same on consecutive reads.
For context, my code (below) checks for changes in each quadrant and treats it like a coordinate grid. As a person walks closer to 0x0 (where the moon is located) the moon will increase in brightness (moon code not included).
I have read the documentation for the sensor. I don’t see anything in the docs about increasing the range to 4000mm.
#include <Wire.h>
#include <SparkFun_VL53L5CX_Library.h> //http://librarymanager/All#SparkFun_VL53L5CX
SparkFun_VL53L5CX myImager;
VL53L5CX_ResultsData measurementData; // Result data class structure, 1356 byes of RAM
int imageResolution = 0; // Used to pretty print output
int imageWidth = 0; // Used to pretty print output
long measurements = 0; // Used to calculate actual output rate
long measurementStartTime = 0; // Used to calculate actual output rate
int lastMeasureArray[64];
int ignoreStatic[64];
float distanceToMoon = 30;
void setup()
{
Serial.begin(115200);
delay(1000);
Serial.println("SparkFun VL53L5CX Imager Example");
Wire.begin(); // This resets I2C bus to 100kHz
Wire.setClock(200000); //Sensor has max I2C freq of 1MHz
//myImager.setWireMaxPacketSize(32); // Increase default from 32 bytes to 128 - not supported on all platforms
Serial.println("Initializing sensor board. This can take up to 10s. Please wait.");
if (myImager.begin() == false)
{
Serial.println(F("Sensor not found - check your wiring. Freezing"));
while (1)
;
}
myImager.setResolution(8 * 8); // Enable all 64 pads
// I have not tested these configurations yet:
//myImager.setRangingMode(SF_VL53L5CX_RANGING_MODE.CONTINUOUS);
//myImager.setSharpenerPercent(20);
//myImager.setTargetOrder(SF_VL53L5CX_TARGET_ORDER.CLOSEST);
imageResolution = myImager.getResolution(); // Query sensor for current resolution - either 4x4 or 8x8
imageWidth = sqrt(imageResolution); // Calculate printing width
// Using 4x4, min frequency is 1Hz and max is 60Hz
// Using 8x8, min frequency is 1Hz and max is 15Hz
myImager.setRangingFrequency(1);
myImager.startRanging();
measurementStartTime = millis();
}
void loop()
{
// Poll sensor for new data
if (myImager.isDataReady() == true)
{
if (myImager.getRangingData(&measurementData)) // Read distance data into array
{
float newDistanceToMoon = 30;
// The ST library returns the data transposed from zone mapping shown in datasheet
// Pretty-print data with increasing y, decreasing x to reflect reality
for (int y = 0; y < imageWidth; y++)
{
for (int x = 0; x < imageWidth; x++)
{
int arrayIndex = x + (y * imageWidth);
float distanceMm = measurementData.distance_mm[arrayIndex];
float change = abs(lastMeasureArray[arrayIndex] - distanceMm);
float changePercent = change / distanceMm * 100; // unused
//Serial.println(change);
if(change > 10) { // this seems to effectively filter out errant reads
if( ignoreStatic[arrayIndex] > 0) {
if(distanceMm < 4000 && distanceMm > 600) {
Serial.print(distanceMm);
int xscale = x * 3; // arbitrary increase in scale makes variation easier to sus out
int yscale = y * 3;
float dist = sqrt((sq(xscale) + sq(yscale))); // moon is at 00
newDistanceToMoon = min(newDistanceToMoon,dist);
} else {
Serial.print("[ ]");
}
} else {
ignoreStatic[arrayIndex] = ignoreStatic[arrayIndex] + 1;
Serial.print("[ ]");
}
} else {
if(ignoreStatic[arrayIndex] > 0) {
ignoreStatic[arrayIndex] = ignoreStatic[arrayIndex] - 1;
}
Serial.print("[ ]");
}
Serial.print("\t");
lastMeasureArray[arrayIndex] = distanceMm;
}
Serial.println();
}
//Serial.println();
if(newDistanceToMoon > distanceToMoon) { // moving away
distanceToMoon += (newDistanceToMoon - distanceToMoon) * .1;
} else { // moving close
distanceToMoon += (newDistanceToMoon - distanceToMoon) * .4;
}
distanceToMoon = constrain(distanceToMoon,0,30);
for(int b = 0; b <= distanceToMoon; b++) {
//Serial.print("█ ");
}
//Serial.print(distanceToMoon);
// Serial.println();
Serial.println();
//Uncomment to display actual measurement rate
// measurements++;
// float measurementTime = (millis() - measurementStartTime) / 1000.0;
// Serial.print("rate: ");
// Serial.print(measurements / measurementTime, 3);
// Serial.println("Hz");
}
}
delay(5); // Small delay between polling
}