cancel
Showing results for 
Search instead for 
Did you mean: 

VL53L3CX and ESP32 weird ranging data

PHumm.2
Associate

Hi,

I am using an esp32 to read out the sensor data of a VL53L3CX. I've tried the example code for the distance sensor and slightly modified it by commenting the if statement out which checks if the distance changed to get continiously data:

 

 

#define  XSHUT_PIN  6
#define  INT_PIN    7
#define  SERIAL_BAUD_RATE  115200

#define  DEVICE_I2C_ADDR  0x12
VL53LX vl53lx(&Wire, XSHUT_PIN);

// Holds latest measured distances (up to 4)
#define  MAX_OBJECTS  4
uint16_t dist[MAX_OBJECTS];


//----------------------------------------
// intaISR - Interrupt handler
//----------------------------------------
portMUX_TYPE  syncINTA = portMUX_INITIALIZER_UNLOCKED;        // For handling ISR entry/exit
bool          intaINT  = false;                               // True = Interrupt occured
unsigned long intervalTimer;                                  // Timer used for checking for lost interrupts

void IRAM_ATTR intaISR() {
  portENTER_CRITICAL(&syncINTA);
  intaINT = true;                                             // Signal that MCP INTA occured
  portEXIT_CRITICAL(&syncINTA);
}


void setup()
{
   int i;
   VL53LX_Error rc;
   VL53LX_Version_t ver;
   uint8_t ProductRevisionMajor, ProductRevisionMinor, byteData;
   VL53LX_DeviceInfo_t devInfo;
   uint64_t Uid;

   Serial.begin(SERIAL_BAUD_RATE, SERIAL_8N1);
   while (!Serial);
   delay(5000);
   Serial.println("Starting...");

   // Initialize the array
   for (i=0; i<MAX_OBJECTS; i++)
      dist[i] = 0;

   // Initialize the I2C bus
   Wire.begin(4,5);
   Wire.setClock(400000);

   // Configure the VL53LX
   vl53lx.begin();
   vl53lx.VL53LX_Off();
   vl53lx.InitSensor(DEVICE_I2C_ADDR);

   // Print chip info
   rc = vl53lx.VL53LX_GetVersion(&ver);
   Serial.printf("GetVersion: rc=%d, Build=%d, Major=%d, Minor=%d, Revision=%d\n", rc, ver.build, ver.major, ver.minor, ver.revision);
   rc = vl53lx.VL53LX_GetProductRevision(&ProductRevisionMajor, &ProductRevisionMinor);
   Serial.printf("GetProductRevision: rc=%d, Major=%d, Minor=%d\n", rc, ProductRevisionMajor, ProductRevisionMinor);
   rc = vl53lx.VL53LX_GetDeviceInfo(&devInfo);
   Serial.printf("GetDeviceInfo: rc=%d, ModuleType(0xAA?)=0x%X, ProdRevMajor=%d, ProdRevMinor=%d\n", rc, devInfo.ProductType, devInfo.ProductRevisionMajor, devInfo.ProductRevisionMinor);
   rc = vl53lx.VL53LX_GetUID(&Uid);
   Serial.printf("GetUID: rc=%d, UID=0x%llX\n", rc, Uid);

   // To enable using the below I2CRead function, you need to move its definition in vl53lx_class.h from the Protected section to the Public section
   rc = vl53lx.VL53LX_I2CRead(DEVICE_I2C_ADDR, 0x010F, &byteData, 1);
   Serial.printf("I2CRead 0x010F: rc=%d, Model_ID=0x%02X\n", rc, byteData);
   rc = vl53lx.VL53LX_I2CRead(DEVICE_I2C_ADDR, 0x0110, &byteData, 1);
   Serial.printf("I2CRead 0x0110: rc=%d, Module_Type=0x%02X\n", rc, byteData);

   pinMode(INT_PIN, INPUT_PULLUP);
   attachInterrupt(digitalPinToInterrupt(INT_PIN), intaISR, FALLING);
   intervalTimer = millis();                                            // Set timer

   vl53lx.VL53LX_ClearInterruptAndStartMeasurement();
   Serial.println("Ready...");
}


