VL53L0X API - Initialization error, performRefSpadManagement() returns -6 (VL53L0X_ERROR_RANGE_ERROR)
Hello everyone,
I am developing a project involving an Arduino Zero-like microcontroller and some I2C sensors, including the ST VL53L0X ToF sensor.
One of my requirements is not to use the Arduino's Wire library for I2C communication, so I'm almost obliged to put my effort trying to understand the ST API for this sensor.
What I'm trying to achieve can be summarized as follows:
- Initialize the sensor and configure it in Single Ranging Mode
- Periodically poll the sensor to retrieve distance measurements
On one side, I've been able to write an I2C driver to communicate with my sensors, including VL53L0X and MPU6050 accel-gyroscope. However, for VL53L0X I got stuck in the initialization process.
Here is the expected workflow, using ST API and following "vl53l0x_SingleRanging_Example.c" included with the library:
- Call VL53L0X_DataInit() --> receive VL53L0X_ERROR_NONE
- Call VL53L0X_StaticInit() --> receive VL53L0X_ERROR_NONE
- Call VL53L0X_PerformRefSpadManagement() --> receive VL53L0X_ERROR_NONE
- Call VL53L0X_PerformRefCalibration() --> receive VL53L0X_ERROR_NONE
- Call VL53L0X_SetDeviceMode(..., VL53L0X_DEVICEMODE_SINGLE_RANGING) --> receive VL53L0X_ERROR_NONE
- etc.
The actual workflow is the same until point 2, but then VL53L0X_PerformRefSpadManagement returns the error code -6 (VL53L0X_ERROR_RANGE_ERROR).
Here is my code, where I basically go through the initialization process and print on serial the status code for each step:
void VL53L0X_singleRanging() {
VL53L0X_Error Status = VL53L0X_ERROR_NONE;
VL53L0X_Dev_t MyDevice;
VL53L0X_Dev_t *pMyDevice = &MyDevice;
VL53L0X_Version_t Version;
VL53L0X_Version_t *pVersion = &Version;
VL53L0X_DeviceInfo_t DeviceInfo;
int32_t status_int;
uint8_t VhvSettings;
uint8_t PhaseCal;
uint32_t refSpadCount;
uint8_t isApertureSpads;
VL53L0X_RangingMeasurementData_t RangingMeasurementData;
pMyDevice->I2cDevAddr = 0x29;
pMyDevice->comms_type = 1;
pMyDevice->comms_speed_khz = 400;
status_int = VL53L0X_GetVersion(pVersion);
SerialUSB.print("Status GetVersion = ");
SerialUSB.println(status_int);
Status = VL53L0X_DataInit(pMyDevice);
SerialUSB.print("Status DataInit = ");
SerialUSB.println(Status);
Status = VL53L0X_GetDeviceInfo(&MyDevice, &DeviceInfo);
SerialUSB.print("Status GetDeviceInfo = ");
SerialUSB.println(Status);
SerialUSB.print("VL53L0X_GetDeviceInfo:\n");
SerialUSB.print("Device Name : ");
SerialUSB.println(DeviceInfo.Name);
SerialUSB.print("Device Type : ");
SerialUSB.println(DeviceInfo.Type);
/*
printf("Device ID : %s\n", DeviceInfo.ProductId);
printf("ProductRevisionMajor : %d\n", DeviceInfo.ProductRevisionMajor);
printf("ProductRevisionMinor : %d\n", DeviceInfo.ProductRevisionMinor);
*/
Status = VL53L0X_StaticInit(pMyDevice); // Device Initialization
SerialUSB.print("Status StaticInit = ");
SerialUSB.println(Status);
Status = VL53L0X_PerformRefSpadManagement(pMyDevice,
&refSpadCount, &isApertureSpads); // Device Initialization
SerialUSB.print("Status PerformRefSpadManagement = ");
SerialUSB.println(Status);
Status = VL53L0X_PerformRefCalibration(pMyDevice,
&VhvSettings, &PhaseCal);
SerialUSB.print("Status PerformRefCalibration = ");
SerialUSB.println(Status);
Status = VL53L0X_SetDeviceMode(pMyDevice, VL53L0X_DEVICEMODE_SINGLE_RANGING); // Setup in single ranging mode
SerialUSB.print("Status SetDeviceMode = ");
SerialUSB.println(Status);
Status = VL53L0X_SetLimitCheckEnable(pMyDevice,
VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, 1);
SerialUSB.print("Status SetLimitCheckEnable = ");
SerialUSB.println(Status);
Status = VL53L0X_SetLimitCheckEnable(pMyDevice,
VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, 1);
SerialUSB.print("Status SetLimitCheckEnable = ");
SerialUSB.println(Status);
Status = VL53L0X_SetLimitCheckEnable(pMyDevice,
VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, 1);
SerialUSB.print("Status SetLimitCheckEnable = ");
SerialUSB.println(Status);
Status = VL53L0X_SetLimitCheckValue(pMyDevice,
VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD,
(FixPoint1616_t)(1.5*0.023*65536));
SerialUSB.print("Status SetLimitCheckValue = ");
SerialUSB.println(Status);
while(true) {
Status = VL53L0X_PerformSingleRangingMeasurement(pMyDevice,
&RangingMeasurementData);
SerialUSB.print("Status PerformSingleRangingMeasurement = ");
SerialUSB.println(Status);
SerialUSB.print("Measured distance: ");
SerialUSB.print(RangingMeasurementData.RangeMilliMeter);
SerialUSB.println(" millimeters");
SerialUSB.print("Range Status: ");
SerialUSB.println(RangingMeasurementData.RangeStatus);
VL53L0X_State palState;
Status = VL53L0X_GetPalState(pMyDevice, &palState);
char stateString[50];
memset(stateString, 0, 50);
VL53L0X_GetPalStateString(palState, stateString);
SerialUSB.println(stateString);
delay(1000);
}
}Another thing that might be important is my I2C communication logic: no matter which PAL function gets called (RdByte, WrWord, etc), one and only one stop condition is always issued at the end of each of them.
Every form of help will be very appreciated.
Thanks in advance,
Alberto
