nestorit/vl6180x

0.0.1

Latest
uploaded 17 hours ago
Native ESP-IDF I2C driver for the VL6180X proximity and ambient light sensor

Readme

# VL6180X ESP-IDF Driver

Production-oriented I2C driver for the ST VL6180X Time-of-Flight proximity
sensor with integrated ambient light sensing (ALS), written for ESP-IDF
5.x/6.x using the new I2C master API (`driver/i2c_master.h`). No Arduino
dependencies.

All register semantics follow the VL6180X datasheet (DocID026171 Rev 7) and
the VL6180 datasheet (DocID024986 Rev 14). The API syntax matches the
[LIS331DLH driver](https://github.com/iot-academy/esp-lis331), so both sensors
can be used on the same I2C bus in one product.

## Features

- Native ESP-IDF I2C master driver (`vl6180x_create()`, always available);
- optional ESP-IoT-Solution `i2c_bus` transport (`vl6180x_create_i2c_bus()`),
  enabled with `CONFIG_VL6180X_USE_I2C_BUS=y`;
- device identification via MODEL_ID (0xB4) at creation, plus a firmware
  boot-up wait;
- single-shot and continuous ranging (distance in mm, 0..255);
- range status / error code and raw range reads;
- signal rate read (9.7 fixed point, MCPS);
- ambient light sensing in lux (VL6180X);
- range and ALS interrupt configuration and status;
- offset and crosstalk calibration;
- runtime I2C address change for multi-sensor products.

## Hardware connection

- SDA -> GPIO21, SCL -> GPIO22 (defaults in the examples).
- ESP32 internal pull-ups are disabled by the examples, so external pull-up
  resistors are required on both I2C lines.
- The 7-bit I2C address is fixed at `0x29` (can be changed at runtime with
  `vl6180x_set_address()`).
- SCL clock must stay within 100..400 kHz.

## Example usage

```c
#include "driver/i2c_master.h"
#include "vl6180x.h"

i2c_master_bus_config_t bus_config = {
    .i2c_port = I2C_NUM_0,
    .sda_io_num = 21,
    .scl_io_num = 22,
    .clk_source = I2C_CLK_SRC_DEFAULT,
    .glitch_ignore_cnt = 7,
    .flags.enable_internal_pullup = false,
};
i2c_master_bus_handle_t bus;
ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &bus));

vl6180x_config_t config = {
    .i2c_clock_hz = 100000,
    .max_convergence_time_ms = 49,
    .averaging_sample_period = 48,
    .minimal_init = false,  /* set true for clones that need a reduced init */
};
vl6180x_handle_t sensor;
ESP_ERROR_CHECK(vl6180x_create(bus, VL6180X_DEFAULT_I2C_ADDR, &config, &sensor));

uint8_t range_mm;
ESP_ERROR_CHECK(vl6180x_range_read(sensor, &range_mm));

vl6180x_range_status_t status;
ESP_ERROR_CHECK(vl6180x_range_get_status(sensor, &status));
/* status.error_code == VL6180X_RANGE_ERROR_NONE when the reading is valid. */
```

## Data interpretation

- `vl6180x_range_read()` returns the final range in **millimeters** (8-bit,
  0..255). The value is only meaningful when the range status error code is
  `VL6180X_RANGE_ERROR_NONE`; `VL6180X_RANGE_ERROR_MAX_CONVERGENCE` (7) means no
  target was detected.
- `vl6180x_range_get_signal_rate()` returns the return signal rate as a 9.7
  fixed-point value; divide by 128 to get MCPS.
- `vl6180x_als_read()` returns illuminance in **lux**:
  `lux = lux_resolution * (count / gain) * (100 ms / integration_period)`.
  The factory `lux_resolution` is 0.32 lux/count at gain 1 and 100 ms
  integration (calibrated without glass); recalibrate after mounting cover
  glass with `vl6180x_als_set_lux_resolution()`.

## Ranging modes

- Single shot: `vl6180x_range_read()`.
- Continuous: `vl6180x_range_start_continuous(handle, period_ms)` (period
  clamped to 10..2540 ms), then `vl6180x_range_read_continuous()` which returns
  `ESP_ERR_NOT_FINISHED` when no new sample is ready.

## Interrupts

- `vl6180x_interrupt_config()` selects the source (range or ALS) and mode
  (disabled, level low/high, out of window, new sample ready).
- `vl6180x_range_set_thresholds()` sets the range threshold window.
- `vl6180x_get_interrupt_status()` reports the pending events,
  `vl6180x_clear_interrupt()` clears them.

## Calibration

- `vl6180x_set_range_offset()` writes the part-to-part range offset (mm).
- `vl6180x_set_crosstalk_rate()` writes the crosstalk compensation rate (9.7
  fixed point, MCPS).

## Limitations

- **ALS and interleaved mode are VL6180X features.** The corresponding
  registers are not documented in the base VL6180 datasheet, so the ALS
  functions are only guaranteed on a VL6180X.
- **Ranging compatibility with the base VL6180 and clones:** a genuine
  VL6180X ranges with the default (full) initialization. Some VL6180-family
  devices (e.g. clones) need a reduced initialization; enable it with
  `vl6180x_config_t.minimal_init = true` in the creation config. One defective
  unit that reports a persistent VCSEL continuity error (range error code 1)
  could not be made to range even with `minimal_init`.
- The driver does not implement the upscale (extended range) feature, history
  buffer reads, or the wrap-around filter.
- The driver is not thread-safe; a single handle should be used from one task
  (the ESP-IDF I2C master driver serializes bus transactions, but the driver
  keeps no per-sensor state lock).
- The application owns the I2C bus: the driver adds a device to it and never
  deletes the bus.

## Using VL6180X together with LIS331DLH

Both drivers share the same API conventions and can be attached to the same
I2C bus in one product:

```c
i2c_master_bus_handle_t bus;
ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &bus));

lis331_handle_t lis;
ESP_ERROR_CHECK(lis331_create(bus, LIS331_I2C_ADDR_SA0_GND, NULL, &lis));

vl6180x_handle_t vl;
ESP_ERROR_CHECK(vl6180x_create(bus, VL6180X_DEFAULT_I2C_ADDR, NULL, &vl));
```

The default addresses do not collide (LIS331DLH: 0x18/0x19, VL6180X: 0x29).
To use several VL6180X on one bus, power the sensors one at a time and change
each address with `vl6180x_set_address()`.

## Examples

Both examples build with `idf.py build` from their directories after exporting
an ESP-IDF environment:

- `examples/basic` - native ESP-IDF I2C master driver;
- `examples/i2c_bus` - ESP-IoT-Solution `i2c_bus` transport (requires
  `CONFIG_VL6180X_USE_I2C_BUS=y`, the dependency is pulled automatically from
  the component registry).

## Tests

`tests/register_encoding` contains host-side unit tests for the register
encoding and initialization sequence. Run them with `make run`.

## Dependencies

- `espressif/cmake_utilities` (always);
- `espressif/i2c_bus` (conditional on `CONFIG_VL6180X_USE_I2C_BUS`, pulled from
  the component registry when enabled).

## License

This project is licensed under the MIT License - see the `LICENSE` file.

Links

To add this component to your project, run:

idf.py add-dependency "nestorit/vl6180x^0.0.1"

download archive

Stats

  • Archive size
    Archive size ~ 20.87 KB
  • Downloaded in total
    Downloaded in total 0 times
  • Downloaded this version
    This version: 0 times

Badge

nestorit/vl6180x version: 0.0.1
|