Mini Lidar for £11

Well to be honest, a VL53L0X time of flight chip mounted on a small circuit board and then attached to a pan and tilt set-up positioned by 9g servos.

Adafruit do a very nice little VL53L0X  board although they can also be easily sourced from a number of suppliers. I downloaded the AdaFruit Arduino wrapper for the device library to get me started. Communication is over an I2C serial interface which keeps things straightforward. 

Connections from an Arduino are just to SDA and SCL as well as 5v and ground.

The tiny VL53L0X chip includes a 940nm VCSEL laser (Vertical Cavity Surface-Emitting Laser) fitted with infra-red filters giving reasonable immunity to ambient light interference. The laser is safe and will not damage eyesight. The device sends out a short laser pulse and measures the time taken for the light to be reflected back. The measurement range is up to 2 metres although the device is normally operated in one of 4 modes. There is a default mode, a high speed mode, a high accuracy mode and a long range mode. I think that all but the long range mode are good up to about 1.2 metres.

Initial tests using code copied and pasted from the AdaFruit example program confirmed that distance measurement was excellent – as far as I could see plus or minus a millimetre in a range to 50cm although my measurements were probably only just about that accurate anyway. At this initial stage, I was just pleased it worked.

I then added some code to get the pan and tilt servos working so I could scan a space in a sequence of horizontal lines. This got me thinking that I was effectively being presented with a low resolution 3D image – it just needs some more code (somewhere) to make sense of it.

The circuit could not be much simpler at this stage.

The first draft of the code, still using the simple Adafruit library wrapper, looked like this.

#include <Servo.h> #include <Wire.h> #include "Adafruit_VL53L0X.h" #define V_VERTICAL 124 #define H_HORIZONTAL 103 uint8_t servoHPin = 10; uint8_t servoVPin = 11; const uint8_t sclPin = A5; const uint8_t sdaPin = A4; Servo hServo, vServo; Adafruit_VL53L0X lox = Adafruit_VL53L0X(); void setup() { Serial.begin(115200); hServo.attach(servoHPin); vServo.attach(servoVPin); hServo.write(H_HORIZONTAL); vServo.write(V_VERTICAL); if (!lox.begin()) {     Serial.println(F("Failed to boot VL53L0X"));     while(1); } justScan(); } void justScan() { VL53L0X_RangingMeasurementData_t measure; while(true) {     for(int i = -20; i <= 20; i++) {      vServo.write(V_VERTICAL + i);      for (int j = -20; j <= 20; j++) {         hServo.write(H_HORIZONTAL + j);         lox.rangingTest(&measure, false);         if (measure.RangeStatus != 4){          Serial.println(measure.RangeMilliMeter);          Serial.flush(); // wait for serial buffer to clear         }      }     } } }

If you have a go at this then you would need to adjust the two values that set the neutral (straight ahead and vertical) values for the two servos as these will vary depending upon just how you put the pan and tilt together. It would have been nice if they were both 90 (the servo neutral position) but life did not work out that way.

#define V_VERTICAL 124
#define H_HORIZONTAL 103

A quick look around the Internet (May 2018) suggests that you could source all of the parts for this little set-up, ignoring the Arduino, for a few pence over £11.

I have been playing with plotting the distance measurements as a 3D surface and will report back on how that shapes up.

If you want to learn more about using the I2C serial interface or controlling servos then I can recommend my book "Practical Arduino C" available at Amazon.


Popular posts from this blog

Arduino Regular Expressions

An Arduino Sudoku Solver

Unicode output from an Arduino.