Saurabh Sakhare
Saurabh Sakhare

Reputation: 11

VL53L0x sensor Ranging error. How to solve the error?

I'm trying to interface vl53l0x sensor with my atSamE51A19 controller. I can send the data to the sensor. As it has established connection I send identification code and it responds. But further initialization and ranging is not working.

I'm using stm library implementation on my sam board. [stmArduinoLib][1] The only changes I made is in the read write functions. It was using stm base functions but I'm using different functions.

    /****************** Write and read functions from I2C *************************/

VL53L0X_Error VL53L0X::VL53L0X_WriteMulti(VL53L0X_DEV Dev, uint8_t index, uint8_t *pdata, uint32_t count)
{
    int status;

    status = VL53L0X_I2CWrite(index, pdata, (uint16_t) count);
    if (status == 0)
    {
        status = VL53L0X_ERROR_CONTROL_INTERFACE;
    }
    else
    {
        status = VL53L0X_ERROR_NONE;
    }
    return status;      
}

VL53L0X_Error VL53L0X::VL53L0X_ReadMulti(VL53L0X_DEV Dev, uint8_t index, uint8_t *pdata, uint32_t count)
{
    int status;

    if (count >= VL53L0X_MAX_I2C_XFER_SIZE)
    {
        status = VL53L0X_ERROR_INVALID_PARAMS;
    }

    status = VL53L0X_I2CRead(index, pdata, (uint16_t) count);

    return status;  
}

VL53L0X_Error VL53L0X::VL53L0X_WrByte(VL53L0X_DEV Dev, uint8_t index, uint8_t data)
{
    int status;

    status = WriteRegister(index, data);    //VL53L0X_I2CWrite(index, &data, 1);

    if (status == 0)
    {
        status = VL53L0X_ERROR_CONTROL_INTERFACE;
    }
    else
    {
        status = VL53L0X_ERROR_NONE;
    }

    return status;  
}

VL53L0X_Error VL53L0X::VL53L0X_WrWord(VL53L0X_DEV Dev, uint8_t index, uint16_t data)
{
    int status;
    int32_t status_int;
    alignas(2) uint8_t buffer[2];

    buffer[0] = data >> 8;
    buffer[1] = data & 0x00FF;

    status_int = VL53L0X_I2CWrite(index, (uint8_t*) buffer, 2);

    // buffer[0] = MSB
    // buffer[1]
    // buffer[2]
    // buffer[3] = LSB
    if (status_int == 0)
    {
        status = VL53L0X_ERROR_CONTROL_INTERFACE;
    }
    else
    {
        status = VL53L0X_ERROR_NONE;
    }

    return status;  
}

VL53L0X_Error VL53L0X::VL53L0X_WrDWord(VL53L0X_DEV Dev, uint8_t index, uint32_t data)
{
    int status;
    int32_t status_int;
    alignas(2) uint8_t buffer[4];

    buffer[0] = (data >> 24) & 0xFF;                // MSB
    buffer[1] = (data >> 16) & 0xFF;
    buffer[2] = (data >> 8) & 0xFF;
    buffer[3] = (data >> 0) & 0xFF;                 // LSB
    status_int = VL53L0X_I2CWrite(index, buffer, 4);

    if (status_int == 0)
    {
        status = VL53L0X_ERROR_CONTROL_INTERFACE;
    }
    else
    {
        status = VL53L0X_ERROR_NONE;
    }

    return status;  
}

VL53L0X_Error VL53L0X::VL53L0X_RdByte(VL53L0X_DEV Dev, uint8_t index, uint8_t *data)
{
    int status = VL53L0X_ERROR_NONE;

    status = ReadRegister(index, *data);    //
    if (status)
    {
        status = VL53L0X_ERROR_NONE;
        return status;
    }
    else
    {
        status = VL53L0X_ERROR_CONTROL_INTERFACE;
    }
    return status;
}

VL53L0X_Error VL53L0X::VL53L0X_RdWord(VL53L0X_DEV Dev, uint8_t index, uint16_t *data)
{
    int status = 0;
    uint8_t buffer[2] =
    { 0, 0 };

    status = VL53L0X_I2CRead(index, buffer, 2);
    if (status == 0)
    {
        *data = (uint16_t) (buffer[0] << 8) | (buffer[1] & 0xFF);       // | ? +
    }

    return status;          
}

