Enter Your Project for a chance to win a Nano Grand Prize bundle for the most innovative use of Arduino plus a $400 shopping cart! Back to homepage | Project14 Home | |
Monthly Themes | ||
Monthly Theme Poll |
I've begun to characterize the distance measurement repeatability of the VL6180X TOF sensor. The testing is in context of setting the focal distance of my laser cutter. I've empirically determined that the correct focal distance is 39 mm.
The resolution of the VL6180X is 1 mm and the spec measurement noise is 2.0 mm over 100 measurements. I'm hoping to be able to get to +/- 0.5 mm repeatability using averaging.
From the spec it looks like it could be challenging:
The optimum operating temperature range is -10 to 60 C and my environment is probably +/- 2 C so hopefully I won't see that much drift and I'm also hoping that the onboard regulator is better than the 2.8V +/- 100 mV spec.
We'll have to see how the test data looks....
The VL6180X has a single-shot and continuous mode. The continuous mode allows scheduling of periodic measurements which is great for doing multiple measurements for averaging. The VL6180X library from Pololu includes an example of an averaged measurement using continuous mode. I've adapted that to use with the MicroView. The example averages over 100 measurements but that's a parameter that I could play with. The sampling period is set to 100 ms.
MicroView_VL6180X_InterleavedContinuous.ino
/* This example demonstrates how to use interleaved mode to take continuous range and ambient light measurements. The datasheet recommends using interleaved mode instead of running "range and ALS continuous modes simultaneously (i.e. asynchronously)". In order to attain a faster update rate (10 Hz), the max convergence time for ranging and integration time for ambient light measurement are reduced from the normally recommended defaults. See section 2.4.4 ("Continuous mode limits") and Table 6 ("Interleaved mode limits (10 Hz operation)") in the VL6180X datasheet for more details. Raw ambient light readings can be converted to units of lux using the equation in datasheet section 2.13.4 ("ALS count to lux conversion"). Example: A VL6180X gives an ambient light reading of 613 with the default gain of 1 and an integration period of 50 ms as configured in this sketch (reduced from 100 ms as set by configureDefault()). With the factory calibrated resolution of 0.32 lux/count, the light level is therefore (0.32 * 613 * 100) / (1 * 50) or 392 lux. The range readings are in units of mm. */ #include <MicroView.h> #include <Wire.h> #include <VL6180X.h> VL6180X sensor; float dist, sens, csens, offset = 5.0; int count; void setup() { Wire.begin(); sensor.init(); sensor.configureDefault(); // Reduce range max convergence time and ALS integration // time to 30 ms and 50 ms, respectively, to allow 10 Hz // operation (as suggested by Table 6 ("Interleaved mode // limits (10 Hz operation)") in the datasheet). sensor.writeReg(VL6180X::SYSRANGE__MAX_CONVERGENCE_TIME, 05); //sensor.writeReg16Bit(VL6180X::SYSALS__INTEGRATION_PERIOD, 10); sensor.setTimeout(500); // stop continuous mode if already active sensor.stopContinuous(); // in case stopContinuous() triggered a single-shot // measurement, wait for it to complete delay(300); //READOUT__AVERAGING_SAMPLE_PERIOD sensor.writeReg(0x10A, 0x08); // start interleaved continuous mode with period of 100 ms //sensor.startInterleavedContinuous(100); sensor.startRangeContinuous(10); Serial.begin(57600); uView.begin(); uView.clear(PAGE); uView.setFontType(0); //ideas // Look at docs to see how to improve accuracy // only use samples that converged // look into whether samples are used twice or other issues with the uncoltrolled loop // allow more variability in the output of the sensor and average in the mcu // measure drift by connecting to the CNC machine to get precise moves count=100; } void loop() { //Serial.print("Ambient: "); //Serial.print(sensor.readAmbientContinuous()); //if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); } sens=sensor.readRangeContinuous(); csens =sens + offset; // uView.clear(PAGE); // uView.display(); // uView.setCursor(0,0); // uView.println("Distance:"); if(sens<255) { if( abs(csens-dist)>10.0) {dist=csens;} dist = .995* dist + .005 * csens; } count=count-1; if (count ==0) { count=100; //Serial.print("\t Range: "); Serial.print(dist); Serial.println(); uView.clear(PAGE); uView.setCursor(0,0); uView.println("Distance:"); uView.print(dist); uView.println(" (mm)"); uView.display(); } if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); } }
First try - sanity check
Here is my first quick check. I used the my calibration block to adjust the laser lens to 39 mm. Then I did a couple of 2 minute data runs (100 samples each). I have an approximate offset in the software to get the measured value near 39 mm.
A short video of the MicroView display:
First run Second run
Plots
The run averages are pretty close. I suspect that some of the lower frequency, larger excursion noise is due to the fact that I was in close proximity setting up my phone to take the video. This could be due to ambient light or temperature fluctuations or maybe both. Now that I've sanity checked the setup I need to spend some time taking a clean set of data. The initial data does give me hope that I can meet +/- 0.5 mm. Maybe I need to average the averages .
I'll try to characterize:
- Short term noise (maybe over 5 minutes).
- Long term drift (could be hard to establish cause - I saw that one guy thought his "drift" was repeatable and correlated to his furnace cycling).
- Linearity (I think 1 mm steps over +/- 10 mm should be enough for my purposes).
- Repositioning repeatability.
Then it's on to try to interface to the GRBL controller and Laser GRBL. The hardware is all 5V so hopefully that will be easy. The hard part is probably going to be interfacing with the program. I've never tried to add a custom button before but it seems that it is a common thing to do.
Top Comments