void loop()
{
   VL53LX_MultiRangingData_t MultiRangingData;
   VL53LX_MultiRangingData_t *rangingData = &MultiRangingData;
   uint8_t NewDataReady = 0;
   int objectsFound = 0, j, status;
   bool dataChanged = false;

   if (intaINT) {

      status = vl53lx.VL53LX_GetMeasurementDataReady(&NewDataReady);
      if (status == 0  &&  NewDataReady != 0) {

         status       = vl53lx.VL53LX_GetMultiRangingData(rangingData);
         objectsFound = rangingData->NumberOfObjectsFound;
         if (objectsFound > 0) {

            for(j = 0; j < objectsFound; j++) {
               // Check only if status is OK
               if (rangingData->RangeData[j].RangeStatus == 0) {
                  // Only consider changes of over 10 mm
                  //if (abs(rangingData->RangeData[j].RangeMilliMeter - dist[j]) > 10) {
                     // Movement happened
                     dist[j] = rangingData->RangeData[j].RangeMilliMeter;
                     dataChanged = true;
                  //}
               }
            }
            // Clear rest of values
            for (j=objectsFound; j < MAX_OBJECTS; j++)
               dist[j] = 0;

            if (dataChanged) {
               dataChanged = false;
               Serial.printf("%d %d %d %d\n", dist[0], dist[1], dist[2], dist[3]);
            }
         }
      }

      intaINT = false;
      vl53lx.VL53LX_ClearInterruptAndStartMeasurement();
      intervalTimer = millis();

   } else {

      // Did we lose an interrupt?

     if ((millis() - intervalTimer) > 2000) {

         Serial.println("Lost interrupt?");
         vl53lx.VL53LX_ClearInterruptAndStartMeasurement();
         intervalTimer = millis();
      }
   }

}

 

 

 

This is my test setup:
 IMG_1667[13579].jpg

 

The output looks like that:

571 0 0 0
584 0 0 0
575 0 0 0
581 0 0 0
578 0 0 0

Which clearly isn't correct. 

1. There is only one object detected. 2. The distance isn't even correct for one of the objects that are ~50cm and 76cm away from the sensor. 

Furthermore i am expecting that it continuously getting data but sometimes it is stuck and then after ~10sec it continues getting data...

My schematic of the PCB looks like that: 

Anmerkung 2024-03-25 131929.jpg

Has anybody an idea what i am doing wrong??

Thanks for your help!

2 REPLIES 2
John E KVAM
ST Employee

did your call to 

rc = vl53lx.VL53LX_GetDeviceInfo(&devInfo);

Work? 

That would at least verify that the I2C is communicating. 

As a first step don't go with a complicated scene. Start with the sensor looking up - at your hand. Your hand is easy to move. (IN your scene that desk is in the FoV.)

the only way to goof this up is to have a byte-swap or work swap issue. As most of the commands are byte, you get the feeling that things are working, and it's not until you start sending words that you realize something is wrong. 

 

#define I2C_TEST
#ifdef I2C_TEST
int rd_write_verification( VL53L1_Dev_t *dev, uint16_t addr, uint32_t expected_value)
{
	VL53L1_Error Status  = VL53L1_ERROR_NONE;
	uint8_t bytes[4],mbytes[4];
	uint16_t words[2];
	uint32_t dword;
	int i;
	VL53L1_ReadMulti(dev, addr, mbytes, 4);
	for (i=0; i<4; i++){ VL53L1_RdByte(dev, addr+i, &bytes[i]); }
	for (i=0; i<2; i++){ VL53L1_RdWord(dev, addr+i*2, &words[i]); }
	Status = VL53L1_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 i2c_test(VL53L1_Dev_t *dev)
{
	VL53L1_Error Status  = VL53L1_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;

	Status = rd_write_verification(dev, 0x10f, 0xeacc10ff);			// verify the Chip ID works

	Status += VL53L1_WriteMulti(dev, 0x01,  long_out, 135);			// check if WriteMulti can write 135 bytes
	Status += VL53L1_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++;

	Status += VL53L1_WriteMulti(dev, REG,  buff, 4);				// check WriteMulti
	if (rd_write_verification(dev, REG, 0x11223344) <0) err_count++;

	Status += VL53L1_WrDWord(dev, REG, 0xffeeddcc);				// check WrDWord
	if (rd_write_verification(dev, REG, 0xffeeddcc) <0) err_count++;

	Status += VL53L1_WrWord(dev, REG, 0x5566);					// check WrWord
	Status += VL53L1_WrWord(dev, REG+2, 0x7788);
	if (rd_write_verification(dev, REG, 0x55667788) <0) err_count++;

	for (i=0; i<4; i++){ VL53L1_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);
	}
}

