2020-11-25 08:06 AM
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
2020-11-30 11:04 AM
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?
2020-11-30 11:31 AM
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;
}