cancel
Showing results for 
Search instead for 
Did you mean: 

The offset value to VL53L1X_SetOffset set is different from the one VL53L1X_GetOffset got from.

RChen.1654
Associate II

I use VL53L1X ultra lite driver.

For example:

The value written to ALGO__PART_TO_PART_RANGE_OFFSET_MM(0x001E) register is 0xFF24 when VL53L1X_SetOffset() is called with OffsetValue -55.

The value got from ALGO__PART_TO_PART_RANGE_OFFSET_MM(0x001E) register is 0x1F24 when VL53L1X_GetOffset is called and the returned offset value is 1993.

I meet this issue when offset value < 0.

4 REPLIES 4
John E KVAM
ST Employee
VL53L1X_ERROR VL53L1X_SetOffset(VL53L1_Dev_t dev, int16_t OffsetValue)
{
	VL53L1X_ERROR status = 0;
	int16_t Temp;
 
	Temp = (OffsetValue*4);
	VL53L1_WrWord(&dev, ALGO__PART_TO_PART_RANGE_OFFSET_MM,
			(uint16_t)Temp);
	VL53L1_WrWord(&dev, MM_CONFIG__INNER_OFFSET_MM, 0x0);
	VL53L1_WrWord(&dev, MM_CONFIG__OUTER_OFFSET_MM, 0x0);
	return status;
}
 
VL53L1X_ERROR  VL53L1X_GetOffset(VL53L1_Dev_t dev, int16_t *offset)
{
	VL53L1X_ERROR status = 0;
	uint16_t Temp;
 
	status = VL53L1_RdWord(&dev,ALGO__PART_TO_PART_RANGE_OFFSET_MM, &Temp);
	Temp = Temp<<3;
	Temp = Temp >>5;
	*offset = (int16_t)(Temp);
	return status;
}

The register is 13 bits. And the value is stored in mm.XX where XX are the fractional parts of millimeters (mm).

So if the offset wants to be 12mm, 12 x 4 would be stored in the register. (Offset Value*4)

When the register is retrieved, we read the value, Shift up by 3 to eliminate any 'junk' bits, then right shift by 5 to get back to mm.

So what we have here is a sign issue.

I believe the correct code should be:

VL53L1X_ERROR  VL53L1X_GetOffset(VL53L1_Dev_t dev, int16_t *offset)
{
	VL53L1X_ERROR status = 0;
	uint16_t Temp;
 
	status = VL53L1_RdWord(&dev,ALGO__PART_TO_PART_RANGE_OFFSET_MM, &Temp);
	Temp = Temp<<3;
	Temp = Temp >>5;
	if((Temp & 0x1000) !=0) Temp = Temp|0xF000);
	*offset = (int16_t)(Temp);
	return status;
}

Where we added line 9 - A mod to check the sign bit, and make a negative value before returning.

Please double check my code if you use it, there is no peer review.


In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question. It helps the next guy.
John E KVAM
ST Employee

Upon double checking the definition of a right shift is implementation dependent. Meaning some MCUs will sign extend and some will not.

Clearly yours does not do sign extension.


In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question. It helps the next guy.
RChen.1654
Associate II

Follow the above modification, the returned offset value is still incorrect.

VL53L1X_ERROR VL53L1X_GetOffset(VL53L1_Dev_t dev, int16_t *offset)
{
	VL53L1X_ERROR status = 0;
	uint16_t Temp;
 
	status = VL53L1_RdWord(&dev,ALGO__PART_TO_PART_RANGE_OFFSET_MM, &Temp);	//Temp is 0x1F24 if offset is -55.
	Temp = Temp<<3;
	Temp = Temp>>5; 					// Temp is 0x07C9
	if((Temp & 0x1000) !=0) Temp = Temp|0xF000;
	*offset = (int16_t)(Temp); 				// Temp is 0x07C9
	return status;
}

I modify VL53L1X_GetOffset as bellow. The returned offset value is the same as the one set in the VL53L1X_SetOffset function.

Is this correct ?

VL53L1X_ERROR VL53L1X_GetOffset(VL53L1_Dev_t dev, int16_t *offset)
{
	VL53L1X_ERROR status = 0;
	uint16_t Temp;
 
	status = VL53L1_RdWord(&dev,ALGO__PART_TO_PART_RANGE_OFFSET_MM, &Temp);
	Temp = Temp<<3;
	Temp = Temp>>5;
	if((Temp & 0x0400) !=0) Temp = Temp|0xF800;
	*offset = (int16_t)(Temp);
	return status;
}

Hello @RChen.1654​ .

I had the same problem. After much debugging and much trial and error, I have come to the same conclusion as you:

if((Temp & 0x0400) !=0) Temp = Temp|0xF800;

For example:

VL53L1X_CalibrateOffset() calculates OFFSET = -265 = 0xFEF7 = 1111 1110 1111 0111 --> This is stored in sensor's internal memory.

Now, I want to read the value previously stored in sensor's internal memory using VL53L1X_GetOffset():

1) Without the above line of code:

VL53L1X_GetOffset() returns OFFSET = 1783 = 0x06F7 = 110 1111 0111 --> This is not right.

2) With the above line of code:

0x06F7 OR 0xF800 --> 0000 0110 1111 0111 OR 1111 1000 0000 0000 --> 1111 1110 1111 0111 = -265 --> This is now right. VL53L1X_GetOffset() return the same value that was calculated by VL53L1X_CalibrateOffset().