#endif

 

Try this bit of code - it's for the L1, but the two processors are neary the same, and you can easily change the VL53L1 to VL53L3 and run it.  

If you set the sensor to running, you can query the sensor every bunch of milliseconds and you should see data. 

But do print out the range_status. When something goes wrong that status tells you what the issue is.

- john


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.
PHumm.2
Associate

Hi John,

thanks for your reply. It seems like the command works:

Starting...
GetVersion: rc=0, Build=4, Major=1, Minor=1, Revision=2352
GetProductRevision: rc=0, Major=1, Minor=1
GetDeviceInfo: rc=0, ModuleType(0xAA?)=0xAA, ProdRevMajor=1, ProdRevMinor=1
GetUID: rc=0, UID=0xFDEFC3745D1814C5
I2CRead 0x010F: rc=0, Model_ID=0xEA
I2CRead 0x0110: rc=0, Module_Type=0xAA
Ready...

I n my code i am now always printing the ranging status.

Here i moved my hand in and out of the FoV. Beause of cable length issues the sensor is looking into the far where no object is. The test looks good so far:

Ranging status: 255; Nothing found
Ranging status: 12; Nothing found
Ranging status: 0; Distances: 187 0 0 0
Ranging status: 0; Distances: 178 0 0 0
Ranging status: 0; Distances: 181 0 0 0
Ranging status: 0; Distances: 186 0 0 0
Ranging status: 0; Distances: 193 0 0 0
Ranging status: 0; Distances: 203 0 0 0
Ranging status: 0; Distances: 174 0 0 0
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 12; Nothing found
Ranging status: 0; Distances: 173 0 0 0
Ranging status: 0; Distances: 176 0 0 0
Ranging status: 0; Distances: 195 0 0 0
Ranging status: 0; Distances: 204 0 0 0
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 255; Nothing found
Ranging status: 12; Nothing found
Ranging status: 0; Distances: 210 0 0 0
Ranging status: 0; Distances: 196 0 0 0
Ranging status: 0; Distances: 209 0 0 0
Ranging status: 0; Distances: 201 0 0 0
Ranging status: 0; Distances: 214 0 0 0
Ranging status: 0; Distances: 201 0 0 0
Ranging status: 0; Distances: 212 0 0 0
Ranging status: 0; Distances: 198 0 0 0
Ranging status: 0; Distances: 210 0 0 0

 

I tested your code and called "i2c_test(&vl53l3cx);" in the loop(). This is the output:

Ranging status: 4; Nothing found
[955197][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955197][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955200][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955207][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955214][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955221][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955227][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955234][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
expected   = eacc10ff,
read_multi =  0,  0, 20,  9
read_bytes =  0,  0,  0,  0
read words =    0,    0
read dword =        0
[955253][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955260][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955267][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955273][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955280][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955287][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955294][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955301][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955308][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
expected   = 11223344,
read_multi =  0,  0,  0,  0
read_bytes = 60, 67, c9, 3f
read words =    0,    0
read dword =        0
[955327][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955333][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955340][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955347][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955354][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955361][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955368][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955375][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
expected   = ffeeddcc,
read_multi = ff, ee, dd, cc
read_bytes = 60, 67, c9, 3f
read words =    0,    0
read dword =        0
[955394][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955400][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955407][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955414][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955421][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955428][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955435][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955442][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
expected   = 55667788,
read_multi = ff, ee, 77, 88
read_bytes = 60, 67, c9, 3f
read words =    0,    0
read dword =        0
[955461][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955467][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955474][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955481][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955488][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955495][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955502][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[955509][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
expected   = 11223344,
read_multi = 44, ee, 77, 88
read_bytes = 60, 67, c9, 3f
read words =    0,    0
read dword =        0
i2c test failed - please check it. Status = 1

I am pretty new to that esp32 and distance sensor thingy...can you work with this output?

Does it mean that there is a communication issue in the vl53l3cx?