Lost + Found VL53L1X time-of-flight distance sensor driver library for Raspberry Pi Pico C SDK
  • C 98.9%
  • Python 0.7%
  • CMake 0.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-02 09:36:25 -07:00
include Initial commit: Reusable VL53L1X time-of-flight distance sensor driver library for Raspberry Pi Pico C SDK 2026-08-02 09:36:25 -07:00
src Initial commit: Reusable VL53L1X time-of-flight distance sensor driver library for Raspberry Pi Pico C SDK 2026-08-02 09:36:25 -07:00
CMakeLists.txt Initial commit: Reusable VL53L1X time-of-flight distance sensor driver library for Raspberry Pi Pico C SDK 2026-08-02 09:36:25 -07:00
conanfile.py Initial commit: Reusable VL53L1X time-of-flight distance sensor driver library for Raspberry Pi Pico C SDK 2026-08-02 09:36:25 -07:00
LICENSE.txt Initial commit: Reusable VL53L1X time-of-flight distance sensor driver library for Raspberry Pi Pico C SDK 2026-08-02 09:36:25 -07:00
README.md Initial commit: Reusable VL53L1X time-of-flight distance sensor driver library for Raspberry Pi Pico C SDK 2026-08-02 09:36:25 -07:00

lf-vl53l1x

Reusable VL53L1X time-of-flight distance sensor driver library for the Raspberry Pi Pico C SDK, packaged as a Conan package. This driver is based on the C++ VL53L1X Pico driver by George Tchelidze, derived from the Pololu VL53L1X Arduino library (Copyright STMicroelectronics & Pololu Corp) and licensed under the BSD 3-Clause License.

This is part of the Lost + Found suite of projects.

🛠️ Usage with CMake

Copy the driver directory into your project as a subdirectory:

add_subdirectory(lib/lf-vl53l1x)

target_link_libraries(your_project PRIVATE
    lf-vl53l1x
)

And in your C/C++ code:

#include "lf_vl53l1x.h"

🔌 Hardware Setup

Connect the VL53L1X breakout board I2C pins and XSHUT pin to your Raspberry Pi Pico:

  • Pico GP4 (SDA) <-> Breakout SDA
  • Pico GP5 (SCL) <-> Breakout SCL
  • Pico GND <-> Breakout GND
  • Pico GP7 (GPIO7) <-> Breakout XSHUT / SHTD (for hardware reset/shutdown)
  • Pico 3V3 OUT <-> Breakout VIN / VCC

(Note: Pins can be configured on any available Pico I2C bus and GPIOs).

💡 Example

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "hardware/gpio.h"
#include "lf_vl53l1x.h"

// Hardware configuration
#define I2C_PORT      i2c0
#define PIN_SDA       4      // Pico Physical Pin 6 (Default I2C0 SDA)
#define PIN_SCL       5      // Pico Physical Pin 7 (Default I2C0 SCL)
#define PIN_XSHUT     7      // Pico Physical Pin 10 (GPIO7) for sensor shutdown/reset
#define I2C_BAUDRATE  400000 // 400 kHz fast mode

