esphome / feature-requests

ESPHome Feature Request Tracker
https://esphome.io/
409 stars 26 forks source link

Add the STM VL53L1X sensor (4m version of the VL53L0X) #836

Open torwag opened 4 years ago

torwag commented 4 years ago

Describe the problem you have/What new integration you would like

I would like to see support for the STM VL53L1X sensor for ranging distances and detecting objects.

Please describe your use case for this integration and alternatives you've tried:

I looked into the integration of the STM VL53L0X in the hope that it would be very similar or even fit. However, looking into the specs it does not unfortunately, there is a complete different set of registers.

Additional context

Polou which afaik is the base for the integration in esphome, offers two distinct projects to integrate both versions.
vl53l0x vl53l1x Albeit I do not know about the state of the vl53l1x project, as I did not yet test it. Unfortunately, even it is said that the esphome integration is based on the pololu/vl53l0x-arduino library, I could not see enough similarities to get into it and to see how something similar could be done with the vl53l1x project. As of now I could not find the specific API description of STM either, I found some C-lib but not yet the I2C communication protocol. A link would be highly appreciated.

rspaargaren commented 4 years ago

As far as I can read there is no difference in controlling 1x and 0x. So I the same library can be used. There is now also option to set 0x in long range mode in esp. For the 1x there are 3 profiles but short medium and long range. But I don't know what is default when u use 0x code.

https://wolles-elektronikkiste.de/vl53l0x-und-vl53l1x-tof-abstandssensoren

torwag commented 4 years ago

I don't think it is the same. The Pololu libs look quite different. Albeit on the discord channel was a post of someone who created a custom component based on the pololu libs for the vl53l1x. Will test this and if it works. It might be not to hard to make this a contribution to main. Reference: https://github.com/jardous/tof_vl53l1x

torwag commented 3 years ago

The implementation of this sensor is a bigger task as it uses 16 bit address registers (whereas the vl53l0x uses 8 bits). As the current implementation of the I2C bus in esphome uses 8bit address registers as standard, it takes more effort to get this unit working. See #875

osos commented 1 year ago

I made a simple setup with small modifications to https://github.com/jardous/tof_vl53l1x.

esphome yaml:

substitutions:
  devicename: distancetest

esphome:
  name: '${devicename}'
  platform: ESP32
  #board: lolin32
  board: mhetesp32minikit
  # https://doc.riot-os.org/group__boards__esp32__mh-et-live-minikit.html
  includes:
    - tof_vl53l1x.h
  libraries:
    - "Wire"
    - "VL53L1x"

wifi:
...
captive_portal:

# Enable logging
logger:
  level: DEBUG

# Enable Home Assistant API
api:

ota:

i2c:
  sda: 21
  scl: 22
  scan: false
  frequency: 400kHz

sensor:
- platform: custom
  lambda: |-
    auto my_VL53L1X_sensor = new VL53L1XCustomSensor();
    my_VL53L1X_sensor->set_update_interval(2000); // define update interval
    App.register_component(my_VL53L1X_sensor);
    return {my_VL53L1X_sensor};
  sensors:
    name: "Distance"
    accuracy_decimals: 0
    unit_of_measurement: "mm"

Placed the tof_vl53l1x.h in same directory as the yaml file. with this slightly modified content:

#include "esphome.h"

#include <Wire.h>
#include <VL53L1X.h>

class VL53L1XCustomSensor : public PollingComponent, public Sensor {

 private:
  VL53L1X tof_sensor;

 public:
  // constructor
  VL53L1XCustomSensor() : PollingComponent(15000) {} // polling every 15s

  void setup() override {
    // This will be called by App.setup()
    Wire.begin();
    Wire.setClock(400000); // use 400 kHz I2C

    tof_sensor.setTimeout(500);
    tof_sensor.setAddress(0x29);
    if (!tof_sensor.init()) {
      ESP_LOGE("VL53L1X custom sensor", "Failed to detect and initialize sensor!");
      return;
    }

    tof_sensor.setDistanceMode(VL53L1X::Long);
    tof_sensor.setMeasurementTimingBudget(250000);  // 1000us = 1ms

    ESP_LOGI("VL53L1X custom sensor", "initialised");

    //tof_sensor.startContinuous(250);  // ms
  }

  void update() override {
    //uint16_t distance_mm = tof_sensor.read(false);
    uint16_t distance_mm = tof_sensor.readSingle();

    if (!tof_sensor.timeoutOccurred()) {
      publish_state(distance_mm);
    } else {
      ESP_LOGE("VL53L1X custom sensor", "Timeout during read().");
    }
  }
};
jcamer commented 1 year ago

I made a simple setup with small modifications to https://github.com/jardous/tof_vl53l1x.

esphome yaml:

substitutions:
  devicename: distancetest

esphome:
  name: '${devicename}'
  platform: ESP32
  #board: lolin32
  board: mhetesp32minikit
  # https://doc.riot-os.org/group__boards__esp32__mh-et-live-minikit.html
  includes:
    - tof_vl53l1x.h
  libraries:
    - "Wire"
    - "VL53L1x"

