VL53L1X ST API, Device Handles

VL53L1X ST API sets device handles as:

VL53L1_Dev_t              dev
VL53L1_DEV                Dev = &dev

How does one write this for multiple devices?

Thank You,
Randy

Hi, Randy.

You should be able to simply declare another copy of each variable for each sensor:

VL53L1_Dev_t                   dev1;
VL53L1_DEV                     Dev1 = &dev1;

VL53L1_Dev_t                   dev2;
VL53L1_DEV                     Dev2 = &dev2;

(Note that the VL53L1_Dev_t objects are the ones that actually represent the sensors; the VL53L1_DEV objects are just pointers for convenience, so you could omit them and replace Dev1 with &dev1 everywhere.)

Kevin

Thanks Kevin,

I had it written as:

VL53L1_Dev_t    devfwd, devrgt, devrwr, devlft; //  Actual Sensor
VL53L1_DEV      DevFWD = &devfwd, DevRGT = &devrgt, DevRWR = &devrwr, DevLFT = &devlft; //  Pointer

Either way may work I don’t know yet because that’s apparently not the problem.

Problem must be in address assignment, this is the code for the first two sensors:

//  FLIR Sensor ShutDown
  pinMode(22, OUTPUT);  //  Pin 22 - PA0 Port A Bit 0;  flirFWD_XSHUT, Xshutdown pin active LOW
  pinMode(23, OUTPUT);  //  Pin 23 - PA1 Port A Bit 1
  pinMode(24, OUTPUT);  //  Pin 24 - PA2 Port A Bit 2
  pinMode(25, OUTPUT);  //  Pin 25 - PA3 Port A Bit 3
 
  Wire.begin();
  Wire.setClock(400000);
  Serial.begin(115200);

  //  Set FLIR Addresses
  digitalWrite(22, LOW);   //  Pin 22 - PA0 Port A Bit 0; flirFWD_XSHUT LOW = hardware standby
  digitalWrite(23, HIGH);  //  Pin 23 - PA1 Port A Bit 1; flirRGT_XSHUT HIGH = enable the sensor
  digitalWrite(24, HIGH);  //  Pin 24 - PA2 Port A Bit 2; flirRWR_XSHUT
  digitalWrite(25, HIGH);  //  Pin 25 - PA3 Port A Bit 3; flirLFT_XSHUT
  
  //  ---------------DevFWD-----------------

  DevFWD->I2cDevAddr = 0x52;
  delay(50);
  digitalWrite(22, HIGH); //  enable the sensor
  delay(50);
  
  status = VL53L1_WaitDeviceBooted(DevFWD);  //  function ensures that the device is booted and ready <= 4ms.
  status = VL53L1_DataInit(DevFWD);          // performs device initialization. It is called once and only once after the device is brought out of reset.
  status = VL53L1_StaticInit(DevFWD);        // function allows loading of the device settings that are specific for a given use case.

  status = VL53L1_SetDistanceMode(DevFWD, VL53L1_DISTANCEMODE_LONG);
  status = VL53L1_SetMeasurementTimingBudgetMicroSeconds(DevFWD, 20000);
  status = VL53L1_SetInterMeasurementPeriodMilliSeconds(DevFWD, 1000);
  status = VL53L1_SetXTalkCompensationEnable(DevFWD, 0);
  delay(200);
  
  //  ---------------DevRGT-----------------

  digitalWrite(23, LOW);  //  hardware standby
  delay(50);
  DevRGT->I2cDevAddr = 0x54;
  delay(50);
  digitalWrite(23, HIGH); //  enable the sensor
  delay(50);

  status = VL53L1_WaitDeviceBooted(DevRGT);  //  function ensures that the device is booted and ready <= 4ms.
  status = VL53L1_DataInit(DevRGT);          // performs device initialization. It is called once and only once after the device is brought out of reset.
  status = VL53L1_StaticInit(DevRGT);        // function allows loading of the device settings that are specific for a given use case.

  status = VL53L1_SetDistanceMode(DevRGT, VL53L1_DISTANCEMODE_LONG);
  status = VL53L1_SetMeasurementTimingBudgetMicroSeconds(DevRGT, 20000);
  status = VL53L1_SetInterMeasurementPeriodMilliSeconds(DevRGT, 1000);
  status = VL53L1_SetXTalkCompensationEnable(DevRGT, 0);
  delay(200);

I have also tried setting the address after Data and Static Init, but that doesn’t seem to work either? (I realize that I’m setting the Forward Devices’ address to its default, this is for clarity and will be cleaned up after the code is working).

Thanks,
Randy

I think there are a few problems with your code. First, if you are using our carrier board with a 5V Arduino, note that the XSHUT pin is not level-shifted and not 5V tolerant, so you should never drive it high. Instead, you can alternate between driving the pin low and setting the pin to an input to let the on-board pull-up resistor pull it up to 3.3V. (It is fine to drive XSHUT high if you are using a 3.3V Arduino.)

