cancel
Showing results for 
Search instead for 
Did you mean: 

VL53L3CX measurement never ready

k1ra
Associate

I've been trying to get my VL53L3CX to communicate with my ESP32-S3. I'm using esp-idf and ported https://github.com/stm32duino/VL53L3CX by rewriting the I2C and GPIO code for esp-idf. As far as I can tell, I'm successfully communicating with the VL53L3CX. I used the following code to confirm that I2C communication is working properly:

 

 

 

 

int VL53LX::rd_write_verification(VL53LX_Dev_t *dev, uint16_t addr, uint32_t expected_value)
{
  VL53LX_Error Status = VL53LX_ERROR_NONE;
  uint8_t bytes[4], mbytes[4];
  uint16_t words[2];
  uint32_t dword;
  int i;
  VL53LX_ReadMulti(dev, addr, mbytes, 4);
  for (i = 0; i < 4; i++)
  {
    VL53LX_RdByte(dev, addr + i, &bytes[i]);
  }
  for (i = 0; i < 2; i++)
  {
    VL53LX_RdWord(dev, addr + i * 2, &words[i]);
  }
  Status = VL53LX_RdDWord(dev, addr, &dword);

  printf("expected   = %8x,\n", expected_value);
  printf("read_multi = %2x, %2x, %2x, %2x\n", mbytes[0], mbytes[1], mbytes[2], mbytes[3]);
  printf("read_bytes = %2x, %2x, %2x, %2x\n", bytes[0], bytes[1], bytes[2], bytes[3]);
  printf("read words = %4x, %4x\n", words[0], words[1]);
  printf("read dword = %8x\n", dword);

  if ((mbytes[0] << 24 | mbytes[1] << 16 | mbytes[2] << 8 | mbytes[3]) != expected_value)
    return (-1);
  if ((bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]) != expected_value)
    return (-1);
  if ((words[0] << 16 | words[1]) != expected_value)
    return (-1);
  if (dword != expected_value)
    return (-1);
  return Status;
}

#define REG 0x3A
void VL53LX::i2c_test()
{
  VL53LX_Error Status = VL53LX_ERROR_NONE;
  int err_count = 0;
  uint8_t buff[4] = {0x11, 0x22, 0x33, 0x44};
  uint8_t long_out[135] = {0x29, 0x02, 0x10, 0x00, 0x22, 0xBC, 0xCC, 0x81, 0x80, 0x07, 0x16, 0x00, 0xFF, 0xFD,
                           0xF7, 0xDE, 0xFF, 0x0F, 0x00, 0x15, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                           0x44, 0x00, 0x2C, 0x00, 0x11, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                           0x00, 0x11, 0x02, 0x00, 0x02, 0x08, 0x00, 0x08, 0x10, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF,
                           0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0B, 0x00, 0x00, 0x02, 0x14, 0x21, 0x00, 0x00,
                           0x02, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x38, 0xFF, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00,
                           0x9D, 0x07, 0x00, 0xD2, 0x05, 0x01, 0x68, 0x00, 0xC0, 0x08, 0x38, 0x00, 0x00, 0x00, 0x00, 0x03,
                           0xB6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x05, 0x06, 0x06, 0x01, 0x00, 0x02,
                           0xC7, 0xFF, 0x8B, 0x00, 0x00, 0x00, 0x01, 0x01, 0x40};
  uint8_t long_in[135] = {0xff};
  int i = 0;

  printf("Chip ID\n");
  Status = rd_write_verification(Dev, 0x10f, 0xeaaa10ff); // verify the Chip ID works

  printf("WriteMultiLongOut\n");
  Status += VL53LX_WriteMulti(Dev, 0x01, long_out, 135); // check if WriteMulti can write 135 bytes

  printf("ReadMultiLongIn\n");
  Status += VL53LX_ReadMulti(Dev, 0x01, long_in, 135); // check if WriteMulti can read 135 bytes

  for (i = 0; i < 135; i++)
    if (long_in[i] != long_out[i])
      err_count++;
  if (err_count > 10)
    Status++;

  printf("WriteMulti\n");
  Status += VL53LX_WriteMulti(Dev, REG, buff, 4); // check WriteMulti
  if (rd_write_verification(Dev, REG, 0x11223344) < 0)
    err_count++;

  printf("WriteDWord\n");
  Status += VL53LX_WrDWord(Dev, REG, 0xffeeddcc); // check WrDWord
  if (rd_write_verification(Dev, REG, 0xffeeddcc) < 0)
    err_count++;

  printf("WriteWord\n");
  Status += VL53LX_WrWord(Dev, REG, 0x5566); // check WrWord
  Status += VL53LX_WrWord(Dev, REG + 2, 0x7788);
  if (rd_write_verification(Dev, REG, 0x55667788) < 0)
    err_count++;

  printf("WriteByte\n");
  for (i = 0; i < 4; i++)
  {
    VL53LX_WrByte(Dev, REG + i, buff[i]);
  }
  if (rd_write_verification(Dev, REG, 0x11223344) < 0)
    Status++;
  if (Status > 0)
  {
    printf("i2c test failed - please check it. Status = %d\n", Status);
  }
}

 

 

 

 

