Comments: VL6180 Hookup Guide
Looking for answers to technical questions?
We welcome your comments and suggestions below. However, if you are looking for solutions to technical questions please see our Technical Assistance page.
If you've found an issue with this tutorial content, please send us your feedback!
You have a bug in your library. For anyone trying to hook up two VL6180's on the same bus you need to modify the .cpp file (or Sparkfun should up date this). You need to use the changeAddress command in the .h file. To do this though I pulled my hair out for a long time till I found a bug in the library. You need to add this line after you set the register with your new i2C address
_i2caddress = new_address;
Hardware wise You will need to use the GPIO0 pin on the VL6180. Hook each device up to an output from the Arduino. You probably should use a voltage divider to make sure your input is 3.3v not 5v.
Here is the code I use to get two sensors working on an i2C bus. Hope to save others the time it took me to figure this thing out. Don't forget to modify the .cpp file
include <SparkFun_VL6180X.h>
include <Wire.h>
/****************************************************************************** * This program allows two sensors to be hooked up on a single i2C bus. Note that you * need to use the GPIO0 pins connected to outputs on the Arduino to make this work ******************************************************************************/
define VL6180X_ADDRESS 0x29
define NEWVL6180X_ADDRESS 0x30 // first VL6180
int enable1 = 2; // enable for sensor1 int enable2 = 3; // enable for sensor 2 VL6180xIdentification identification;
VL6180x sensor2(VL6180X_ADDRESS); // create both sensors VL6180x sensor1(VL6180X_ADDRESS);
void setup() { pinMode (enable1, OUTPUT); // set both pins to output pinMode (enable2,OUTPUT); Serial.begin(115200); //Start Serial at 115200bps Wire.begin(); //Start I2C library delay(100); // delay .1s digitalWrite(enable1, HIGH); // turn on sensor one and shut down sensor 2 digitalWrite(enable2,LOW);
sensor1.getIdentification(&identification); // Retrieve manufacture info from device memory
};
sensor1.VL6180xDefautSettings(); //Load default settings to get started.
sensor1.changeAddress(VL6180X_ADDRESS,NEWVL6180X_ADDRESS); // change address of sensor 1
sensor2.getIdentification(&identification); // Retrieve manufacture info from device memory
};
sensor2.VL6180xDefautSettings(); //Load default settings to get started.
}
void loop() {
//Get Distance and report in mm
Serial.print("Distance measured sensor 1 (mm) = "); Serial.println( sensor1.getDistance() );
Serial.print("Distance measured sensor 2(mm) = "); Serial.println( sensor2.getDistance() );
delay(500); };
I cannot get both of these to work. I adjusted each thing you all mentioned but I can only get one sensor to work. I have adjusted the code and wired GPIO to one of the digital pins. I have the SDA and SCL going to the analog pins but it only works if I enable 1 sensor.
UPDATE: https://www.st.com/content/ccc/resource/technical/document/application_note/b4/f0/79/ec/ca/54/45/07/DM00114403.pdf/files/DM00114403.pdf/jcr:content/translations/en.DM00114403.pdf
Hi there, it sounds like you are looking for technical assistance. Please use the link in the banner above, to get started with posting a topic in our forums. Our technical support team will do their best to assist you.
Reformatted code from above:
Hi Member #828335,
Thank you for posting your code - this is great! I am struggling with the same issue you had. Can you elaborate on your first statement about the bug in the library? It is unclear from what you have written whether the change should be made to the .cpp file or to the .h file, and whether the change should be made as part of the class VL6180x statement (in .h) or as a replacement for "_i2caddress = address; " in Wire.begin (in .cpp). Trying either of these options will result in the code not compiling.
I am able to get your code to compile and run with the basic Sparkfun library, but only one sensor is sending information to the arduino (both sensor 1 and sensor 2.getDistance() report the output of sensor 1 (or sensor 2 if I swap the GPIO outputs.) Any clarification you could give would be great, and thank you again for posting this.
UPDATE - for anyone reading this, the answer to my question was to put "_i2caddress = address; " in Sparkfun_VL6180X.cpp in here: ... VL6180x_setRegister(VL6180X_I2C_SLAVE_DEVICE_ADDRESS, new_address); _i2caddress = new_address; return VL6180x_getRegister(VL6180X_I2C_SLAVE_DEVICE_ADDRESS); } ... Doing this got both sensors working in realtime for me.
I had hopes of using these devices for alignment purposes on equipment however after setting up in my lab I simply cannot get an accurate measurement out of it. I tried various lighting conditions and surfaces but a fixed distance will vary up to 4mm over each consecutive call and that's in a bench setup with a target adjusted at +/- .02mm accuracy. This is nowhere near what I expected and basically useless for anything requiring consistent accuracy. I didn't bother testing the ALS so can't comment on that.
In addition to redefining the i2c address in the .cpp file, I had to re-initialize the I2C bus in my main script, here's an example: new_adr = sensor.changeAddress(VL6180X_ADDRESS, 0x30); Wire.end(); VL6180x sensor(new_adr);
In the API from ST i found a way to get the VL6180 work with measure 0-20cm/0-40cm/0-60cm, as it is was specified from ST in the first datasheets.
in the API you can find the needed register, which is not in the currently datasheet.
This register is to manipulate the Range scaler by the factor x1/x2/x3. To make it work you have to modify the register VL6180X_SYSRANGE_PART_TO_PART_RANGE_OFFSET too, like shown in the API from ST. You have to divide the startup value of the register with the scaler.
The VL6180X_RANGE_SCALER register has a lookup table for its register values.
x1 = 253, x2 = 127, x3 = 84
I do a github repository with all the changes in the library.
https://github.com/Heftie/VL6180X
I have bought a Sparkfun VL6180 Sensor Board and connected it to a STM32F415 MikroE Mini M4 MCU. I can correctly talk to it by asking the Model ID, (which returns 0xB4 correctly), but the RESULT_RANGE_STATUS register (0x4D) always returns 0x19 (0b00011001) which according to the VL6180 datasheet means that it has a VCSEL continuity error (bits 7:4 or 0b0001). I have gotten this with both a VL6180 sensor (which has the 2.8V DC regulator) and with another VL6180 breakout (without the regulator). Is anyone else experiencing this problem?
Great tutorial but I have an application where I am using multiple VL6180 sensors on the same bus and I have a couple of questions.
In your tutorial you state that the sensor is "Defaulted to enable, two required pull-up resistors are attached to the I2C lines. Remove solder jumper if using multiple sensors on the same bus."
What does removing the solder achieve? I could be mistaken, but wouldnt you not be able to receive an I2C transmission if you desolder those pull up resistors?
Read the note a bit closer: "Remove solder jumper on all but one unit if using multiple sensors on the same bus."
Having the pull-ups enabled on all of them will actually drive the signal too high to get anything useful out of any of the boards. You only need the one set of pull-ups to prevent the signals from floating, as the I2C is active low.
How does setting up an array like this enable someone to poll each device individually, if the device addresses are all the same?
You can use a multiplexor to switch between each device individually.
If you dont want to go this route the datasheet also states that you program a new I2C slave address to the device. The setback however is that the new address is not stored in non-volatile memory. So each time the device is powered down it will revert back to its default I2C address. You will need to power up each device individually and change the address. CaseyTheRobot was going to add to the Hookup Guide on how to do this but hasnt gotten around to it.
You can use a multiplexer. That's really the only way to use multiple I2C devices on the same bus if they have the same address that cannot be changed, either hardware wise or software wise.