I’m already using adafruit library,would installing the library you mentioned in your comment be a good idea? using which statement can I set high accuracy mode for my sensor under adafruit library? Also I have verified that I have the right library installed.
I assumed you were using our carrier board for the VL53L0X and our library, but it seems like that is not the case. What board are you using? Our library is designed specifically to work with our carrier board, although it might still work for you if you are using Adafruit’s breakout or another board.
It is possible to change the ranging profile in our library as I mentioned, and you can look at our example sketch to see how it does this. If you want to keep using the Adafruit library, though, I recommend looking at their library documentation or contacting their support directly, since we do not know if it can do what you want.
-Nathan
I ordered it from rhydolabz, and it is your make. Here is the link from where I purchased.
I thought your library or adafruit’s library is applicable for all types of VL53LOX carrier boards. Anyways it appears that I am using adafruit’s library in your board, can that be a reason for problem? The distance measured by this sensor is in the ±5 mm of actual distance. Can setting the profile to high accuracy bring it down to 0.5 mm because that is the accuracy I need for my project.
To be honest, Adafruit’s code is little bit easy to understand than yours. But still I am more than willing to use your library and code for my project. can you give me the link to some of your examples where you have been using this sensor for continuous mode? Also I am not using long range for my project, I just need to measure distance up to 650 mm. In that case what signal rate limit should I set?
Adafruit’s library will probably work with our boards, but we cannot help you use it since we do not know if it is possible to use it to change the parameters we discussed earlier. It is possible to install our VL53L0x library in your IDE without breaking the Adafruit library, but you should only use one or the other in any sketch.
We have some examples including a continuous mode example sketch included with our library. You might try loading the library (using the instructions I mentioned above) and test the results from the example sketch with your sensor with target at a few known distances around 650 mm to see how it behaves. If you get poor results with the default sketch, we should be able to help you modify the sketch to see if it is possible to improve the results.
By the way, the resolution of the sensor’s measurements is only 1.0mm, so you will not be able to get down to 0.5mm without some kind of averaging of multiple measurements. It is not clear if getting 0.5mm accuracy from the sensor is practical.
-Nathan
would this code work?
#include <Wire.h>
#include <VL53L0X.h>
VL53L0X sensor;
int pospulse = 11;
int negpulse = 12;
int clockwise = 7;
int anticlockwise = 8;
float sum = 0;
float sensorvalue = 0;
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();
sensor.setMeasurementTimingBudget(200000);
}
You should call the setMeasurementTimingBudget()
function before startContinuous()
, but otherwise your code seems fine. You might do that, add some code to return values via the serial monitor (we have that in the examples), and then point the sensor at a target and check the results.
-Nathan
I am doing something like this to achieve better accuracy,
#include <Wire.h>
#include <VL53L0X.h>
VL53L0X sensor;
int pospulse = 11;
int negpulse = 12;
int clockwise = 7;
int anticlockwise = 8;
float sum = 0;
float sensorvalue = 0;
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.setMeasurementTimingBudget(200000);
sensor.startContinuous();
}
void loop()
{
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
pinMode(clockwise, OUTPUT);
pinMode(8, OUTPUT);
float arrayofreadings[20];
for (int i = 0; i < 20; i++)
{
arrayofreadings[i] = sensor.readRangeContinuousMillimeters();
if (sensor.timeoutOccurred()) {
Serial.print(" TIMEOUT");
}
sum = sum + arrayofreadings[i];
Serial.println(sum);
}
sensorvalue = sum / 20;
//sensorvalue = measure.RangeMilliMeter;
Serial.println("sensorvalue = ");
Serial.print(sensorvalue);
Serial.println();
I am reading continuous values in millimeters from the sensor and adding them together to eventually find mean (mathematical). Is what am I doing correct?
When I examine this code practically it gives consistent readings but when it “fails to boot” (according to adafruit’s library) it gives constant reading of 17476 mm. I don’t know where did this come from and how to control this? I mean I have to stop execution of the code when such sort of error occurs and show some message on the serial monitor.
Hello, Dhruvan.
That code looks like it should work. We are not familiar with the “failure to boot” error or readings that are consistently 17476mm. Our library will return a reading of 8190 or 8191 if it does not get a strong enough return from the target. You might look at your individual measurements and discard any with those two values before you perform your averaging if you will be using the sensor in conditions where it is not likely to see your intended target. You might also check your electrical connections to the sensor to make sure they are not intermittent.
-Nathan
Thanks a lot Nathan, I guess I can carry on from here. Although I’ll get back to you if I need any further assistance. Once again, thanks for all your help.
I am getting a lot of fluctuations in readings from the sensor is there anyway I can make it constant?
Hello.
Can you post your latest code here?
-Nathan
#include <VL53L0X.h>
VL53L0X sensor;
int pospulse = 11;
int negpulse = 12;
int clockwise = 7;
int anticlockwise = 8;
float sum = 0;
float sensorvalue = 0;
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.setMeasurementTimingBudget(200000);
sensor.startContinuous();
}
void loop()
{
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
float arrayofreadings[20];
for (int i = 0; i < 20; i++)
{
arrayofreadings[i] = sensor.readRangeContinuousMillimeters();
if (sensor.timeoutOccurred()) {
Serial.print(" TIMEOUT");
}
sum = sum + arrayofreadings[i];
Serial.println(sum);
}
sensorvalue = sum / 20;
//sensorvalue = measure.RangeMilliMeter;
Serial.println("sensorvalue = ");
Serial.print(sensorvalue);
Serial.println();
I’m taking an average of 20 readings still it isn’t correct one.
What kind of variation do you currently see in the measurements and how long do you have to take your measurements? You might try using these following functions to increase the return signal rate limit and laser pulse periods:
// set the return signal rate limit (default is 0.25 MCPS)
sensor.setSignalRateLimit(0.25);
// set laser pulse periods (defaults are 14 and 10 PCLKs)
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 14);
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 10);
I am not certain those settings will help, but it seems like they might. They are discussed more in section 7 of the API User Manual ST provides.
-Nathan
I tried what the code you suggested in your above message. After changing my code, the code looked as follows:
#include <Wire.h>
#include <VL53L0X.h>
VL53L0X sensor;
int pospulse = 11;
int negpulse = 12;
int clockwise = 7;
int anticlockwise = 8;
float sum = 0;
float sensorvalue = 0;
void setup()
{
Serial.begin(115200);
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.setMeasurementTimingBudget(200000);
sensor.startContinuous();
sensor.setSignalRateLimit(0.25); // 0.25 MCPS
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 14); // 14 and 10 PCLKs
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 10);
}
void loop()
{
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
sum = 0;
float arrayofreadings[20];
for (int i = 0; i < 20; i++)
{
arrayofreadings[i] = sensor.readRangeContinuousMillimeters();
if (sensor.timeoutOccurred()) {
Serial.println(" TIMEOUT");
}
sum = sum + arrayofreadings[i];
Serial.println(sum);
}
sensorvalue = sum / 20;
//sensorvalue = measure.RangeMilliMeter;
Serial.println("sensor value = ");
Serial.print(sensorvalue);
Serial.println();
}
But it doesn’t seem to be working. Instead it stopped working at all. It gives me “65535 TIMEOUT” error.
Then I researched on internet and found that the following code might address this timeout issue.
#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();
sensor.setSignalRateLimit(0.25); // 0.25 MCPS
#if defined LONG_RANGE
// lower the return signal rate limit (default is 0.25 MCPS)
// increase laser pulse periods (defaults are 14 and 10 PCLKs)
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 14);
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 10);
#endif
#if defined HIGH_SPEED
// reduce timing budget to 20 ms (default is about 33 ms)
sensor.setMeasurementTimingBudget(200000);
#endif
}
void loop()
{
Serial.print(sensor.readRangeContinuousMillimeters());
if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
Serial.println();
delay(500);
}
Well, it does addresses the issue at hand but the result is same as before-> Inconsistent readings. Following are the readings I got from the sensor upon execution of above code.
519
522
523
512
516
518
522
510
512
523
517
519
511
521
513
520 and so on.
Please reply to the above message.
Hello.
Sorry for the delay; I did some testing here.
It appears that you did not change the values from their defaults as I suggested, so I would not expect the code you posted to make the sensor results behave any differently than if those lines were omitted.
ST does not provide especially clear documentation of how those variables affect measurements, but I did not see a clear pattern here in my test configuration (using the sensor at a distance of about 160mm with a large white board), so perhaps they will not be very useful for your application, either. However, increasing Measurement Timing Budget seems like a reliable way to decrease variation of measurements. Here are standard deviations of a set of 250 single measurement samples using different measurement timing budgets.
As you can see, increasing the length of time of the measurements reliably decreases the variance of the measurements, however you are trading measurement time for accuracy in those situations. Averaging multiple measurements should also decrease the variance. In my somewhat ideal test setup (with a large, close, reflective object), it appears that (if the trend holds), it would take several seconds of averaging to get to 0.5mm repeatability reliably. I would expect a non-ideal situation to take longer,
-Nathan
you don’t need to say sorry nathanb. Actually I’m sorry for being a bit impatient.
I did exactly what you said in your code.
// set the return signal rate limit (default is 0.25 MCPS)
sensor.setSignalRateLimit(0.25);
// set laser pulse periods (defaults are 14 and 10 PCLKs)
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 14);
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 10);
Are these values(0.25,14 & 10) to be set to another specific values? If yes, then to which values?
From the chart and as you said, I can see that higher the timing budget, lower the variations. How high should i set my timing budget? currently it’s set to 200 ms. Should I set it to 2000 ms?
I understand it would be at the cost of delay in time for measurement, but I don’t have time constraints. I don’t mind if the readings take more than 2 sec.
After doing some tests, is seems like changing the defaults does not increase the accuracy for most cases, but what range of distances are you trying to measure?
You might try 500ms and to double the number of measurements you are averaging, but again, your setup might vary. Also, it seems like the material does have a small effect on measurement range and that the average of a bunch of measurements does not always equal the true distance. It seems like it might not be very practical to get a range that is more accurate than a few millimeters. This other ongoing thread might be useful for you:
-Nathan
Thanks nathanb, I agree that changing the defaults doesn’t make much of a difference. I am trying to measure a range from 0 to 600 mm. I tried 500 ms and it gives consistent readings without much fluctuations, in fact when I add a median Filter it gives even better readings. I am posting my code below.
#include <Wire.h>
#include <VL53L0X.h>
#include <MedianFilter.h>
MedianFilter test(10, 0);
VL53L0X sensor;
float sum = 0;
float sensorvalue = 0;
void setup()
{
Serial.begin(115200);
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.setMeasurementTimingBudget(200000);
sensor.startContinuous();
sensor.setSignalRateLimit(0.1); // 0.25 MCPS
// sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18); // 14 and 10 PCLKs
//sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
}
void loop()
{
int val = sensor.readRangeSingleMillimeters();
test.in(val);
val = test.out();
Serial.print("val value = "); Serial.println(val);
sum = 0;
float arrayofreadings[10];
for (int i = 0; i < 10; i++)
{
int val = sensor.readRangeSingleMillimeters();
test.in(val);
val = test.out();
arrayofreadings[i] = val;
if (sensor.timeoutOccurred()) {
Serial.println(" TIMEOUT");
}
sum = sum + arrayofreadings[i];
Serial.print("sensor value = ");Serial.print(val); Serial.print(" ");
Serial.print("sum value = ");Serial.println(sum);
}
sensorvalue = sum / 10;
//sensorvalue = measure.RangeMilliMeter;
Serial.print("sensor value = ");
Serial.println(sensorvalue);
}
But the problem with this code is that it is giving measurements that are quite far from the actual measurements.
|Actual Value| Sensor Value| Difference|
|180| 185| 5|
|185| 192| 7|
|190| 199| 9|
|195| 202| 7|
|200| 208| 8|
|205| 212| 7|
|210 218| 8|
|215| 224| 9|
|220| 229| 9|
|225| 234| 9|
|230| 238| 8|
|235| 247| 12|
|240| 251| 11|
|245| 255| 10|
|250| 261| 11|
|255| 267| 12|
|260| 273| 13|
|265| 278| 13|
|270| 283| 13|
|275| 288| 13|
|280| 296| 16|
|285| 300 15|
|290| 305| 15|
|295| 310| 15|
|300| 315| 15|
|305| 321| 16|
|310| 327| 17|
|315| 331| 16|
|320| 336| 16|
As you can see, the difference between actual value and sensor value keeps on increasing. But I can’t seem to find an equation that satisfies this variations. If there is some sort of mathematical curve that can predict the deviation of the sensor value from the actual value, then I can use it to correct the error.