The one at the link I provided? I thought you were using the VL6180Sketch you attached here… Which sketch were you running when you made the video?
I still don’t have permission to view it. This is the link I have:
https://drive.google.com/file/d/1lhqJS55gw6dOduaFw5kUVi4s5VWVy_cC/view?usp=drive_link. You’ll have to make the file publicly accessible like you did with the video files. Alternatively, you could attach the code to a forum post like you did earlier.
Sorry I forgot to make the configuration file public.
Hey @jerdonaldson,
From what I can tell, your initialization code only configures three registers in the same manner as the Arduino library. The rest are either different, missing, or unnecessary. I suggest you adapt Adafruit’s initialization routine as closely as possible. That is, configure all of the registers they configure, in the same order that they configure them, with the same values that they used to configure them. Only once you’ve matched the behavior to your Arduino setup should you try customizing any settings.
Matt,
Funny I found that site recently but the register addresses looked strange so I just bookmarked it for later.
I wrote a config that split the addresses between msb and lsb, and sent the data to all the registers and it fixed the problem.
As in the Arduino I have no delay between starting the measurement and reading it. The configuration may cause a built in delay but I didn’t see one in the I2C waveforms.
This shouldn’t matter in my setup because I have eight sensors to read all in sequence so using the XSHUT pin I start each one and then go back and read each measurement. I prototyped this method and it seemed to work.
Thanks for all the help. Hope I don’t have to bother you again.
Jerry
Matt,
Ran into another problem.
I have to get the distances from eight sensors in 50ms or less. I can’t use XSHUT because the data sheet says to wait 300ms after enabling it. So I have the I2C clock going to an HC4051 multiplexer/demultiplexer and all the data lines tied together. I select one sensor at a time, start their measurements and after doing them all and after an appropriate delay read all the distances. I mentioned before that I have confirmed that this works but that was done with the old problem before the Arduino configuration file.
Now working with just one sensor I don’t have the old problem with the Arduino configuration without using the muxer but as soon as I hook the SCL line to the muxer the old problem is back. The data lines are still all tied together.
The HC4051 is more than fast enough, the waveforms still all line up, the levels and rise and fall times are good. I tried pull ups on all I2C lines and there are no long wires. Nothing seems wrong.
I can send you scope shots of the waveforms if you want them.
Jerry
Hey @jerdonaldson,
There should be no need to multiplex when using multiple VL6180X sensors. The I2C address is configurable.
Matt,
I understand that approach. I’ll use XSHUT in conjunction with 0x212 to set a different slave address for every sensor.
I changed the data in register 0x207 to a 0x02 because I needed more range. I can live with the resolution.
That didn’t work so I wrote this code to read it but I only get back a 255?
int readRegister()
{
int range;
I2C_Master_Start();
I2C_Master_Write(0x29 << 1); // TOF050C I²C slave address write
I2C_Master_Write(0x02); // msb of register byte for range
I2C_Master_Write(0x07); // lsb of register byte for range
I2C_Master_RepeatedStart();
I2C_Master_Write((0x29 << 1) | 1); // TOF050C I²C slave address read
range = I2C_Read_Byte(1); // Read the measured distance
I2C_Master_Stop();
return (range);
} // end int readRegister()
Is that the correct register and can you see why I can’t read it?
Jerry
Matt,
Sorry, I’m actually reading a 1 from register 0x207.
I used the same code to successfully read another register so it seems like there’s something different about 0X207.
Jerry
Hey @jerdonaldson,
I must be missing something here… What leads you believe this will provide greater range?
The only documentation I can find on register 0x0207 is in Section 9 of AN4545: VL6180X Basic Ranging Application Note. This document indicates it is a private register, i.e., not intended for user configuration.
Matt,
I got this from AI when I asked "How can I extend the range of a VL6180X?
“To extend the range of the VL6180X sensor, you can use a scaling multiplier of 2 or 3, which allows the sensor to measure distances beyond its default limit.”
Scaling Factor Maximum Range Resolution
1 20 cm 1 mm
2 40 cm 2 mm
3 60 cm 3 mm
When I asked for the register number it said it was 0x207. Maybe the scale multiplier is a different register.
Jerry
Hey @jerdonaldson,
Such responses from AI agents should never be taken at face value. You should follow up such answers with “Where did you get this information?” or “Show me your sources”. If you can’t trace the information it gives you back to a trustworthy source, it’s likely confused or just making things up.
Matt,
Okay I’ll be more suspicious of AI.
John E KVAM, ST Employee, once put this in a forum.
"When we invented that chip, we expected it to range to 10cm or so. So the range result only needed to be one byte. That should be fine, they said.
But the 6180 can with a bright target get to 600mm and that doesn’t fit in a byte.
So we put in a ‘multiplier’ which can be 2 or 3. With a multiplier of 2, and a real distance of 500 mm, we return 250.
It’s on you to take the result we send and do the x2.
Otherwise there is nothing else to set.
But you are going to have to remember which multiplier you set. Look for VL6180x_UpscaleSetScaling() in the datasheet."
Since I don’t know how far away the target is, how would I know when to apply the multiplier?
I searched for UpscaleSetScaling in the data sheet but it wasn’t there.
Jerry
Hey @jerdonaldson,
Ah, that helps tremendously! You can find that post here: Solved: How to increase the range of VL6180x - STMicroelectronics Community.
The VL6180x_UpscaleSetScaling() John refers to is a function found in the VL6180X API (a.k.a. STSW-IMG003), which appears to have been scrubbed from ST’s website
.
However, there are plenty of other libraries on GitHub which implement this functionality. One of them is the VL6180X repo from stm32duino. It looks like the “16-bit” register at 0x096 is the RANGE_SCALER register (see here). The valid values for this “16-bit” register are defined here.
static const uint16_t ScalerLookUP[] ROMABLE_DATA = {253, 127, 84}; /* lookup table for scaling->scalar 1x2x 3x */
Since these are all 8-bit values, set register 0x096 to 0x00 and set 0x097 to one of the three values (0xFD, 0x7F, 0x54) depending on your desired scaling factor.
You don’t. You once you set the multiplier, you’re stuck with it.
Matt,
This was a great email because that UpscaleSetScaling all worked.
I tried all three values and found that 0xFD ranged to 100mm, 0x7f to 300mm and 0x54 to 400mm. Just measured with a tape measure.
I’ll get back to you after I update the software and hardware to implement the things you pointed out.
I’ve read several things by John E. KVAM. Is he retired from ST?
Thanks,
Jerry
This would be a good question you should ask ST’s directly and not a 3rd party. ST’s forum is located here: Imaging (sensors) - STMicroelectronics Community
Regards,
Matt_Mielke,
I’ve run into another problem.
The device I was using for all our work still works perfectly and I have some new ones that I pre-tested.
Then I wired several of these new ones in parallel but kept XSHUT separate to distinguish which one is active. All had power, ground, SDA and SCA connected and XSHUT was pulled low on all but the one I wanted active.
In this configuration the active one read zero when the sensor got within about 125mm of a target and the readings outside that distance were all over the place and totally wrong.
I pulled one of them out of the parallel wiring and it worked fine. Same hardware and software.
I thought it might have something to do with the model number so I read the old and new ones with the following decimal results.
register 0x00 IDENTIFICATION_MODEL_ID = 180 on both
register 0x01 IDENTIFICATION_MODEL_REV_MAJOR = 1 on both
register 0x02 IDENTIFICATION_MODEL_REV_MINOR = 3 on both
Is there a register to indicate they will be wired in parallel?
Jerry
Hi @jerdonaldson,
There will be no such register. I2C is designed for multiple devices on a shared bus. As long as the sensor is seeing the behavior it expects to see on the bus, it will be happy.
Why might there be unexpected behavior? I can think of two reasons off the top of my head:
- Excessive bus capacitance is increasing the rise time of your signals, preventing them from changing fast enough to exceed the logic-high threshold before the device samples them.
- The master device is mis-managing the bus. Perhaps not properly completing a transaction with one device before starting a transaction with another. Perhaps a clock stretching issue. Something like that…
Since you’ve reported prior success in reading from multiple sensors on this bus, we can probably shelve #2 for now. Unless, of course, you’ve made other changes to the code you haven’t mentioned. Also, you need to be 100% certain there’s no address conflicts!
Regarding issue #1:
How many is several? How long are the wires? Any sources of interference? What’s the pull-up resistor situation?
The first thing I would do is try halving the I2C clock speed. I assume you’re at 100 kHz now? Try 50 kHz (or even less!). This should get the sensors working if bus capacitance is the root problem. You’ll then have to address this capacitance issue if you want to get the bus back up to full speed.
Matt,
Hold off on looking into this while I go back and re-check my code for changing all the slave addresses. I’ll get back to you.
Jerry
Matt_Mielke,
My code to change the slave address was good but I didn’t realize that taking XSHUT to zero reset the sensor. Just had to move some code around.
Good for now.
Jerry
Matt_Mielke,
Just a follow up on what you were helping me with.
I now have nine laser sensors working, all with a different slave address. I give all of them a start command followed by a 25ms delay then go back and read the distances from all nine. The whole thing takes about 35ms.
Thanks,
Jerry