Shop OBEX P1 Docs P2 Docs Learn Events
Driver for SparkFun VL6180 ToF Range Finder Sensor — Parallax Forums

Driver for SparkFun VL6180 ToF Range Finder Sensor

John AbshierJohn Abshier Posts: 1,116
edited 2015-06-07 02:01 in Accessories
The VL6180 is an IR range sensor that uses Time Of Flight and claims to be more accurate and resistant to noise than sensors that rely on reflected light intensity or reflected angles. Range is 10 to 100mm and perhaps up to 254mm depending on the target. Update rate is 40 to 60Hz. The program is mostly a translation of the Arduino code provided by SparkFun and uses the I2C driver written by Jon "JonnyMac" McPhalen . Lots of work left to do: Read the ambient light sensor, change I2C address to allow multiple sensors on the same I2C bus, perhaps a read multiple sensor command.

Here is the SparkFun product page that has links to documentation: https://www.sparkfun.com/products/12785

John Abshier

Comments

  • John AbshierJohn Abshier Posts: 1,116
    edited 2015-03-10 15:28
    Attached archive adds ambient light measurement in milliLux. I have lost interest in this sensor. The datasheet and comment (probably taken from datasheet) indicate that the I2C address resets to default on power cycle. I was not able to change the I2C address. That limits one to only using one VL6180 per I2C buss. If you only need to use one sensor, this one works and could share SDA, SCL with the EEPROM. Problems encountered during development: I have a dead pin on my Prop BOE. The I2C driver's read word method read the light measurement with bytes reversed.

    John Abshier
  • ErlendErlend Posts: 612
    edited 2015-06-02 12:21
    I have bought two off the Teensy VL6180 break out boards and hooked one up. When I run the VL6180Demo the program gets no further than to the SetupRanger function. Hooking up a scope to the SDA pin there is some activity, but I do not know what is passing through. I have tried with the x52 as well as the x29 address setting.
    Any idea how to get further?

    https://www.tindie.com/products/onehorse/vl6180x-proximity-sensor-via-ir-laser-range-finding/


    Erlend
  • John AbshierJohn Abshier Posts: 1,116
    edited 2015-06-02 13:44
    First, make sure there are pull-ups on SDA and SCL. The I2C driver assumes this.
    Second, make sure that the constants for SDA and SCL in VL6180Demo correspond to the pins you are using.
    Third, make sure grounds are connected.
    Fourth, check the return value from SetupRanger method. The demo program doesn't do this.

    John Abshier
  • ErlendErlend Posts: 612
    edited 2015-06-02 14:24
    Check. Check. Check.

    The SetupRange never returns it seems.
    pub main | reply  ,i
    
      waitcnt(clkfreq * 2 + cnt)
      term.start(RX1, TX1, %0000, 115_200)                          ' start terminal I/O
      term.rxflush                                                   ' wait open terminal & keypress
      term.rx
      term.tx(CLS)                                                        
      term.str(string("Starting test",CR))
      Rng.SetupI2cBus(SCL, SDA)
      term.str(string("I2C bus set up",CR))
      reply:= Rng.SetupRanger(I2C_ADDR)
      term.str(string("Ranger set up returns",CR))
      term.dec(reply)
      repeat
         term.tx(CR)
         term.str(string("Range (mm) "))
         reply := Rng.GetSingleRange(I2C_ADDR)
         term.dec(reply)
         term.tx(TAB)
         term.str(string("Light level (milli Lux) "))
         reply := Rng.GetSingleAmbientLight(I2C_ADDR, Rng#ALS_GAIN1)
         term.dec(reply)
         waitcnt(clkfreq * 2 + cnt) 
    
    - never gets beyond "I2C bus set up"

    Frustrating. And I do not own a protocol anlalyzer, so I am a bit blind.

    Erlend
  • John AbshierJohn Abshier Posts: 1,116
    edited 2015-06-03 06:50
    The program will hang where you indicate if the clock line stays low. Put the scope on the clock line to see if it ever goes high.

    John Abshier
  • ErlendErlend Posts: 612
    edited 2015-06-03 09:39
    There is definitely activity on the bus, but I do not know what. I have taken two snapshots of the (single channel) scope and stitched together, supeimposing the SLC over the SDA. Bear in mind, I have guessed on how they overlap in time.
    Looks like someone is trying to read, but get no answer.
    I2Cdebug.jpg


    Erlend
    400 x 645 - 92K
  • John AbshierJohn Abshier Posts: 1,116
    edited 2015-06-03 09:49
    Could you post your complete program as an archive?

    John Abshier
  • ErlendErlend Posts: 612
    edited 2015-06-03 09:56
    I am using the program in post#2 here, unaltered exept for the three debug lines inserted in the terminal dialoge part, as shown in the code I posted #5.

    Erlend
  • ErlendErlend Posts: 612
    edited 2015-06-06 09:43
    I took it apart and wired it up again, and now it works :) I suspect some residual glue on the serial resistors, maybe.

    Agree it is kind of silly that the device does not keep its new adress after power down, it makes it less useful as a bus device. But I am wanting to have 2 or 3 on one bus, and I got the idea that the GPIO0 pin (Reset) which normally is pulled up to V+ can be connected to gnd with a capacitor, and if that capacitor is sized differently for each device, it means that the devices will boot at different times. With an initialization routine that rewrites device address to the first one to boot, then with a time interleave rewrites to the next one to boot, and so on, it should be possible to do a high number of rewrites even within one second. Once done the devices will respond on ther individual addresses. Using a 100k pull up, capacitors with a different multiple of 10nF or so should do the trick I think.

    Erlend
  • John AbshierJohn Abshier Posts: 1,116
    edited 2015-06-06 19:10
    Glad that you got it to work. That is an interesting way to have several on the same bus. Let us know how it works.

    John Abshier
  • ErlendErlend Posts: 612
    edited 2015-06-07 02:01
    Thanks. I am working on how to implement the many-on-the-bus scheme now. First realisation is that the power to all the VL6180 needs to be provided by a propeller pin so that the power-on can be timed. Once power is on it should just be a matter of repeatedly writing a new_address command to the default address until a reply comes in on the new_address, then increment 'new_address' and repeat (n times). When finished all n devices should have, and respond to new addresses. That's the theory, anyway. The VL6180s will share I2C bus with an MCP23017, so first thing I will do is to restructure the methods I have written for that purpose such that the code can be expanded in an orderly fashion.

    Erlend
Sign In or Register to comment.