cancel
Showing results for 
Search instead for 
Did you mean: 

VL53L0X API Status: -50 : Reference Spad Init Error (VL53L0X_1.0.2 hack)

jgnoss
Associate III

That's not meant as a question, more as an input/feed-back for ST developers or users of the VL53L0X device.

I have a custom PCB with STM32F091 and two VL53L0X

Symptom:

If I initialize one only of the sensors, that sensor works great and gives good results.

No matter if it is the left or the right one.

If I initialize first one sensor, (changing device address while initializing)

then the other (also changing device address while initializing),

the second sensor while initializing always runs into

API Status: -50 : Reference Spad Init Error

My setup

custom PCB with STM32F091 + usual components on PCB TOP

2 VL53L0X devices 23cm apart on PCB Bottom.

STM32CubeIDE

Version: 1.4.2

Build: 7643_20200813_1322 (UTC)

VL53L0X_1.0.2 API from en.STSW-IMG005

slightly modified platform stuff in order to run on bare metal

Nucleo or discovery st-link to program the device

------------------------------------------------------------------------------------------------

I traced the error down to

vl53l0x_api_calibration.c

line 594

		/* Confirm that the next good SPAD is non-aperture */
		if (is_aperture(start + nextGoodSpad) != apertureSpads) {
			/* if we can't get the required number of good aperture
			 * spads from the current quadrant then this is an error
			 */
				status = VL53L0X_ERROR_REF_SPAD_INIT;
				break;
		}

this evalates to true if index in the enclosing for loop is

spadCount - 2

so I did the dirty hack

		/* Confirm that the next good SPAD is non-aperture */
		if (is_aperture(start + nextGoodSpad) != apertureSpads) {
			/* if we can't get the required number of good aperture
			 * spads from the current quadrant then this is an error
			 */
 
			//FIXME crude hack to get pass second sensor the spad management
			if (index < spadCount - 2) {
				status = VL53L0X_ERROR_REF_SPAD_INIT;
				break;
			}
		}

and it seems to run OK.

------------------------------------------------------------------------------------------------------------------------------

here a console output with original code and the error occures

VL53L0 Test 00.01 from Nov 25 2020 at 08:52:15.

Hello Ju

>init_ToF for Device RIGHT 

Ack on Adress : 0x29

>

call VL53L0X_DataInit

>API Status: 0 : No Error

Device RIGHT DataInit complete

>

call VL53L0X_DataInit

>API Status: 0 : No Error

Device RIGHT DataInit complete

>

call VL53L0X_SetDeviceAddress

>API Status: 0 : No Error

Device RIGHT VL53L0X_SetDeviceAddress complete

call VL53L0X_GetDeviceInfo

>Device Type : VL53L0X

Device ID : VL53L0CXV0DH/1$C

API Status: 0 : No Error

API Status: 0 : No Error

Call of VL53L0X_StaticInit

API Status: 0 : No Error

Call of VL53L0X_PerformRefCalibration

API Status: 0 : No Error

Call of VL53L0X_PerformRefSpadManagement

refSpadCount = 11, isApertureSpads = 0

API Status: 0 : No Error

Call of VL53L0X_SetDeviceMode

API Status: 0 : No Error

init_ToF for Device LEFT 

Ack on Adress : 0x1E

Ack on Adress : 0x29

>

call VL53L0X_DataInit

>API Status: 0 : No Error

Device LEFT DataInit complete

>

call VL53L0X_SetDeviceAddress

>API Status: 0 : No Error

Device LEFT VL53L0X_SetDeviceAddress complete

call VL53L0X_GetDeviceInfo

>Device Type : VL53L0X

Device ID : VL53L0CXV0DH/1$C

API Status: 0 : No Error

API Status: 0 : No Error

Call of VL53L0X_StaticInit

API Status: -50 : Reference Spad Init Error

----------------------------------------------------------------------------------------------------------------

... and after the modification

VL53L0 Test 00.01 from Nov 25 2020 at 08:52:15.

Hello Ju

>init_ToF for Device RIGHT 

Ack on Adress : 0x29

>

call VL53L0X_DataInit

>API Status: 0 : No Error

Device RIGHT DataInit complete

>

call VL53L0X_SetDeviceAddress

>API Status: 0 : No Error

Device RIGHT VL53L0X_SetDeviceAddress complete

call VL53L0X_GetDeviceInfo

>Device Type : VL53L0X

Device ID : VL53L0CXV0DH/1$C

API Status: 0 : No Error

API Status: 0 : No Error

Call of VL53L0X_StaticInit

API Status: 0 : No Error

Call of VL53L0X_PerformRefCalibration

API Status: 0 : No Error

Call of VL53L0X_PerformRefSpadManagement

refSpadCount = 11, isApertureSpads = 0

