cancel
Showing results for 
Search instead for 
Did you mean: 

vl6180x register 0x004f is never set in single shot mode, yet the 0x062 contains valid distance.

0x00ff
Associate

EDIT [Solution]: The register 0x0014 needs to be set to 0x04. (I put more details in the reply but it has been marked as spam for some reason).

 

I am in process of interfacing an Attiny85 (not Arduino) with a VL6180X board (with I2C level shifter built-in).

I wrote my own I2C master interface (USI) and I am able to successfully to get the VL6180X work in a single shot mode (after many hours of struggle).

I spent a lot of time wild geese chasing due to VL6180X "pretending" to respond correctly to some of the register read/writes but not being able to actually read the actual distance until I moved the whole thing to battery power (adding additional capacitors to 2.8V or 3.3V supplies didn't help).

One thing that lead me astray was the fact that I never bothered to check the actual contents of the 0x0062 register after setting the 0x0018 register, as I was following somewhat scarce documentation and polling the 0x004f register for a ready bit set (as per the application note):

 

 

Poll RESULT__INTERRUPT_STATUS_GPIO {0x4f} register till bit 2 is set to 1

 

 


Now I suspect I am not setting some kind of result threshold thus the problem. I followed the application note as much as I could including the SR03 Settings section and set all the undocumented "Mandatory" registers and "Recommended" including this:

 

 

WriteByte(0x0011, 0x10); // Enables polling for ‘New Sample ready’
                         // when measurement completes

 

 

I also set the "Optional" registers one of those is this:

 

 

WriteByte(0x0014, 0x24); // Configures interrupt on ‘New Sample
                         // Ready threshold event

 

 

Have I missed anything else?

My I2C communication seem to be more or less OK.
setting 0x0018 registersetting 0x0018 registerreading 0x004f registerreading 0x004f registerreading 0x0062..63 registersreading 0x0062..63 registers

Unfortunately the attiny85 USI interface is a bit sloppy with I2C timings, but it seems to be doing the job OK (I think it would have been better if SDA was delayed by ~2uS, but I do not have control over that, unless I rewrite I2C with pure bit banging implementation). BTW I run my attiny85 at 8MHz with 1/1 clock division (I could not go over 50kHz I2C rate otherwise).

Slightly off topic: this sensor caused me a lot of grief, initially I prototyped the device with Micropython, and I got caught out be the fact that the register address size is at least 16bits (16bits seems to cover all use cases), and the fact that instead of not replying the sensor when read from register 0x00 (not 0x0000) at first would give correct 0xb4 output, and further reads would give random values. Then after I figured out most of the things I moved on to Attiny85 with pure C implementation, and then I found out that the sensor would refuse to get into ready state (LSB of 0x004d is not set) when I would drive I2C bus at ~50kHz. To add further to the confusion if I would short the GPIO1 to ground and release it, the sensor would wake up at said frequency and work until a power cycle.

Is there a product that can output 20 to 100mm range, which is more tolerant to I2C sloppy timings and requires less pain to initialise (ie, simple reads from an address would be ideal).

Another questions why would end user require to set the mandatory registers in first place if they are static and undocumented? Should it be part of the firmware of the device? I assume some big partner gets to see full documentation and those registers can unlock more capabilities.

1 ACCEPTED SOLUTION

Accepted Solutions
0x00ff
Associate

I believe I figured out my problem.

I was not setting register 0x0014 (SYSTEM__INTERRUPT_CONFIG_GPIO) to 0x04.

Since then I get two things happening:

  1. GPIO1 being pulled down when the sample is ready (very neat).
  2. The register 0x004f is set.

Not sure if I have enough pins on ATTin85 to use the physical GPIO1 as interrupt, even if not, now I can poll 0x004f instead of sleeping for 200ms.

Interestingly enough while I was debugging (I read every register I set) this I noticed the ALS integration time register setting didn't stick (I don't care about ALS). This sent me to read dt0037-vl6180x-range-and-ambient-light-sensor-quick-setup-guide-stmicroelectronics.pdf which had a neat flow chart that mentioned setting register 0x0014.

0x0040_not_setting.png

View solution in original post

1 REPLY 1
0x00ff
Associate

I believe I figured out my problem.

I was not setting register 0x0014 (SYSTEM__INTERRUPT_CONFIG_GPIO) to 0x04.

Since then I get two things happening:

  1. GPIO1 being pulled down when the sample is ready (very neat).
  2. The register 0x004f is set.

Not sure if I have enough pins on ATTin85 to use the physical GPIO1 as interrupt, even if not, now I can poll 0x004f instead of sleeping for 200ms.

Interestingly enough while I was debugging (I read every register I set) this I noticed the ALS integration time register setting didn't stick (I don't care about ALS). This sent me to read dt0037-vl6180x-range-and-ambient-light-sensor-quick-setup-guide-stmicroelectronics.pdf which had a neat flow chart that mentioned setting register 0x0014.

0x0040_not_setting.png