cancel
Showing results for 
Search instead for 
Did you mean: 

How Can I get 8000mm ranging on the using the stmduino VL53L1 library?

gramcracker
Associate II

I'm using the library here: https://github.com/stm32duino/VL53L1, and it seems to stop measuring around 3.2-3.5 meters. I may be wrong, but think that means that it is not using the histogram? I set it to long distance ranging mode.

Here is my code:

bool Sensor::ConfigureSensor(TOF &tofSensor)
{
    Log.noticeln("Configuring [%s]", tofSensor.name);

    if (tofSensor.sensor_object == nullptr)
    {
        Log.fatal("No TOF sensor object initialized.");
        return false;
    }

    VL53L1_Error status;

    status = tofSensor.sensor_object->InitSensor(tofSensor.address);
    delay(10);
    if (status != VL53L1_ERROR_NONE)
    {
        Log.fatal("Failed to initialize %s. Status: %d. Halting.", tofSensor.name, status);
        while (1){;}
        return false;
    }

    Log.noticeln("%s address set to 0x%x", tofSensor.name, tofSensor.address);

    status = tofSensor.sensor_object->VL53L1_SetPresetMode(VL53L1_PRESETMODE_RANGING);
    delay(10);
    if (status != VL53L1_ERROR_NONE)
    {
        Log.errorln("Failed to set preset mode for %s", tofSensor.name);
        return false;
    }

    status = tofSensor.sensor_object->VL53L1_SetDistanceMode(VL53L1_DISTANCEMODE_LONG);
    delay(10);
    if (status != VL53L1_ERROR_NONE)
    {
        Log.errorln("Failed to set distance mode for %s", tofSensor.name);
        return false;
    }

    status = tofSensor.sensor_object->VL53L1_SetMeasurementTimingBudgetMicroSeconds(200000);
    delay(10);
    if (status != VL53L1_ERROR_NONE)
    {
        Log.errorln("Failed to set timing budget for %s", tofSensor.name);
        return false;
    }

    VL53L1_RoiConfig_t roiConfig;
    roiConfig.NumberOfRoi = 1;

    roiConfig.UserRois[0].TopLeftX = TL_X;
    roiConfig.UserRois[0].TopLeftY = TL_Y; 
    roiConfig.UserRois[0].BotRightX = BR_X;
    roiConfig.UserRois[0].BotRightY = BR_Y;
    
    status = tofSensor.sensor_object->VL53L1_SetROI(&roiConfig);
    delay(10);
    if (status != VL53L1_ERROR_NONE)
    {

        Log.errorln("Failed to set ROI for %s. Status: [%d]", tofSensor.name, status);

        return false;
    }

    status = tofSensor.sensor_object->VL53L1_StartMeasurement();
    delay(10);
    if (status != VL53L1_ERROR_NONE)
    {
        Log.errorln("Failed to start measurement for %s. Status: [%d]", tofSensor.name, status);  
        return false;
    }

    return true;
}
1 ACCEPTED SOLUTION

Accepted Solutions
gramcracker
Associate II

I found the answer on my own. I needed to be using GetMultiRangingData, not GetRangingData, which for some reason doesn't work with the extended measurements.

View solution in original post

4 REPLIES 4
John_Kvam
Senior II

To get 8 meters, absolutely everything has to be exactly right. It's kind of like saying a car can go 100 miles per hour - assuming you are going downhill, with the wind, and you have no luggage.

That 8-meters is the theoretical maximum, and only really achievable with a large, highly reflective surface.

It was invented to focus a projector, and really is only practical if you are looking at a projection screen, which is VERY reflective. 

The sensor natively can only do 4 meters, but because the raw data is uploaded into your MCU, the histogram data can be post-processed to get more data out of it.

But the first thing you must do is insure you have the software for the VL53L1CB and NOT the VL53L1X. That's a pretty subtle difference. 

If you use code that is not ST's, you have to start digging. Look to see if the code uses only the range data from the sensor. That will be limited to 4M max. Look to see if the histogram data is uploaded to the host. That's what you need to start. Then you have to check to see if the histogram is checked for wraparound. 

And it's that last bit that's tricky. 

Generally, the sensor wants to send out as many pulses as it can in the fixed timing budget, and if you only wait for the light to go out 4 meters and come back, you have an issue at say 4.2 meters. The sensor assumes the photons are returning from the most recent flash, when in fact they will be from the N-1 flash. So instead of getting 4.5 meters you are going to get 0.5 meters. It's the actual distance minus the 'wrap around' or aliased distance. 

But the sensor is tricky. It sends light with a wrap point at 4M and another at 4.2 meters. From this the sensor sees a raw distance of 0.5 for the first range and 0.3 for the second. From this, one can work out that the actual distance has to be 4.5. 

But only ST's code does this. If you get your code from somewhere else, it's going to be up to you to insure the unwrapping code is in there. 

Personally, I'd start from the ST code for the VL53L1CB and see if you can adapt the platform.c to your processor. It would be a matter of writing the I2C code for your processor into the code structure of the platform.c file - which is left empty.

And if you want the full 8 meters, you really are going to need a projection screen. 

Good luck, 

- john

 

If this or any post solves your issue, please mark them as "Accept as Solution". It really helps the next guy.
And if you notice anything wrong do not hesitate to "Report Inappropriate Content".
I am a recently retired ST Employee. My former username was John E KVAM.

Thanks John,
I ended up using the ST code for the VL53L1CB API, and for some reason I cannot get past ~3.33 meters without getting errors OUTOFBOUNDS_FAIL and WRAP_TARGET_FAIL when set like this. Even in a dim room on a white wall:

    VL53L1_SetPresetMode(Dev, VL53L1_PRESETMODE_RANGING);
    VL53L1_SetDistanceMode(Dev, VL53L1_DISTANCEMODE_LONG);
    VL53L1_SetMeasurementTimingBudgetMicroSeconds(Dev, 500000);

Same results with this:

    VL53L1_SetPresetMode(Dev, VL53L1_PRESETMODE_RANGING);
    VL53L1_SetDistanceMode(Dev, VL53L1_DISTANCEMODE_MEDIUM);
    VL53L1_SetMeasurementTimingBudgetMicroSeconds(Dev, 500000);

Autonomous mode gets me up to ~5 meters. but why?

    VL53L1_SetPresetMode(Dev, VL53L1_PRESETMODE_AUTONOMOUS);
    VL53L1_SetDistanceMode(Dev, VL53L1_DISTANCEMODE_LONG);
    VL53L1_SetMeasurementTimingBudgetMicroSeconds(Dev, 500000);
gramcracker
Associate II

I found the answer on my own. I needed to be using GetMultiRangingData, not GetRangingData, which for some reason doesn't work with the extended measurements.

Hi

Glad to hear you have found the root cause, indeed L1 supporting below 3 ranging modes,  

  • VL53L1_PRESETMODE_RANGING
  • VL53L1_PRESETMODE_MULTIZONES_SCANNING
  • VL53L1_PRESETMODE_AUTONOMOUS

The bare driver provides two functions to select whether single ranging data or multiple ranging data are returned

  • The “Get a single data” function is only available in autonomous mode. This function should not be used in ranging and multizone scanning modes.
  • The “Get multiple data” function is only available in ranging and multizone scanning modes. This function should not be used in autonomous mode.

 

You can get more detail from chapter 4.3 Time-of-Flight long-distance ranging sensor with advanced multi-zone and multi‑object detection - User manual

 

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.