API Status: 0 : No Error

Call of VL53L0X_SetDeviceMode

API Status: 0 : No Error

init_ToF for Device LEFT 

Ack on Adress : 0x1E

Ack on Adress : 0x29

>

call VL53L0X_DataInit

>API Status: 0 : No Error

Device LEFT DataInit complete

>

call VL53L0X_SetDeviceAddress

>API Status: 0 : No Error

Device LEFT VL53L0X_SetDeviceAddress complete

call VL53L0X_GetDeviceInfo

>Device Type : VL53L0X

Device ID : VL53L0CXV0DH/1$C

API Status: 0 : No Error

API Status: 0 : No Error

Call of VL53L0X_StaticInit

API Status: 0 : No Error

Call of VL53L0X_PerformRefCalibration

API Status: 0 : No Error

Call of VL53L0X_PerformRefSpadManagement

refSpadCount = 10, isApertureSpads = 0

API Status: 0 : No Error

Call of VL53L0X_SetDeviceMode

API Status: 0 : No Error

ready for ranging press 'r' for start/stop

--------------------------------------------------------------------------------------------------

first measured data while moving a white paper back and forth in front of the two sensors after code modification

API Status: 0 : No Error

ready for ranging press 'r' for start/stop

r

Sensor LEFT Ranging activated

Sensor RIGHT Ranging activated

>Call of VL53L0X_StartMeasurement

API Status: 0 : No Error

Call of VL53L0X_StartMeasurement

API Status: 0 : No Error

LEFT   128

RIGHT   130

RIGHT   139

RIGHT   128

RIGHT   141

RIGHT   128

RIGHT   142

RIGHT   128

RIGHT   128

LEFT   128

RIGHT   137

RIGHT   136

LEFT   133

LEFT   128

LEFT   132

RIGHT   133

RIGHT   129

RIGHT   152

LEFT   150

RIGHT   147

LEFT   148

RIGHT   145

LEFT   132

RIGHT   133

LEFT   128

RIGHT   40

LEFT   32

RIGHT   17

LEFT   10

RIGHT   16

RIGHT   0

LEFT   0

RIGHT   2

LEFT   4

RIGHT   4

LEFT   10

RIGHT   16

LEFT   20

RIGHT   18

LEFT   131

RIGHT   128

LEFT   134

RIGHT   128

LEFT   136

RIGHT   132

LEFT   128

Ranging Sensor LEFT deactivated

Ranging Sensor RIGHT deactivated

>Call of VL53L0X_StopMeasurement

Wait Stop to be completed

Stop completed Sensor LEFT

Call of VL53L0X_StopMeasurement

Wait Stop to be completed

Stop completed Sensor RIGHT

2 REPLIES 2
John E KVAM
ST Employee

You only need to do SPAD calibration once. It, along with offset and crosstalk, can be stored in memory and reloaded at boot.

So if you get a failure when the other chip is on - and I find this very strange - but you can...

Boot one sensor do all the calibrations, store them, and shutdown the sensor.

Then do the same thing on the other sensor.

Then boot, change the address, load the calibarion, boot the other sensor, change it's address and load it's calibration.

At that point you should be good to go.

I always tell people that the sensors do not interfer with each other.

But your experiment seems to show that one cannot do a RefSpad calibration with another sensor running nearby.

And that might be the issue. If so that might answer problems others are having.

Can you try getting one booted do the RefSpand cal - but DON't START IT. Then get the other booted and do the refSpad calibration.

Once both the calibrations are done, Then start them ranging. Does that work?


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.
jgnoss
Associate III

Hello John,

thanks for looking into that.

>Can you try getting one booted do the RefSpand cal - but DON't START IT. Then get the other booted and do the refSpad calibration.

I'm afraid I already do that. At least if

VL53L0X_StartMeasurement(&VL53L0XDevs[i]);

is what starts the sensor.

I have two functions, one is setting up the sensors, doing all that calibration stuff.

That happens once, before entering the main loop, and takes up to 20s for both sensors.

The other function is called in the main loop to detect a directional swipe.

The code is mainly coming from the STM examples.

int setupDirSwipe(void) {
	int status = 0;
 
	// so enable both sensors */
	VL53L0XDevs[SENSOR_LEFT].Enabled = 1;
	VL53L0XDevs[SENSOR_RIGHT].Enabled = 1;
 
	dbg_printf(DEBUG_LEVEL_UI, "standby for setup and calibrate sensors \n");
	//We implement DIRECTIONAL_SWIPE only
 
	/* Initialize directional swipes recognition :
	 * swipe detected below 400 mm, no max speed,
	 * min duration is 1 sec for a swipe and
	 * hand must not cover both devices */
 
	status = tof_gestures_initDIRSWIPE_1(swipeDistance, min_SwipeDuration,
			max_SwipeDuration, coverBothSensorsRequired, &gestureDirSwipeData);
 
	/* Setup sensors in single mode */
	if (status == 0) {
		status = setupSingleShot();
	} else {
		dbg_printf(DEBUG_LEVEL_ERROR, "setupSingleShot failed\n");
		__Error_Handler(__FILE__, __LINE__);
	}
 
	if (status != 0) {
		dbg_printf(DEBUG_LEVEL_ERROR, "setupSingleShot failed\n");
		__Error_Handler(__FILE__, __LINE__);
	}
	return status;
}
 
