How to add an option to VL53L0X module

Posted on
of 2
/ 2
  • Hi!
    I want to make tiny modification of VL53L0X module - add an option that means "address is changed already, use new address but do not send address change command to device" - I try to use few VL53L0X thru I2C address changer and one without changer and the address change command will prefer the last one from correct work.
    The code is easy so I can make the modification in local copy. But my JS skills are not good so I think I can not write well-readable code in JS and Espruino tradition.

    How to write it in good style? Well-designed interface is important in the place.
    May be the option will be useful for other modules as well.

    I am going to modify the module further to add features I need - continuous measurement mode etc. And I think I can put the code somewhere - GitHub branch or even here - and somebody who know JS can modify my code to add good JS style.

    By the way, it seems to me, Mongoose OS Pololu VL53L0 code looks to be better for reverse-engineering then original ST.

  • Post the code here or in a github and i will have a look at it and modify it if necessary.

  • Thank you.
    I've just written VCNL4200 module (still not full, but works). Please review it.

    By the way, "Upload a file" does not work in last Firefox. File selection window opens, but nothing happens after I choose file. Where to write about the bug?

    1 Attachment

  • The same after some debug. A few bugs were killed.

    1 Attachment

  • That looks really good to me! If you could add a page with an example in the style of (or other files) it'd be really handy - or if not just paste one here and I'd be happy to make a page up for you.

    Do you have a link to the VL53L0X changes you mentioned as well?

  • The code have at least one problem - bit fields for registers are not shown for module user (or I do not know how to use it). I do not know JS so I do not know how to correct the code. Could you help me?
    I think I can not write description in style of "Writing Modules" because I use own board with a few sensors and do not know about boards available to others. But. of course, I can write code example:

    var i2c=new I2C();
    i2c.setup({ sda:D12, scl:D13} );
    //var sensor = require("VCNL4200").connect(i2c,{address­:0x51}); //0x51 is default address so may be omitted
    var sensor = require("VCNL4200").connect(i2c);
    //sensor.Configure(); //It is possible to use it for some default mode, but it should be investigated what to set as default
    sensor.setProxiConf3MS(0x70,0x27); //0x27 to use INT pin as proximity signal, 0x7 to use INT as interrupt
    function log (){
          " Proximity: " + sensor.getProximity() +
          " Ambient: " + sensor.getAmbient() +
          " White: " + sensor.getWhite() +
          " Int: " + sensor.getInterruptFlags().toString(16))­;
    setInterval(log, 1000);
  • I have just got VL53L0X board, so I have not still working code for the board. I think I would better send modifications after writing some:)

  • I think what you might need is VCNL4200.prototype.ALS = ALS - then you can do:


    if that's what you were asking?

    However I'd strongly advise against that as it will make the module use a lot of memory and isn't very easy for people to use or understand (they basically have to look at the datasheet for everything, and then figure out how to do what the datasheet said using your code).

    Could you maybe try something like:

    // Sets whatever this is, time is 50, 100, 200 or 400 (milliseconds)
    VCNL4200.prototype.setAmbiConf = function ( time ) {
      var times = { 50 : 0, 100 : 64, 200 : 128, 400 : 192 };
      this.w(C.ALS_CONF_REG, [times[time],0]);

    And the same for other functions that expect certain values - so doing the decoding inside the function itself. It's better if the functions actually abstract away from the underlying registers...

  • The register is to set not only the time but a few other parameters as well. So I can write function to set time only, of course. It can get register, then add time and set the register back. But may be it is easier to users to look at the datasheet, isn't it? While the datasheet is not well-understandable, but I do not think adding separate functions or parameters with strange names makes it more understandable.
    So may be it would be better to remove the names from the module. Please do that if you think it will be better in Espruino environment.

  • I am working on VL53L0X module and I have seen a potential holywar: these modules have different semantic of I2C addresses. One uses 7-bit address, as in Linux and in some datasheets while another uses 8-bit shifted address like in some other datasheets.
    Are you going to save current state when different modules have different meaning of I2C address or to change it (may be not just now) to be uniform?

  • It should all be uniform, with 7 bit addresses (like are used for the I2C class at Which ones use shifted addresses? I'll see about changing them.

  • It seems, VL53L0X module. Because the options.address is shifted before use.

  • I am currently looking at the VCNL4200 module from @SergeP as promised. But without a VCNL4200 sensor at hand someone has to check the final version.
    I can look into the module for the VL53L0X soon and i even have a sensor with that chip on the way as we speak.

  • I have just done translation of some part of VL53L0X library to JS. But I can not check it. May be because of small memory on ESP8266 - I am not sure. Or may be there are many bugs there. Could you help me?
    Here is console output after I try to load the module.

     _____                 _
    |   __|___ ___ ___ _ _|_|___ ___
    |   __|_ -| . |  _| | | |   | . |
    |_____|___|  _|_| |___|_|_|_|___|
     1v95.4 Copyright 2017 G.Williams
    Espruino is Open Source. Our work is supported
    only by sales of official boards and donations:
    Flash map 4MB:1024/1024, manuf 0x5e chip 0x4016
    >Uncaught SyntaxError: Got UNFINISHED STRING expected EOF
     at line 1 col 31
    Modules.addCached("VL53L0Xmy","var C={SYSRANGE_START:0,SYSTE...
    New interpreter error: LOW_MEMORY,MEMORY
    Uncaught Error: Module "VL53L0Xmy" not found
     at line 1 col 32
    ...or[0] = require("VL53L0Xmy").connect(i2c,{addres­s:0x52,addre...
    ={ "free": 1496, "usage": 104, "total": 1600, "history": 608,
      "gc": 5, "gctime": 1.99 }
  • Module file. Name is changed during writing because I do not know which module source has priority if names are equal.

    1 Attachment

  • I have found one big bug. Update is here. Result is nearly the same

    1 Attachment

  • Many bugs fixed. Still too big for my current device.
    I try to pass Closure in advanced mode, but do not understand how to preserve I2C functions using some keywords in file comments.

    1 Attachment

  • Now I have version with most bugs fixed which passes Closure minification in advanced mode and works after.
    Unfortunately I do not know if it works without minification - it looks like it is too big for my current device (while I am out of home and so can not use some other device).
    After calibration the sensor is more stable and does not report very small distance when in open space. Also you may use some mode setup functions. It is great for me. But I need also GPIO setup to try switching it to trigger mode, when GPIO turns on if object is too close and turns off when it is far again.
    The module is still big enough even after advanced minification - about 7600 bytes. I can load it only in 'Modules uploaded as functions' mode. In normal mode it results to LOW_MEMORY error.
    I have not still fixed I2C address (it is 8 bit in the module and need to be shifted) while it is easy for me, because I think it is up to @Gordon to change it or leave as is for compatibility. While I think now is good time for the change.
    Also I think it may be interesting to have both modules for the complex sensor - old and new one, because they have different areas of usage. Really I have no good idea what to do with that.

    1 Attachment

  • It was epic battle!
    Nearly impossible for me: I do not know JS, I have never seen Closure compiler before, I have never even heard about it... And 1000 lines of code, which can work only in minificated form... And, of course, bugs, bugs, bugs...
    I am really like an ancient hero!
    Do not only sure, which one - Heracles or Sisyphus :)

  • Thanks! I'll look at shifting the address back.

    Using the closure compiler in advanced mode is a nightmare. Honestly I only ever use 'simple optimisations' (even when minifying modules) because it's so painful :)

    Yes, I guess it might be an idea to have the more complex module as a second one given the difference in size is quite large. Do you have any examples of how to use this new module in its
    various different modes?

    Also, do you know what the difference is between readRangeSingleMillimeters/readRangeCont­inuousMillimeters and the original performSingleMeasurement though? As far as I can tell they're basically identical apart from which registers they wait on, and they return the same data?

    There are so many repeated calls of this.w I think we could probably save a lot of program space by replacing them with one call that takes an array - allowing you to save a lot more space in the ESP8266 - but I'd be happy to do that.

  • I finally had some time to look into the VCNL4200 code. According to the datasheet i found the module should not work.
    You are writing to the command register at 0x80 but i would expect it to be at 0x00. Apart from that and what gordon mentioned about the usability aspect it looks good to me.

    I got my VL53L0X today so i could help work on that if you like.

  • You are writing to the command register at 0x80 but i would expect it to be at 0x00

    Many chips use the top bit of the register address to specify a write to that register - so that could be a reason?

  • Yes that could explain it.. i guess someone with the sensor at hand will find out for us :)

  • Hi! Sorry, I had no time at all before and have too little time now. But I hope tomorrow I will have enough.
    About VCNL4200: I have removed "0x80|addr" in last version of my module from r and r2 funtions, but I am not sure I sent it here. But it works with it and without it. While it is better to remove it to comply documentation.

    About readRangeSingleMillimeters/readRangeCont­inuousMillimeters and the original performSingleMeasurement. Yes, I forget to remove one because had both in my test, and had already not enough time. By the way, both functions looks like can not work if switch GPIO to other modes and I even know why (I did not implement setGPIOMode() still and did it by accessing registers using w2(). Moreover, it was my general goal to test effects of GPIO modes).

  • Hi!
    It seems to me that I use command register at 0x00, it was 0x80 at first version (and it works - may be the chip does not read upper bits) but I have changed it at second one (and it works, too). Or may be I do not see something.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

How to add an option to VL53L0X module

Posted by Avatar for SergeP @SergeP