int main() {
    // Initialize standard library I/O (USB CDC and UART)
    stdio_init_all();
    sleep_ms(2000);

    printf("Initializing VL53L1X Distance Sensor...\n");

    // 1. Hardware Reset via XSHUT pin
    gpio_init(PIN_XSHUT);
    gpio_set_dir(PIN_XSHUT, GPIO_OUT);
    
    // Pull XSHUT low to reset/power-down the sensor
    gpio_put(PIN_XSHUT, 0);
    sleep_ms(20);
    
    // Drive XSHUT high to enable the sensor
    gpio_put(PIN_XSHUT, 1);
    sleep_ms(20); // Wait for the sensor boot completion

    // 2. Initialize I2C hardware
    i2c_init(I2C_PORT, I2C_BAUDRATE);
    gpio_set_function(PIN_SDA, GPIO_FUNC_I2C);
    gpio_set_function(PIN_SCL, GPIO_FUNC_I2C);
    gpio_pull_up(PIN_SDA);
    gpio_pull_up(PIN_SCL);

    // The default I2C address for VL53L1X is 0x29
    const uint8_t sensor_address = 0x29;

    // 3. Instantiate and initialize the VL53L1X sensor structure
    lf_vl53l1x_t sensor;
    lf_vl53l1x_init_struct(&sensor, I2C_PORT, sensor_address, 1000);

    printf("Initializing sensor software...\n");
    if (!lf_vl53l1x_init(&sensor, true)) {
        printf("[ERROR] Failed to initialize VL53L1X software settings!\n");
        while (true) {
            sleep_ms(1000);
        }
    }
    printf("[SUCCESS] Sensor software initialized successfully.\n");

    // 4. Configure sensor settings
    // Distance modes: Short, Medium, Long.
    lf_vl53l1x_set_distance_mode(&sensor, LF_VL53L1X_DISTANCE_MODE_LONG);
    
    // Timing budget: time spent taking a single measurement. Longer time = higher accuracy.
    // Standard choices: 20ms, 33ms, 50ms, 100ms, 200ms, 500ms.
    lf_vl53l1x_set_measurement_timing_budget(&sensor, 50000); // 50ms timing budget

    // Start continuous ranging measurements.
    lf_vl53l1x_start_continuous(&sensor, 50);
    printf("Started continuous ranging\n\n");

    // 5. Ranging Loop
    while (true) {
        // Read distance (blocking read)
        uint16_t distance_mm = lf_vl53l1x_read(&sensor, true);
        lf_vl53l1x_range_status_t status = sensor.ranging_data.range_status;

        if (lf_vl53l1x_timeout_occurred(&sensor)) {
            printf("[TIMEOUT] Sensor ranging read timed out!\n");
        } else {
            const char* status_str = lf_vl53l1x_range_status_to_string(status);
            
            if (status == LF_VL53L1X_RANGE_VALID) {
                printf("Distance: %4d mm | Status: %s\n", distance_mm, status_str);
            } else {
                printf("Distance: %4d mm | Status: %s (Warning/Fail)\n", distance_mm, status_str);
            }
        }

        sleep_ms(100);
    }

    return 0;
}

⚙️ Prerequisites: Setting up Conan with uv

To install the Conan CLI package manager securely and in an isolated environment on your system, it is recommended to use uv:

# Install Conan globally as an isolated tool
uv tool install conan

This makes the conan executable available on your PATH immediately and keeps your system's Python packages clean.


📦 Consumption via Forgejo Conan Registry

The package is hosted and distributed through the Forgejo Conan Package Registry at git.clowderlabs.com.

1. Add the Remote Registry

Add the remote repository to your local Conan configuration:

conan remote add clowder https://git.clowderlabs.com/api/packages/blong/conan

2. Authenticate

Log in using your personal access token:

conan remote login -p <your_token> clowder blong

3. Add to your Project

Add the dependency to your conanfile.txt (or conanfile.py):

[requires]
lf-vl53l1x/0.0.1

Then install the dependencies:

conan install . --output-folder=build --build=missing

Expected Output of conan install

When running conan install, Conan downloads the source package from your remote Forgejo registry, unpacks it locally, and generates the necessary target files for CMake:

======== Computing dependency graph ========
lf-vl53l1x/0.0.1: Not found in local cache, looking in remotes...
lf-vl53l1x/0.0.1: Checking remote: clowder
Connecting to remote 'clowder' with user 'blong'
lf-vl53l1x/0.0.1: Downloaded recipe revision 8809dc809c8e0261b8f0ab07c5e434dd

======== Computing necessary packages ========
Requirements
    lf-vl53l1x/0.0.1#8809dc809c8e0261b8f0ab07c5e434dd:da39a3ee5e6b4b0d3255bfef95601890afd80709 - Build

======== Installing packages ========
lf-vl53l1x/0.0.1: Sources downloaded from 'clowder'

-------- Installing package lf-vl53l1x/0.0.1 (1 of 1) --------
lf-vl53l1x/0.0.1: Building from source
lf-vl53l1x/0.0.1: Package lf-vl53l1x/0.0.1:da39a3ee5e6b4b0d3255bfef95601890afd80709
>>> Source step
lf-vl53l1x/0.0.1: Copying sources to build folder
>>> Package step
Calling package()
package(): Packaged 1 '.c' file: lf_vl53l1x.c
package(): Packaged 1 '.txt' file: CMakeLists.txt
package(): Packaged 1 '.h' file: lf_vl53l1x.h
Package 'da39a3ee5e6b4b0d3255bfef95601890afd80709' created

======== Finalizing install (deploy, generators) ========
Generator 'CMakeDeps' calling 'generate()'
CMakeDeps necessary find_package() and targets for your CMakeLists.txt
    find_package(lf-vl53l1x)
    target_link_libraries(... lf-vl53l1x::lf-vl53l1x)
Install finished successfully

🛠️ Local Testing

To test building and exporting this Conan package locally without uploading, run:

conan export .

This will register lf-vl53l1x/0.0.1 in your local Conan cache for offline testing.