VL53L0X_Error VL53L0X::VL53L0X_RdDWord(VL53L0X_DEV Dev, uint8_t index, uint32_t *data)
{
    int status;
    uint8_t buffer[4] =
    { 0, 0, 0, 0 };

    status = VL53L0X_I2CRead(index, buffer, 4);
    if (!status)                                    // use OR
    {
        *data = ((uint32_t) buffer[0] << 24) | ((uint32_t) buffer[1] << 16) | ((uint32_t) buffer[2] << 8) | (uint32_t) buffer[3];
    }
    return status;

}

VL53L0X_Error VL53L0X::VL53L0X_UpdateByte(VL53L0X_DEV Dev, uint8_t index, uint8_t AndData, uint8_t OrData)
{
    int status;
    uint8_t buffer = 0;

    /* read data direct onto buffer */
    status = VL53L0X_I2CRead(index, &buffer, 1);
    if (!status)
    {
        buffer = (buffer & AndData) | OrData;
        status = VL53L0X_I2CWrite(index, &buffer, (uint8_t) 1);
    }

    if (status == 0)
    {
        status = VL53L0X_ERROR_CONTROL_INTERFACE;
    }
    else
    {

        status = VL53L0X_ERROR_NONE;
    }
    return status;
}

VL53L0X_Error VL53L0X::VL53L0X_I2CWrite(uint8_t RegisterAddr, uint8_t *pBuffer, uint16_t NumByteToWrite)
{
    return WriteRegisters(RegisterAddr, pBuffer, NumByteToWrite);
}

VL53L0X_Error VL53L0X::VL53L0X_I2CRead(uint8_t RegisterAddr, uint8_t *pBuffer, uint16_t NumByteToRead)
{
    alignas(2) uint8_t vpBuffer[5];
    /*  dev_i2c->beginTransmission(((uint8_t) (((DeviceAddr) >> 1) & 0x7F)));
     */

    if (ReadRegisters(RegisterAddr, vpBuffer, NumByteToRead))
    {
        pBuffer = vpBuffer;
        return 0;
    }

    return 1;
}

In this functions I'm not sending device address everytime just sending the index and data. In constructor only I've set the address once. The only error I'm getting when I use Status = VL53L0X_PerformRefSpadManagement(Device, &refSpadCount, &isApertureSpads); This function. In initialization. Don't know how to solve this issue. Tried to change the mode to continous that didn't help. Note: the sensor is working fine with arduino. [1]: https://github.com/stm32duino/VL53L0X

Upvotes: 0

Views: 1356

Answers (1)

KhalGary
KhalGary

Reputation: 11

I found a new possible solution to this problem, as I spent 2 days to solve it, I feel that I need to share it with you guys. Here is the summary of solutions:

  1. Powering problem 1: add a 50ms delay in the setup function (before the sensor init, obviously). This way, the Vin will have time enough to reach the level needed by the sensor, as explained in a previous message (ocrdu)
  2. Powering problem 2: This sensor demands more than others, normally the 5V pin of your board will do it better than the 3v3. If there are many sensors connected at the same time, disconnect all of them to check whether they are using the power our vl53l0x needs.
  3. Powering problem 3: If you feed it with an external source, unify grounds with the board, don't forget it
  4. SCL - SDA weak signals: add a pullup (2k2 - 4k7 from each channel to vin), this way the signals will perform better, that could be the problem
  5. Soldering problem: Make sure that each header pin is well soldered. I've found many cases of poor soldering. The tiny pads don't help. It is advisable to check continuity with a multimeter between the headers and the pads where they should be connected
  6. XSHUT not pulled up: My problem, this was that AZDelivery board says that it has a pull up in XSHUT (which works like an enable). But it could either be false, or badly implemented. Xshut needs to be high, 3v3/5v, otherwise, the sensor won't work. Bridge the XSHUT to Vin or implement a pull up and the problem will be solved.
  • I am using adafruit's library 1.1.2, and it works, with pullups, without pullups, connected to 5V and also connected to 3V3, with the 50ms delay, and connecting XSHUT to high (3V3 / Vin)
  • My board is vl53l0x from AZDelivery (5€ amazon)
  • I have tested the sensor with arduino nano and with ESP32, both work fine

Hope you guys find this useful <3

Upvotes: 1

Related Questions