I got the following output :

 

 

 

 

Chip ID
expected   = eaaa10ff,
read_multi = ea, aa, 10, ff
read_bytes = ea, aa, 10, ff
read words = eaaa, 10ff
read dword = eaaa10ff
WriteMultiLongOut
ReadMultiLongIn
WriteMulti
expected   = 11223344,
read_multi = 11, 22, 33, 44
read_bytes = 11, 22, 33, 44
read words = 1122, 3344
read dword = 11223344
WriteDWord
expected   = ffeeddcc,
read_multi = ff, ee, dd, cc
read_bytes = ff, ee, dd, cc
read words = ffee, ddcc
read dword = ffeeddcc
WriteWord
expected   = 55667788,
read_multi = 55, 66, 77, 88
read_bytes = 55, 66, 77, 88
read words = 5566, 7788
read dword = 55667788
WriteByte
expected   = 11223344,
read_multi = 11, 22, 33, 44
read_bytes = 11, 22, 33, 44
read words = 1122, 3344
read dword = 11223344
␛[0;32mI (4684) VL53LX: Setup complete␛[0m
VL53LX Satellite: Count=0, #Objs=0 
␛[0;32mI (5684) VL53LX: WAITING - UID 5900083940140852421␛[0m

 

 

 

 

 

 

I'm using the following code to set up and poll the VL53L3CX (I'm not using interrupts, GPIO1 is left unconnected)

 

 

 

 

VL53LX vl53lxInstance(37);
VL53LX_Error error = VL53LX_ERROR_NONE;

vl53lxInstance.begin();
vl53lxInstance.VL53LX_Off();
error = vl53lxInstance.InitSensor(0x52);
assert(error == VL53LX_ERROR_NONE);
error = vl53lxInstance.VL53LX_StartMeasurement();

assert(error == VL53LX_ERROR_NONE);
ESP_LOGI("VL53LX", "Setup complete");

while (true)
{
        VL53LX_MultiRangingData_t MultiRangingData;
        VL53LX_MultiRangingData_t *pMultiRangingData = &MultiRangingData;
        int no_of_object_found = 0, j;
        char report[64];
        int status;

        vl53lxInstance.VL53LX_WaitMeasurementDataReady();

        status = vl53lxInstance.VL53LX_GetMultiRangingData(pMultiRangingData);
        no_of_object_found = pMultiRangingData->NumberOfObjectsFound;
        snprintf(report, sizeof(report), "VL53LX Satellite: Count=%d, #Objs=%1d ", pMultiRangingData->StreamCount, no_of_object_found);
        printf(report);
        for (j = 0; j < no_of_object_found; j++)
        {
            if (j != 0)
                printf("\r\n                               ");
            printf("status=");
            printf(std::to_string(pMultiRangingData->RangeData[j].RangeStatus).c_str());
            printf(", D=");
            printf(std::to_string(pMultiRangingData->RangeData[j].RangeMilliMeter).c_str());
            printf("mm");
            printf(", Signal=");
            printf(std::to_string((float)pMultiRangingData->RangeData[j].SignalRateRtnMegaCps / 65536.0).c_str());
            printf(" Mcps, Ambient=");
            printf(std::to_string((float)pMultiRangingData->RangeData[j].AmbientRateRtnMegaCps / 65536.0).c_str());
            printf(" Mcps");
        }
        printf("\n");
        if (status == 0)
        {
            status = vl53lxInstance.VL53LX_ClearInterruptAndStartMeasurement();
        }
        vTaskDelay(DELAY_MS / portTICK_PERIOD_MS);

        uint64_t uid;
        vl53lxInstance.VL53LX_GetUID(&uid);
        ESP_LOGI("VL53LX", "WAITING - UID %s", std::to_string(uid).c_str());
}

 

 

 

 

It seems like the VL53LX_StartMeasurement() in the setup returns an empty measurement that is ready and gets printed.

Then, it seems like after VL53LX_ClearInterruptAndStartMeasurement() gets called and the loop, on its 2nd iteration, arrives at VL53LX_WaitMeasurementDataReady(), it waits forever and no new measurement becomes ready. I've confirmed that while VL53LX_WaitMeasurementDataReady() is blocking the thread, there is continuous reading traffic on the I2C bus, so the ESP32 seems to be continuously polling the VL53L3CX but for some reason, the measurement data is never ready.

 

Any help would be appreciated. Am I doing something wrong here?

The sensor is brand new straight off a reel, do I need to calibrate it before first use?

0 REPLIES 0