Second, your general approach for initializing multiple sensors is not right. The idea is to enable one sensor at a time and tell the newly enabled sensor (which starts off listening at the default address) to change to a different address so that you can subsequently bring up another sensor at the default address. (You are starting with 3 of the 4 sensors enabled, which will not work.)

Furthermore, I believe you have to use the function VL53L1_SetDeviceAddress() to change the address (this is what actually sends the I2C command to the sensor to tell it to change its address) and you have to do this after enabling the sensor, not while putting it in standby. I think you do also need to change I2cDevAddr to match, but you should do this immediately after calling VL53L1_SetDeviceAddress().

Kevin

Excellent explanation Kevin, as usual…

I really don’t know where that bit of code came from, had it in my program for a year or so (commented out) because I knew I would need it later.

See if this looks better… Had to edit, I think it’s right now.

//  FLIR XSHUT pins, XSHUT pin active LOW
  pinMode(22, OUTPUT);  //  Pin 22 - PA0 Port A Bit 0
  pinMode(23, OUTPUT);  //  Pin 23 - PA1 Port A Bit 1
  pinMode(24, OUTPUT);  //  Pin 24 - PA2 Port A Bit 2
  pinMode(25, OUTPUT);  //  Pin 25 - PA3 Port A Bit 3

  Wire.begin();
  Wire.setClock(400000);
  Serial.begin(115200);

  //  Set FLIR XSHUT pins LOW = hardware standby
  digitalWrite(22, LOW);  //  Pin 22 - PA0 Port A Bit 0; flirFWD_XSHUT
  digitalWrite(23, LOW);  //  Pin 23 - PA1 Port A Bit 1; flirRGT_XSHUT
  digitalWrite(24, LOW);  //  Pin 24 - PA2 Port A Bit 2; flirRWR_XSHUT
  digitalWrite(25, LOW);  //  Pin 25 - PA3 Port A Bit 3; flirLFT_XSHUT

  //  ---------------DevFWD-----------------

pinMode(22, INPUT);  //  flirFWD XSHUT pin, float to enable sensor
  delay(50);
  /*  Sensor default address is 0x52, so this is not necessary here but,
   *   is necessary on each successive device
  status = VL53L1_SetDeviceAddress(DevFWD, 0x52); //  set devices' slave address
  delay(50);
  */
  DevFWD->I2cDevAddr = 0x52;  //  set master address for µC
  delay(50);

  status = VL53L1_WaitDeviceBooted(DevFWD);  //  function ensures that the device is booted and ready <= 4ms.
  status = VL53L1_DataInit(DevFWD);          // performs device initialization. It is called once and only once after the device is brought out of reset.
  status = VL53L1_StaticInit(DevFWD);        // function allows loading of the device settings that are specific for a given use case.

  status = VL53L1_SetDistanceMode(DevFWD, VL53L1_DISTANCEMODE_LONG);
  status = VL53L1_SetMeasurementTimingBudgetMicroSeconds(DevFWD, 20000);
  status = VL53L1_SetInterMeasurementPeriodMilliSeconds(DevFWD, 1000);
  status = VL53L1_SetXTalkCompensationEnable(DevFWD, 0);
  delay(200);

  //  ---------------DevRGT-----------------

  pinMode(23, INPUT);  //  flirRGT XSHUT pin, float to enable sensor
  delay(50);
  DevRGT->I2cDevAddr = 0x52;  //  set master address for µC
  delay(50);
  status = VL53L1_SetDeviceAddress(DevRGT, 0x54); //  DevRGT
  delay(50);
  DevRGT->I2cDevAddr = 0x54;  //  set address for µC
  delay(50);

  status = VL53L1_WaitDeviceBooted(DevRGT);  //  function ensures that the device is booted and ready <= 4ms.
  status = VL53L1_DataInit(DevRGT);          // performs device initialization. It is called once and only once after the device is brought out of reset.
  status = VL53L1_StaticInit(DevRGT);        // function allows loading of the device settings that are specific for a given use case.

  status = VL53L1_SetDistanceMode(DevRGT, VL53L1_DISTANCEMODE_LONG);
  status = VL53L1_SetMeasurementTimingBudgetMicroSeconds(DevRGT, 20000);
  status = VL53L1_SetInterMeasurementPeriodMilliSeconds(DevRGT, 1000);
  status = VL53L1_SetXTalkCompensationEnable(DevRGT, 0);
  delay(200);

Thanks again,
Randy

That looks mostly okay, except whenever you use more than one sensor, only the last one you enable can be left at its default address. This is because each one comes out of standby with the default address of 0x52, so if you try to leave the first one at 0x52 and then enable the second one, you will have two sensors listening at 0x52. Therefore, you should edit your code to change the first sensor’s address instead.

(By the way, I have also read a recommendation to also change the last sensor’s address to not be the default; that way, if something happens and a sensor gets reset accidentally, you will know because it will reset to the default address.)

Kevin

Right, I can’t believe I didn’t see that?

The Good News:
All 4 sensors are online and running. :joy:
The sensors don’t seem to have been damaged by 5V (4.35V) on XSHUT? :astonished:

Thanks a bunch,
Randy

1 Like