Programm stops at StaticInit Function
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-07-11 6:51 AM
Hello Community
After a long time of figuring out the api and file structure, I got the I2C communication working. I copied the Single Range Measurement Example from the API-ZIP into my programm. Additionally I ran the I2C-Verification Code, which came out good.
Following is my code:
// ====================================
#include "mbed.h"
#include "vl53l0x_api.h"
#include "vl53l0x_platform.h"
I2C i2c(p9, p10);
BusOut led(LED1, LED2, LED3, LED4);
Serial pc(USBTX, USBRX, 9600);
VL53L0X_Dev_t vl_device;
void i2c_test(void);
int rd_write_verification(uint8_t addr, uint32_t expected_value);
void i2c_test(void)
{
int err_count = 0;
int expected_value = 0;
uint8_t buff[4] = {0x11, 0x22, 0x33, 0x44};
uint8_t ChipID[4];
int i = 0;
for (i = 0; i < 4; i++)
{
VL53L0X_RdByte(&vl_device, 0xC0 + i, &ChipID[i]);
}
expected_value = ChipID[0] << 24 | ChipID[1] << 16 | ChipID[2] << 8 | ChipID[3];
if (rd_write_verification(0xc0, expected_value) < 0)
err_count++; // check the chip ID
VL53L0X_WriteMulti(&vl_device, 0x4, buff, 4); // check WriteMulti
if (rd_write_verification(0x4, 0x11223344) < 0)
err_count++;
VL53L0X_WrDWord(&vl_device, 0x4, 0xffeeddcc); // check WrDWord
if (rd_write_verification(0x4, 0xffeeddcc) < 0)
err_count++;
VL53L0X_WrWord(&vl_device, 0x4, 0x5566); // check WrWord
VL53L0X_WrWord(&vl_device, 0x6, 0x7788);
if (rd_write_verification(0x4, 0x55667788) < 0)
err_count++;
for (i = 0; i < 4; i++)
{
VL53L0X_WrByte(&vl_device, 0x04 + i, buff[i]);
}
if (rd_write_verification(0x4, 0x11223344) < 0)
err_count++;
if (err_count > 0)
{
pc.printf("i2c test failed - please check it\n");
}
pc.printf("\n\n\r");
}
int rd_write_verification(uint8_t addr, uint32_t expected_value)
{
uint8_t bytes[4], mbytes[4];
uint16_t words[2];
uint32_t dword;
VL53L0X_ReadMulti(&vl_device, addr, mbytes, 4);
for (int i = 0; i < 4; i++)
{
VL53L0X_RdByte(&vl_device, addr + i, &bytes[i]);
}
for (int i = 0; i < 2; i++)
{
VL53L0X_RdWord(&vl_device, addr + i * 2, &words[i]);
}
VL53L0X_RdDWord(&vl_device, addr, &dword);
pc.printf("expected = %8x,\n", expected_value);
pc.printf("read_multi = %2x, %2x, %2x, %2x\n", mbytes[0], mbytes[1], mbytes[2], mbytes[3]);
pc.printf("read_bytes = %2x, %2x, %2x, %2x\n", bytes[0], bytes[1], bytes[2], bytes[3]);
pc.printf("read words = %4x, %4x\n", words[0], words[1]);
pc.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 (0);
}
void print_pal_error(VL53L0X_Error Status)
{
char buf[VL53L0X_MAX_STRING_LENGTH];
VL53L0X_GetPalErrorString(Status, buf);
pc.printf("API Status: %i : %s\n", Status, buf);
}
void print_range_status(VL53L0X_RangingMeasurementData_t *pRangingMeasurementData)
{
char buf[VL53L0X_MAX_STRING_LENGTH];
uint8_t RangeStatus;
/*
* New Range Status: data is valid when pRangingMeasurementData->RangeStatus = 0
*/
RangeStatus = pRangingMeasurementData->RangeStatus;
VL53L0X_GetRangeStatusString(RangeStatus, buf);
pc.printf("Range Status: %i : %s\n", RangeStatus, buf);
}
VL53L0X_Error rangingTest(VL53L0X_Dev_t *pMyDevice)
{
VL53L0X_Error Status = VL53L0X_ERROR_NONE;
VL53L0X_RangingMeasurementData_t RangingMeasurementData;
int i;
FixPoint1616_t LimitCheckCurrent;
uint32_t refSpadCount;
uint8_t isApertureSpads;
uint8_t VhvSettings;
uint8_t PhaseCal;
if (Status == VL53L0X_ERROR_NONE)
{
pc.printf("Call of VL53L0X_StaticInit\n");
Status = VL53L0X_StaticInit(pMyDevice); // Device Initialization
print_pal_error(Status);
}
if (Status == VL53L0X_ERROR_NONE)
{
pc.printf("Call of VL53L0X_PerformRefCalibration\n");
Status = VL53L0X_PerformRefCalibration(pMyDevice,
&VhvSettings, &PhaseCal); // Device Initialization
print_pal_error(Status);
}
if (Status == VL53L0X_ERROR_NONE)
{
pc.printf("Call of VL53L0X_PerformRefSpadManagement\n");
Status = VL53L0X_PerformRefSpadManagement(pMyDevice,
&refSpadCount, &isApertureSpads); // Device Initialization
pc.printf("refSpadCount = %d, isApertureSpads = %d\n", refSpadCount, isApertureSpads);
print_pal_error(Status);
}
if (Status == VL53L0X_ERROR_NONE)
{
// no need to do this when we use VL53L0X_PerformSingleRangingMeasurement
pc.printf("Call of VL53L0X_SetDeviceMode\n");
Status = VL53L0X_SetDeviceMode(pMyDevice, VL53L0X_DEVICEMODE_SINGLE_RANGING); // Setup in single ranging mode
print_pal_error(Status);
}
// Enable/Disable Sigma and Signal check
if (Status == VL53L0X_ERROR_NONE)
{
Status = VL53L0X_SetLimitCheckEnable(pMyDevice,
VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, 1);
}
if (Status == VL53L0X_ERROR_NONE)
{
Status = VL53L0X_SetLimitCheckEnable(pMyDevice,
VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, 1);
}
if (Status == VL53L0X_ERROR_NONE)
{
Status = VL53L0X_SetLimitCheckEnable(pMyDevice,
VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, 1);
}
if (Status == VL53L0X_ERROR_NONE)
{
Status = VL53L0X_SetLimitCheckValue(pMyDevice,
VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD,
(FixPoint1616_t)(1.5 * 0.023 * 65536));
}
/*
* Step 4 : Test ranging mode
*/
if (Status == VL53L0X_ERROR_NONE)
{
for (i = 0; i < 10; i++)
{
pc.printf("Call of VL53L0X_PerformSingleRangingMeasurement\n");
Status = VL53L0X_PerformSingleRangingMeasurement(pMyDevice,
&RangingMeasurementData);
print_pal_error(Status);
print_range_status(&RangingMeasurementData);
VL53L0X_GetLimitCheckCurrent(pMyDevice,
VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, &LimitCheckCurrent);
pc.printf("RANGE IGNORE THRESHOLD: %f\n\n", (float)LimitCheckCurrent / 65536.0);
if (Status != VL53L0X_ERROR_NONE)
break;
pc.printf("Measured distance: %i\n\n", RangingMeasurementData.RangeMilliMeter);
}
}
return Status;
}
int main()
{
i2c.frequency(100000);
VL53L0X_Error Status = VL53L0X_ERROR_NONE;
VL53L0X_Version_t vl_version;
VL53L0X_DeviceInfo_t vl_deviceInfo;
vl_device.i2c_device = &i2c;
vl_device.i2c_address = 0x29;
pc.printf("VL53L0X API Simple Ranging example\n\n");
int32_t status_int;
int32_t init_done = 0;
if (Status == VL53L0X_ERROR_NONE)
{
status_int = VL53L0X_GetVersion(&vl_version);
if (status_int != 0)
Status = VL53L0X_ERROR_CONTROL_INTERFACE;
}
/*
* Verify the version of the VL53L0X API running in the firmrware
*/
if (Status == VL53L0X_ERROR_NONE)
{
if (vl_version.major != 1 ||
vl_version.minor != 0 ||
vl_version.build != 2)
{
pc.printf("VL53L0X API Version Error: Your firmware has %d.%d.%d (revision %d). This example requires %d.%d.%d.\n",
vl_version.major, vl_version.minor, vl_version.build, vl_version.revision,
1, 0, 2);
}
}
// End of implementation specific
if (Status == VL53L0X_ERROR_NONE)
{
pc.printf("Call of VL53L0X_DataInit\n");
Status = VL53L0X_DataInit(&vl_device); // Data initialization
print_pal_error(Status);
}
if (Status == VL53L0X_ERROR_NONE)
{
Status = VL53L0X_GetDeviceInfo(&vl_device, &vl_deviceInfo);
}
if (Status == VL53L0X_ERROR_NONE)
{
pc.printf("VL53L0X_GetDeviceInfo:\n");
pc.printf("Device Name : %s\n", vl_deviceInfo.Name);
pc.printf("Device Type : %s\n", vl_deviceInfo.Type);
pc.printf("Device ID : %s\n", vl_deviceInfo.ProductId);
pc.printf("ProductRevisionMajor : %d\n", vl_deviceInfo.ProductRevisionMajor);
pc.printf("ProductRevisionMinor : %d\n\n\n\r", vl_deviceInfo.ProductRevisionMinor);
if ((vl_deviceInfo.ProductRevisionMinor != 1) && (vl_deviceInfo.ProductRevisionMinor != 1))
{
pc.printf("Error expected cut 1.1 but found cut %d.%d\n",
vl_deviceInfo.ProductRevisionMajor, vl_deviceInfo.ProductRevisionMinor);
Status = VL53L0X_ERROR_NOT_SUPPORTED;
}
}
i2c_test();
if (Status == VL53L0X_ERROR_NONE)
{
Status = rangingTest(&vl_device);
}
}
I added some printfs inside the vl53l0x_api.cpp file to check, where exactly the error happened (see attachment). Also the attached text file shows all the printed text (including I2C Verification info).
I really hope it's fixable.
Sincerely, Joel von Rotz
- Labels:
-
Time of flight
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-07-11 8:04 AM
Well done on the I2C verification - that proves you didn't get a wrong value because of a byte-swap issue.
And you did well to debug as far as you did.
There are only 3 places you can get error 50, and they are all in
Status = enable_ref_spads(Dev...)
I've not seen this error, so I have 2 questions:
1) Does it happen on more that one sensor?
2) What happens if you just keep going?
The reason I ask is that the enable_ref_spads() function reads some data in the NVM having to do with the SPADS, and updates it.
It could be something in the NVM is wrong - that would be in the first 2 places.
Or it could be in the last, verification, step. If it's there the chip may run just fine, but the verification check is wrong.
Let me know.
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-07-11 9:35 AM
I got a message that seemed to indicate it's a power rail issue.
Several things to do here.
1) Get a scope and look for a voltage drop. Starving the sensor of current is our most common issue.
2) If you can, hook the sensor to a known power supply. (I use the power pin from the P-Nucleo-53L0A1.)
If that works then you have a direction to go.
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-07-11 10:51 PM
Hi John
I hooked the module board (it's a custom made board based on the schematic of the Adafruit VL53L0X Board) and measured the 3.3V Supply. I didn't notice any voltage drops, the max voltage drop seen was roughly 60mV.
Also I looked at the values in the StaticInit-function (in the vl53l0x_api.cpp file).
/* set the ref spad from NVM */
count = (uint32_t)VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, ReferenceSpadCount);
ApertureSpads = VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, ReferenceSpadType);
I have 9 exactly the same modules, but this code snipplets gives different data back:
4 Boards return
- count = 8
- Aperture Spads = 0
2 Boards return
- count = 7
- Aperture Spads = 0
1 Board returns
- count = 6
- Aperture Spads = 0
1 Board returns
- count = 5
- Aperture Spads = 0
1 Board returns
- count = 17
- Aperture Spads = 0
Should I be somewhat worried?
I can also confirm, that with the Arduino Library from Pololu (updated to the mbed platform), the sensor works without a problem. The hardware seems to work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-07-15 11:08 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-07-16 12:59 AM
Hi John
The pololu library is a reversed engineered library, so I don't have access to these kinds of information or I haven't found a way on how to gain access to said information. But I found out, that the spad init error is happening inside the enable_ref_spads function during the comparison of a spadArray with the checkSpadArray. The first 5 elements are correct, the last one is incorrect.
/* Compare spad maps. If not equal report error. */
while (i < size)
{
if (spadArray[i] != checkSpadArray[i])
{
status = VL53L0X_ERROR_REF_SPAD_INIT;
break;
}
i++;
}
i spadArray checkSpadArray
[0] 0x7F 0x7F
[1] 0x00 0x00
[2] 0x00 0x00
[3] 0x00 0x00
[4] 0x00 0x00
[5] 0x00 0x0E
[6] ? ?
I'm sorry if I waste your time, but I seriously want this to work. I've been working on this thing since last monday, I can't get it to work and I'm starting to have doubts.
- Joel
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-07-18 4:17 AM
Hi John
The pololu library is a reversed engineered library, so I don't have access to these kinds of information or I haven't found a way on how to gain access to said information. But I found out, that the spad init error is happening inside the enable_ref_spads function during the comparison of a spadArray with the checkSpadArray. The first 5 elements are correct, the last one is incorrect.
/* Compare spad maps. If not equal report error. */
while (i < size)
{
if (spadArray[i] != checkSpadArray[i])
{
status = VL53L0X_ERROR_REF_SPAD_INIT;
break;
}
i++;
}
i spadArray checkSpadArray
[0] 0x7F 0x7F
[1] 0x00 0x00
[2] 0x00 0x00
[3] 0x00 0x00
[4] 0x00 0x00
[5] 0x00 0x0E
[6] ? ?
I'm sorry if I waste your time, but I seriously want this to work. I've been working on this thing since last monday, I can't get it to work and I'm starting to have doubts.
- Joel
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-07-24 2:57 PM
it appears the board is trying to read the number of ref-spads and it doesn't get a good answer.
Try calling VL53L0X_set_reference_spads() Prior to trying to init the chip.
But setting the ref spads to something legal - perhaps (3,0) it will force the chip to actually do the refSpad management.
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-07-26 1:59 AM
I somewhat got it to work without the set_reference_spads alternative. I simply removed all the Status comparisons in the example code. I don't know why this works.
Since I've done this there is a little problem now: sometimes the sensor responds with 20mm constantly (for about 5-10 samples).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-07-26 7:36 AM
Doing the RefSpad Calibration is important - but as you saw, the sensor will re-calibrate after a few samples.
Perhaps a better approach is to run the sensor for a while as you have and do a get_reference_spads(). Then write those to your chip in subsequent reboots.
But as you have seen, it does self-correct. Might not always be as quick as 5-10 samples for all conditions however.
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.
