VL53L1X and a particle electron - how to make them sing?

I’m trying to get the the particle electron to use the vl53l1x time-of-flight range sensor at the most basic level (programming the pinouts and connecting the wires).

Link for the sensor

Link to sensor wiki

Link for the library I’m trying to use is in that wiki page at the bottom under
"Demo Code" “Arduino”

SparkFun similar sensor

I/O:

    Pin	    Direction   Color       Description
    -------------------------------------------------------------------------------
    VCC 	   In        Red        Power
    GND	       In        Black      Ground
    SDA	       In        Blue       Data
    SCL	       In        Yellow     Clock
    SHUT	   Out       Orange     Shutdown, can be pulled low to put the IC in shutdown mode
    INT	       In        Green      Interrupt, goes low when data is ready

So: What should be done with everything not red or black?
SDA --> D0
SCL --> D1
SHUT --> D2
INT --> D3

int lidarSDA = D0;
int lidarSCL = D1;
int lidarSHUT = D2;
int lidarINT = D3;

void setup() {
pinMode(lidarSDA, in);
pinMode(lidarSCL, in);
pinMode(lidarSHUT, out);
pinMode(lidarINT, in);
}

I dont currently have any plans other than basic reading… so nothing to do with anything outside the data line (SDA). Is that going to work or must I manipulate the other I/Os regardless?

Also, from SDA I’m anticipating getting a digital integer value equal to the distance read in centimeters, is that right?

First thing to try would be searching this forum for said sensor.

Pololu provides two arduino libraries that work well with this sensor. I tried them both and finally opted to use the simpler arduino one. It provides basic features in an easy to use api. You need to connect sda/scl obviously, and if using just one sensor no need to connect xshut pin.

Wish you would have given benefit of the doubt there… your comment comes across as dismissive and condescending - hope it wasn’t meant that way… but since it wasn’t followed up with a helpful link or information - it doesn’t leave a lot of room for any benevolence.

Posting is generally my last resort. I did search this forum and came across issues with the webIDE and Libraries and a long post on the previous model vl53l0x. I did see the link with the photon which boiled down to not using the library for the vl53l0x for the vl53l1x…He instead used sparkfun but that library (IIRC) talked about using their qwiik connect thingy. What I didn’t see specifically was the clear answer to what I just asked above. When you’re a n00b the slightest thing can really set you back. I thought by offering up a question with a stab at the answer in a well formatted easy to read way - I could both avoid the accusation that I was being lazy and also provide a post useful to the next n00b with the same question. I spent over 10 hours yesterday just trying to writing code and researching to get this simple device to work… I’m done with everything except the pin statements (and all the other code compiles).