/*****************************************************************/
/**** main State machine functions *******************************/
/*****************************************************************/
 
 
 
mainSMState_t do_ReadyForDetection(mainSMState_t oldState) {
 
	// just sitting here and wait for someone activating swipe detection
 
	return ReadyForDetection;
}
 
mainSMState_t do_SwipeDetection(mainSMState_t oldState) {
	uint8_t status;
	uint8_t nReady = 0;
	int i;
	uint8_t NewDataReady = 0;
	int gesture_code;
	int32_t leftRange;
	int32_t rightRange;
 
	/* kick off measure on enabled devices */
	for (i = 0; i < SENSOR_COUNT; i++) {
		if (!VL53L0XDevs[i].Present || !VL53L0XDevs[i].Enabled)
			continue;
		status = VL53L0X_StartMeasurement(&VL53L0XDevs[i]);
		if (status) {
			dbg_printf(DEBUG_LEVEL_SENSOR,
								"VL53L0X_StartMeasurement failed on device %d", i);
		}
		VL53L0XDevs[i].Ready = 0;
		//dbg_printf(DEBUG_LEVEL_SENSOR,"StartMeasurement %d OK ", i);
	}
 
	/* wait for all enabled devices to have a measure */
	nReady = 0;
	do {
		HAL_Delay(1);
		for (i = 0; i < SENSOR_COUNT; i++) {
			/* Skip devices not present or not enabled */
			if (!VL53L0XDevs[i].Present || !VL53L0XDevs[i].Enabled)
				continue;
			/* Is new sample ready ? */
			status = VL53L0X_GetMeasurementDataReady(&VL53L0XDevs[i],
					&NewDataReady);
			if (status) {
				dbg_printf(DEBUG_LEVEL_SENSOR,
									"VL53L0X_GetMeasurementDataReady failed on device %d",
						i);
			}
			/* Skip if new sample not ready */
			if (NewDataReady == 0)
				continue;
 
			/* Clear Interrupt */
			status = VL53L0X_ClearInterruptMask(&VL53L0XDevs[i], 0);
 
			/* Otherwise, get new sample data and store */
			status = VL53L0X_GetRangingMeasurementData(&VL53L0XDevs[i],
					&RangingMeasurementData);
			if (status) {
				dbg_printf(DEBUG_LEVEL_SENSOR,
									"VL53L0X_GetRangingMeasurementData failed on device %d",
						i);
			}
			/* Data logging */
			/*
			 trace_printf("%d,%u,%d,%d,%d\n", VL53L0XDevs[i].Id, TimeStamp_Get(),
			 RangingMeasurementData.RangeStatus,
			 RangingMeasurementData.RangeMilliMeter,
			 RangingMeasurementData.SignalRateRtnMegaCps);
			 */
			sensor_SetNewRange(&VL53L0XDevs[i], &RangingMeasurementData);
			VL53L0XDevs[i].Ready = 1;
			nReady++;
		}
	} while (nReady < nSensorEnabled);
 
	/********************************************************************************/
	/* GESTURES : Apply gestures detection functions on the measures                */
	/********************************************************************************/
 
	/* Clip ranging values as tof_gestures_detectDIRSWIPE_1 function must be called all the times to detect the gesture */
	leftRange =
			(VL53L0XDevs[SENSOR_LEFT].RangeStatus == 0) ?
					VL53L0XDevs[SENSOR_LEFT].LeakyRange : 1200;
	rightRange =
			(VL53L0XDevs[SENSOR_RIGHT].RangeStatus == 0) ?
					VL53L0XDevs[SENSOR_RIGHT].LeakyRange : 1200;
	gesture_code = tof_gestures_detectDIRSWIPE_1(leftRange, rightRange,
			&gestureDirSwipeData);
 
 
	if (gesture_code == GESTURES_SWIPE_LEFT_RIGHT) {
		wheelsInTunnel++;
	} else if (gesture_code == GESTURES_SWIPE_RIGHT_LEFT) {
		wheelsInTunnel--;
	} else {
		//ShowGestureHelpMsg(gesture_code);
	}
 
	return SwipeDetection;
 
}