wifi:
...
captive_portal:

# Enable logging
logger:
  level: DEBUG

# Enable Home Assistant API
api:

ota:

i2c:
  sda: 21
  scl: 22
  scan: false
  frequency: 400kHz

sensor:
- platform: custom
  lambda: |-
    auto my_VL53L1X_sensor = new VL53L1XCustomSensor();
    my_VL53L1X_sensor->set_update_interval(2000); // define update interval
    App.register_component(my_VL53L1X_sensor);
    return {my_VL53L1X_sensor};
  sensors:
    name: "Distance"
    accuracy_decimals: 0
    unit_of_measurement: "mm"

Placed the tof_vl53l1x.h in same directory as the yaml file. with this slightly modified content:

#include "esphome.h"

#include <Wire.h>
#include <VL53L1X.h>

class VL53L1XCustomSensor : public PollingComponent, public Sensor {

 private:
  VL53L1X tof_sensor;

 public:
  // constructor
  VL53L1XCustomSensor() : PollingComponent(15000) {} // polling every 15s

  void setup() override {
    // This will be called by App.setup()
    Wire.begin();
    Wire.setClock(400000); // use 400 kHz I2C

    tof_sensor.setTimeout(500);
    tof_sensor.setAddress(0x29);
    if (!tof_sensor.init()) {
      ESP_LOGE("VL53L1X custom sensor", "Failed to detect and initialize sensor!");
      return;
    }

    tof_sensor.setDistanceMode(VL53L1X::Long);
    tof_sensor.setMeasurementTimingBudget(250000);    // 1000us = 1ms

    ESP_LOGI("VL53L1X custom sensor", "initialised");

    //tof_sensor.startContinuous(250);    // ms
  }

  void update() override {
    //uint16_t distance_mm = tof_sensor.read(false);
    uint16_t distance_mm = tof_sensor.readSingle();

    if (!tof_sensor.timeoutOccurred()) {
      publish_state(distance_mm);
    } else {
      ESP_LOGE("VL53L1X custom sensor", "Timeout during read().");
    }
  }
};

I have tried the steps you have, but when I go to install I am getting the error below:

In file included from src/tof_vl53l1x.h:4:0, from src/main.cpp:23: src/VL53L1X.h: In member function 'virtual float MyCustomSensor::get_setup_priority() const': src/VL53L1X.h:6:54: error: 'XXXX' is not a member of 'esphome::setup_priority' float get_setup_priority() const override { return esphome::setup_priority::XXXX; } ^ In file included from src/main.cpp:23:0: src/tof_vl53l1x.h: At global scope: src/tof_vl53l1x.h:10:3: error: 'VL53L1X' does not name a type VL53L1X tof_sensor; ^ src/tof_vl53l1x.h: In member function 'virtual void VL53L1XCustomSensor::setup()': src/tof_vl53l1x.h:21:5: error: 'tof_sensor' was not declared in this scope tof_sensor.setTimeout(500); ^ src/tof_vl53l1x.h:28:32: error: 'VL53L1X' has not been declared tof_sensor.setDistanceMode(VL53L1X::Long); ^ src/tof_vl53l1x.h: In member function 'virtual void VL53L1XCustomSensor::update()': src/tof_vl53l1x.h:38:28: error: 'tof_sensor' was not declared in this scope uint16_t distance_mm = tofsensor.readSingle();

What does your VL53L1X.h file look like?

thanks,

John

edit: I found the file from pololu and used it, it works. (https://github.com/pololu/vl53l1x-arduino/blob/master/VL53L1X.h)

stanogustafik commented 2 months ago

I tried this solution, but it just doesn´t work... please would you consider to build platform for these devices? there are no other sensors detecting distance to 400cm... this is from my logs after trying the solution by @osos :

`INFO ESPHome 2024.6.3 INFO Reading configuration /config/esphome/my-sensor.yaml... INFO Generating C++ source... INFO Compiling app... Processing my-sensor (board: esp32dev; framework: arduino; platform: platformio/espressif32@5.4.0)

Removing unused dependencies... Library Manager: Removing VL53L1X @ 1.3.1 INFO Removing VL53L1X @ 1.3.1 Library Manager: VL53L1X@1.3.1 has been removed! INFO VL53L1X@1.3.1 has been removed! HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash

thank you

frederickjh commented 1 month ago

The abstraction for reading and writing to 16 bit I2C registers was added to esphome/esphome#4844 and merged. #875 was closed as a result of this. Hopefully this paves the way for support for the VL53L1x to be added.

baerrs commented 1 month ago

I would love to see this added as well.

soldierkam commented 2 weeks ago

My WIP version of the component: https://github.com/soldierkam/vl53l1x_sensor

clomads commented 13 hours ago

@soldierkam just loaded it on one of my ESP32_C3 dev boards and it's working great at 100ms update_interval in SHORT mode.