Thank you.

  1. I will be using 2 eventually so the SHUT pin should then be used to shut off one sensor while the other is reading to avoid interference I take it?

  2. I expect INT to be totally optional if you are not interested in a stored measurement (rather just getting measurements when/only your code initiates for them)?

  3. Not sure how I glossed over it but clearly the range is output in mm not cm.

  4. I think perhaps the crux of my initial question is that I don’t understand the setup/interface between the hardware and software. for instance (from the arduino library you linked VL53L1X.h lines 1292-1294:

    void startContinuous(uint32_t period_ms);
    void stopContinuous();
    uint16_t read(bool blocking = true);

How do you make the pin assignments line up with the read function? IOW, How does this “read” function know where the SDA pin is if you don’t pass it in, i.e. “read(pinForSDA);”

And the SCL - what do I have to do with that in terms of a pin assignment?

Before, I was using an analog ouput lidar - so you would tell it analogread(lidarOutputPin); so I anticipated this thing would look something like digitalread(SDApin);
I can understand the function reduction to read but not the exclusion of the place to read from

  1. using XSHUT to enable sensors one by one and change their I2C address turned out to be more difficult than what I expected coming from VL53L0X sensors. I realized after some time that the VL53L1X sensor retains the address change unless it’s powered off. Just keep that in mind when doing your debugging. I wrote a code that can re-assign the I2C address in any case and I can share it later if requested.

  2. i didn’t connect or use the INT pin. I’m just reading the sensors data on a periodic basis.

  3. that’s the default for all libraries I’ve seen

  4. when you call the init() function in your setup(), the default I2C instance that uses default I2C pins (D0 & D1) is initialized.
    The minimal code should look like this:

#define XSHUT_FL        A2
Pololu_VL53L1X distSensorFL;
uint32_t FL_distance; //in mm

void setup(void) {
...
    // next four lines are optional and only required if using more than 1 sensor
    pinMode(XSHUT_FL, OUTPUT); // disable the sensor by setting its XSHUT low
    digitalWrite(XSHUT_FL, LOW);
    delay(50);
    pinMode(XSHUT_FL, INPUT); // enable the sensor by not applying any level on XSHUT
    // 
    delay(10);
    Wire.begin(); // if not  already called earlier in the code
    distSensorFL.init();
    distSensorFL.setAddress(0x31); //optional, required only if using more than 1 sensor
    distSensorFL.startContinuous(continuous_time_interval_ms);

} 

void loop () {
...
// every continuous_time_interval_ms milliseconds or more, you can retrieve the distance in mm (and other status flags) this way:
FL_distance = distSensorFL.readRangeContinuousMillimeters();
...
2 Likes

Thank you for that response, again!

Oh :hushed:
So… things I didn’t know:

  1. The SCL and SDA labels aren’t just for the sensor - they are labeled that way as part of a convention (the I2C convention?). The Particle uses this convention as well (as I presume Arduino and others do too) and the
    Electron Pin Map show this explicitly for pin pairs (D0, D1) and (C4, C5). (BTW, the (SDA --> D0),(SCL --> D1) found in my first post was nothing but dumb luck, I had no idea what I2C was)
    Is it the case then that a single electron then can only support up to two of these devices because it has only has 2 pairs of these I2C ports?
    -XOR- Could other pins also be configured to support these devices?

  2. What should I have done to determine how to use the files (VL53L1X.h, VL53L1X.cpp) to determine how to configure the device pins?

2a. (note the files were are using here are written for an Arduino not a Particle, are they essentially interchangeable in terms of using code on them so long as the pins are assigned properly to the platform?)

  1. Why did you choose A2 for SHUT?
  • The Electron Pin Map shows pin A2 is an ADC (Analog-to-Digital) input pin as well as (SPI) SS (SPI communication pin). Is it the case that analog/digital input/output don’t really matter in this case simply because the SHUT function only senses presence/absence of voltage on that pin and basically any pin can be written high or low?

1- I2C is a bus, you can connect up to 127 devices (or close to that) as long as they have different addresses. Since VL53L1X (and VL53L0X) are configured to respond at address 0x29 when powered on, you’ll need to change that address by issuing the suitable command (while using default address 0x29, hence you can do it with one device enabled at a time) if you plan to use more that one sensor on the same bus.
Now, for the Electron, it has two I2C peripherals, meaning that you can attach 2 sensors to different buses (I2C: D0/D1 and I2C1: C5/C4, see here, and use the sensors at their default address separately on each I2C buses. Of course that’s for max 2 range sensors.

2- if you plan to use I2C bus, nothing to be done, just include the file. If you’re also using I2C1 bus, an easy way is to duplicate these 2 files and then replace Wire by Wire1 in the new pair of files.

3- I was using a Xenon and the other digital IOs where attached to other peripherals. You can configure “analog” pins to be digital in/out with pinMode(). Again, the docs are very helpful to figure all this out

2a- I’m not sure if you can use as is. To be on the safe side, add:

#if defined(PARTICLE)
#include "application.h"
#endif

at the beginning of the header file.

2 Likes

Fantastic. Thank you for all the help.

I am starting to get a handle on all this… everything about it is new to me so I am trudging through the basics (C, C++, github, vscode, JSON, javascript, electronics, terminology, you name it) - I couldn’t even write a functioning makefile so I could compile on my local machine via the Particle workbench - nor could I get it’s built in terminal to flash my device - had to do both via the webIDE and CLI.

In general it’s sad when you are staring at the right answer in documentation or board posts or wherever - but don’t know enough to know that you are… but that’s just what it is sometimes.

I got it up and running - it’s not quite as sensitive as I had expected/hoped. I think it has a lot to do with the background MCPS due to ambient light - I’ll find out soon when I get it spitting out reports that include the quality of measurement parameters… it has to work in all outdoor lighting conditions. I am going to build a housing for it and use some IR plexiglass that I found for it - it’s dark and should help shield out interfering light. I am also going to checkout the separator glass cover they discuss on the manufacture website… I of course also need to get in and tease out calibration coding.

Thanks again for taking the time to answer my questions.

1 Like

Background lighting really screws up the sensors abilities.

It will measure snow and rain dropping in front of it also.

There is a thread on here about this sensor I started last year or so with more info about this sensor.

Yes I saw your conversation and read the whole thread… I got a “reader” award for it because it was over 100 posts!!

I have read most of the technical documents from the manufacturer - they did a good job reporting everything. Certainly not much I can do about atmospheric conditions… though humidity and rain will be a common occurrence. I think once I get the sensor working properly (or as best it can) in the sunshine (and in general with calibration and the like) I’ll move on to working with unfavorable atmospheric conditions in a statistical fashion in the code.

Did anyone ever figure out the “cover glass” supplier that the manufacturer mentioned in their video here In documentation it mentions Hornix… but not for the version that he uses. Questions were posted on their website with no useful answers and hornix website doesn’t have anything listed. At minimum, my plan is to use their free stp file and not insert IR glass but instead use a plexiglass IR cover an inch or so away - we’ll see how it works.

2 Likes

You should not be needing to come up with your own makefile in Workbench as long all source files are organised the way Workbench expects them to be organised.
Granted, there isn't good documentation for that yet :blush:

If you are using libraries you need to have them in a dedicated subfolder in lib which carries the name of the library, contains a library.properties file and a src folder in which the sources are placed (this can contain subfolders too) - there should not be any examples in the library folder.

I created a new project via Particle: Create New Project and placed the files of the library repo in it as seen bellow.
If your project folder looks like this, then Workbench should be able to locally compile it

C:.
│   project.properties
│   README.md
│   VL53L1X_Test.code-workspace
│
├───.vscode
│       launch.json
│       settings.json
│
├───lib
│   └───VL53L1X
│       │   library.properties
│       │
│       └───src
│               VL53L1X.cpp
│               VL53L1X.h
│
└───src
        VL53L1X_Test.ino

Sorry for the bad start :pensive:
Having read 145K+ posts and answered 15K+ of which hundreds were actually just reiterating the same thing over and over because many people don't seem to search or read the docs first I just assumed wrong that your OP was one of these again.
Sorry for jamming you into the same category and glad to know you are one of the positive exceptions :+1:

3 Likes

I am going to go ahead and preen the folder substructure as you posted and try again on the local compile. The way it sits now the the Particle.cloudCompile works.

The workbench local terminal (PowerShell) particle flash --serial file.ino command does not work - although it seems to come close.

No worries - I know where you are coming from and I still eagerly look forward to reading replies from ScruffR when they come in. I have to risk looking stupid and being annoying so I can learn. It is hard to make myself look different than folks who don’t try and do their due diligence homework first because I cannot feign knowledge that I do not have. At minimum, I’m trying to leave a trail behind me that is useful to others (with code snips, links, lesson learned summaries, well organized, etc.). Perhaps someday I’ll be able to pay it forward… but for now I’m basically a vacuous pit of seemingly endless need. :hole:

1 Like

I understand the confusion.
particle flash --serial can only flash binaries (which after a local compile will be located in the target folder).
You can run particle flash <deviceID> file.ino since that will first initiate a cloud build and then OTA flashing of the resulting binary.
I also prefer the DFU Mode flashing via particle flash --usb firmware.bin -v syntax as it provides more info about the success of the command (you can also the -v verbose switch with many other commands).

2 Likes