VL53L0x register access via TWI

Go To Last Post
19 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am trying to evaluate various distance sensor modules for use in a package dimensioning application. The requirements are a range of about 1 inch to 48", with an accuracy of 1/4". One of the prime candidates is the VL53L0X 'time of flight' laser sensor: http://www.st.com/en/imaging-and-photonics-solutions/vl53l0x.html. Experimenting with this particular device presents a two-fold challenge: it is a complex device with about 100 registers and a rather poor data sheet, and then there is the TWI implementation, one of the XMEGA features I have not used till now. Although the maker (ST Electronics) provides an app, it is widely considered opaque and useless by most of the community (the manual is about 180 pages). To evaluate, I would like to be able to at least read and write registers. Can anyone provide a link or suggestion to a C implementation of the TWI routines to do basic register access? There is lots of info on Github and other sources for Arduino drivers, but of course they are for the ATMEGA328, with a different TWI implementation, and a different set of constants, bit masks, and defines. What would be ideal would be a simple set of C functions to read and write VL53L0X registers (8 and 16 bit) specifically for the XMEGA. I will mention that I am using the XMEGA128A1U because it has 4 TWI ports, and I need 3 of them for the X,Y, and Z axes. Besides, I really like the XMEGA family, great variety and features!

 

In addition, I am open to suggestions for other sensors that might work well in this application. I now have an Adafruit VL53L0x module, that I am currently trying to bring up (subject of this post). I have also looked at the Lidar-Lite V3 unit, very disappointing at $130, poor linearity and accuracy below about a foot. This was attractive because of its available PWM mode, requiring only on I/O pin to measure distance (although it is basically an I2C device). Slated for evaluation in the coming week(s), the Mikroelectronica 'Proximity 3 click' (laser), the Parallax 'Ping)))' (ultrasonic), and the Parallax 'Laser Range Finder 2M', p/n 28044 (camera triangulation). The latter device is very attractive because it has a dead simple ttl serial i/f. if anyone has experience with any of these, pro or con, I would love to hear about it. My online research so far indicates that most of these devices fail to live up to their published accuracy specifications. This all started because it was recommended that I hack the Bosch GLM20 laser ruler, available at hardware stores for about $50. This device seems to be the gold standard of what I am looking for, (1/8" accuracy up to 65 feet) , but unfortunately Bosch does not make the guts available as an OEM product. If they did this would be the perfect sensor for robotics, drones, etc (are you listening Bosch?).

 

Suggestions and comments welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hsieber wrote:
 I need 3 of [TWI ports] for the X,Y, and Z axes

Why??

 

I2C is a bus - the whole point of a bus is that it can have multiple devices on it!

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Of course the TWI bus can be multidropped. However the slave address of the sensor defaults to 0x52 on every startup. I would need to selectively power off or disconnect 2 sensors at a time to reassign the slave address, every time the power is cycled. TWI is already a bag of doodoo, interfacing a sensor shouldn't be so hard. Why can't they add one wire and use SPI, a very simple and easy to use protocol?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why can't they add one wire and use SPI, a very simple and easy to use protocol?

Maybe because SPI would require two more wires, not just one? ;-)

 

MISO

MOSI

SCK

CS

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

There is an Application Note that shows you how to use multiple devices http://www.st.com/resource/en/application_note/dm00280486.pdf

 

It looks as if they have demo boards too.   It is probably easier to get up and running with the ST evaluation board.

 

No,  I have not used this device.    You will have some learning to do.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
SPI would require two more wires, not just one? ;-)

 

MISO

MOSI

SCK

CS

and that would actually be a CS per device ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ST Device page: http://www.st.com/en/imaging-and-photonics-solutions/vl53l0x.html

 

david.prentice wrote:
It looks as if they have demo boards too.

Indeed:

 

X-NUCLEO-53L0A1

http://www.st.com/content/st_com/en/products/ecosystems/stm32-open-development-environment/stm32-nucleo-expansion-boards/stm32-ode-sense-hw/x-nucleo-53l0a1.html

 

 

It is probably easier to get up and running with the ST evaluation board.

Yes - I generally find that the manufacturer's own eval board is the best bet

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

 

There is an Application Note that shows you how to use multiple devices http://www.st.com/resource/en/application_note/dm00280486.pdf

That doesn't alleviate the problem for the OP:

 

Figure 2 is a typical example schematic using a VL53L0X device. Since the VL53L0X
can have the I2C device address changed by doing an I2C write once it is booted, a
unique reset pin would be needed for each VL53L0X used in a design.
Each device is
then taken out of reset one at a time, and then the I2C Device Address is changed to a
new unique address. This can be done by using multiple GPIO pins from the
microprocessor on the board.

So to control 3 separate devices on a single TWI bus would take 5 pins (SDA, SCK, reset_0, reset_1, reset_2).  That's only one better than three TWI buses (two of which could be bit-banged).

 

However, the devices' reset pins could be triggered by an external reset RC circuit such that each device comes out of reset at a different time.  Firmware on the mcu could just continue device discovery until each device comes online, an change each slave address as they do.  The reset pulse could be triggered by a single GPIO, or be tied to /RESET or VCC for a zero-pin cost.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well the obvious eluded me again. Atmel's AVR1308 app note has good explanation, examples, drivers, all there. It's a bit generalized for my app but will be the way to learn.

OK OK, forgot about CS for SPI. Well if we're saving wires why not go to the truly awful Dallas One-Wire (I think its Maxim now).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

@joey,

The XSHUT pin enables you to disable devices before programming with a new Slave address.   i.e. it is effectively a ChipSelect pin.

 

@hsieber,

As with any project,   break it into sections.   e.g. get TWI working on simpler devices.

Then you can port MEGA328 example high level code directly to your XMEGA.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
So to control 3 separate devices on a single TWI bus would take 5 pins (SDA, SCK, reset_0, reset_1, reset_2).  That's only one better than three TWI buses (two of which could be bit-banged).

I think that's missing the point: the scarce resource here is the number of TWI controllers.

 

As the app note says, if you're stuck for pins, you could do the resets via an I2C IO expander ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think that's missing the point: the scarce resource here is the number of TWI controllers.

Not at all.  Those can bit bit-banged.  However the OP seems already to be leaning towards xmega with enough interfaces.

 

As the app note says, if you're stuck for pins, you could do the resets via an I2C IO expander ...

Many ways to skin a cat.

 

The XSHUT pin enables you to disable devices before programming with a new Slave address.   i.e. it is effectively a ChipSelect pin.

I understood that.  My comment was meant to suggest an approach to get all three sensors to work on one TWI bus without the need for a GPIO pin for each device's reset pin (XSHUT), nor an I2C expander.  You'd still need GPIO pins for each device's interrupt pin.  Of course with the choice of a microcontroller with enough interfaces and pins, you have more options.  You can use either one interface and 6 GPIO pins, or 3 interfaces and 3 GPIO pins.  If a higher data rate is neede from each sensor, multiple buses might be the way to go.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Sat. Mar 31, 2018 - 02:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the suggestions.

I did not mean to disparage TWI- it's clearly a well used and well regarded interface. In fact, the physical layer is pretty straightforward, it's really the Atmel TWI engine that's confusing, at least to me, guess I need to set my 'smart mode' bit. I am now slogging through the app notes & paying dues to get familiar with TWI. The multi-drop issue is moot for me as pointed out clearly in RL's post. I'm just annoyed that I have to learn the TWI ropes just to do an evaluation of a sensor that I might not even use. On the plus side it will be valuable to have the expertise for future projects.

 

The evaluation board would be the path of least resistance, but I would probably go the Arduino route as the boards are pretty cheap, and the program can apparently just be downloaded to the target to start displaying distance measurements. Still would have the ATMEGA to XMEGA TWI translation to do if I were to use a TWI sensor.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

In an ideal world you would have address select pins.   Then multiple VL53L0 devices could sit on the same bus.   Much like small AT24Cxxx devices do.

 

I would guess that the /INT pin could be open drain.   You could share a single pin.    Poll for activity.

This would mean N slaves require SDA, SCL, /INT, + N XSHUT pins.  e.g. 7 GPIO for 4 slaves

 

Individual /INT pins would be SDA, SCL, + N INT, + N XSHUT pins.  e.g. 10 GPIO for 4 slaves

 

Using separate I2C buses could mean you can wire all the XSHUT pins to one GPIO.

Separate buses would be N SDA, N SCL, N INT, XSHUT e.g. 13 GPIO for 4 slaves.

 

We only know that it is an 128A1U which has plenty of I2C buses and plenty of GPIO.

 

I find it unnatural to use separate buses.   But if the Xmega hardware supports this,   goforit.

You get immediate identification of the interrupt.

 

I still reckon that hardware addressing would have been nice.   2 address pins support 4 devices.  e.g. 4 GPIO with polled INT.  7 with hardware INT.

 

David.

Last Edited: Sat. Mar 31, 2018 - 03:01 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Interestingly, this just appeared in my inbox:

 

Tindie wrote:
VL53L1 long-range proximity sensor

Four metre range using time-of-flight range estimation independent of surface reflectivity!

Designed by Pesky Products (Danville, United States) 

 

$18.95 (£13.47 GBP)

 

VL53L1 long-range proximity sensor 1

 

https://www.tindie.com/products/...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Tindie, another candidate. Looks like another ST variant.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

After about a week of fooling with examples, forum code, data sheets, and tutorials, I finally got the VL53L0x sensor to respond via TWI. None of the examples worked, and Atmel's app note also failed to work. The trouble seems to be that none of the examples work with the particular device I am trying to use. In desperation I finally rolled my own bit-bang interface, which after a few hours of issues with timing, bit shifts, and pin state finally began working. After all this it looks like the VL53L0X is not usable. Test readings:

 

dist count  inch

=== ========

2   121  4.75

4   172  6.77

6   216  8.50

8   247  9.72

10 272  10.71

12 286  11.26

14 292  11.50

16 291  11.46

18 265  10.43

dist is actual distance in inches, count is raw count from sensor (in mm), inch=converted to inches. Readings are averaged over 8 reads.

 

Either I am doing something wrong or this device is junk, both wildly inaccurate and non-linear.

 

Next up, the Parallax laser/camera triangulator,  and click board ultrasonic units. After the VL53 fiasco the Parallax will be a dream, simple ttl serial, total of about 8 commands. Film at 11

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Note that you can handle multiple devices with the same address using an I2C port expander. It then becomes almost trivial.  You write to the expander to enable one of the N ports. Then you read and write the device on that expander port. You then write to the expander to change to a different port, then repeat the identical read/write process.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the suggestion, Jim. I am hoping to use a sensor with a non-I2C interface, like PWM or serial. Should I be forced to use I2C I think I would go ahead and bite the bullet and figure out how to shuffle the sensor addresses around by selectively shutting off all but one, and re-setting its address, repeat for all but one of the sensors (that one can use the default address). Plenty of port pins for the shutdown line, and I can still use M8 5-wire cables to the sensors (unless I'm leaving out a line like I did earlier...)