mrtoy-me / esphome-my-components

esphome components by me
3 stars 3 forks source link

Which variant of vl53l1x is the one to use? #5

Open rotdrop opened 4 months ago

rotdrop commented 4 months ago

Thank you!

mrtoy-me commented 4 months ago

Use "vl53l1x_allversions_esphome" I have been updating this one - I just committed some code updates. Eventually I plan to submit this one as a esphome PR.

Let me know if you have any issues. Brett

diplix commented 1 month ago

i recently tried out the vl53l1x_allversions_esphome version. it works very accuratly, almost no flapping with a 2.20 m distance. however, after a couple of days the sensor stopped updating and after a restart the sensor was marked as failed. restarting the ESP did not relieve the issue, i had to power cycle the esp to recover from the marked as failed error. that day after a couple of hours the same happened.

so i reverted back to a custom component that i put together a while ago and that is much less accurate (measurements vary ±40 mm). i chose much longer timeouts and timing budget and a lower updates rate, which probably resulty in less accuracy. but the component served me well over the last couple of years.

it’s very much possible that i have a faulty vl53l1x, but like i said, if i use it with less frequent polling and longer timing budget, it works continuously without errors over years.

in my custom component i also try to soft reset and re-initialize the sensor if to many timouts were registered, i don’t see anything like that in your component.

do your vl53l1x work flawlessly with the vl53l1x_allversions_esphome version?

mrtoy-me commented 1 month ago

Thanks for getting in touch. It worked fine for my shorter testing but I don't have one installed yet for long term assessment. I am pretty busy at the moment but will try to setup one and see how it performs for a week... and let you know. I made a few changes 3 months ago - do you have the latest version and I am interested in the mark failed errors and your yaml config. Not sure what you mean by timeouts? It would be good to exchange info - I am on discord if you use that otherwise let me know how best to communicate. On discord I am ... mrtoy.au

diplix commented 1 month ago

i’ve adapted this lib into a https://github.com/pololu/vl53l1x-arduino/ custom sensor and this library has a function bool VL53L1X::timeoutOccurred() https://github.com/pololu/vl53l1x-arduino/blob/8f21d608af00b42dc8776cfdf5ce935b45d2387d/VL53L1X.cpp#L636

which i use to count timeouts (after calling the read() function). if there are > 80 timeouts counted i perform a soft reset

    tof_sensor.writeReg(VL53L1X::SOFT_RESET, 0x00);
    delay(100);
    tof_sensor.writeReg(VL53L1X::SOFT_RESET, 0x01);
    delay(100),

and re-initialise the sensor.

it’s badly written (based on the continious exaple code) but short enough to post it inline (and it works for me).

#include "esphome.h"

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

VL53L1X tof_sensor;

static int num_timeouts = 0;

class MyCustomSensor : public PollingComponent, public Sensor {
 public:
  // constructor
  //MyCustomSensor() : PollingComponent(15000) {} // polling every 15s
  MyCustomSensor() : PollingComponent(3000) {} // polling every 3s

  void setup() override {
    // This will be called by App.setup()
    Wire.begin(21, 22);
    //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!");
      //while (1);
    }

    tof_sensor.setDistanceMode(VL53L1X::Long);
    //tof_sensor.setDistanceMode(VL53L1X::Medium); 
    //tof_sensor.setMeasurementTimingBudget(50000);
    tof_sensor.setMeasurementTimingBudget(66000);

    //tof_sensor.startContinuous(50);
    tof_sensor.startContinuous(200);
  }

  void update() override {
    uint16_t mm = tof_sensor.read();

    if (!tof_sensor.timeoutOccurred()) {
      publish_state(mm);
      num_timeouts = 0;
    } else {
      ESP_LOGE("VL53L1X custom sensor", "Timeout during read().");
      num_timeouts += 1;
    }
    if (num_timeouts > 80 ) {
      num_timeouts = 0;
      ESP_LOGE("VL53L1X custom sensor", "more than 100 timouts - trying to reset");
      reset_sensor();
    }
  }

  void reset_sensor() {
    tof_sensor.writeReg(VL53L1X::SOFT_RESET, 0x00);
    delay(100);
    tof_sensor.writeReg(VL53L1X::SOFT_RESET, 0x01);
    delay(100),

    tof_sensor.setTimeout(500);
    tof_sensor.setAddress(0x29);

    if (!tof_sensor.init()) {
      ESP_LOGE("VL53L1X custom sensor", "Failed to detect and initialize sensor after trying to reset sensor");
      //while (1);
    }

    tof_sensor.setDistanceMode(VL53L1X::Long);
    tof_sensor.setMeasurementTimingBudget(50000);

    tof_sensor.startContinuous(50);

  }

};
mrtoy-me commented 1 month ago

Testing an esp32 now ok after 8hrs so will wait and see how it goes after a few days. Have you updated to the latest version. I have quite extensive error checks on failure, what is the error log when sensor is marked failed - that will help track down the problem.

mrtoy-me commented 1 month ago

Also only one version now so no confusion

diplix commented 1 month ago

yes, i tested the latest version, just rechecked again. the errors said, that „Sensor does not have VL53L1X or VL53L4CD sensor ID !“ — until i power cycled. „my“ version has been running now for 3-4 days without failure, but also has not counted any timeouts. i suspect the more generous timing budget and/or less frequent polling (3s) go a little easier on the sensor. although one might think, thats what the sensor is built for, measururing frequently and precisely. thats why i won’t rule out, that my sensor might be faulty …

mrtoy-me commented 1 month ago

@diplix You said “until I power cycled” What happened after that ?

Could you post your yaml - it’s hard to help without that:)

mrtoy-me commented 1 month ago

i’ve adapted this lib into a https://github.com/pololu/vl53l1x-arduino/ custom sensor

I did look at the Pololu library when I was developing the component and it did give me some clues but decided to adapt the official library. Interesting about the read timeouts, I have not seen any errors like this.

diplix commented 1 month ago

when the sensor failed, it keept failing even after resetting the esp. after power cycling (pulling the power supply from the esp), everything is fine after powering it up again, the sensor is initializing and measuring. this indicates IMHO, that rebooting the esp does not reset the sensor.

yeah, i havent seen those timeout in while, too. but that might change if i set a lower timing budget and/or polling rate. i think that was the reason that i set a higher timing budget, to get rid of those timing errors. and again, i won’t rule out, that my sensor might be faulty or oversensitive.


yaml for my component (working)

esphome:
  name: $devicename
  friendly_name: "${friendly_name}"
  comment: "${description}"
  platformio_options:
    lib_ldf_mode: chain+
  includes:
    - external_components/tof/tof_vl53l1x.h
  libraries:
    - file:///config//external_components/tof/lib/vl53l1x

i2c:
   - id: bus_a
     sda: 21
     scl: 22
     scan: true
  - platform: custom
    lambda: |-
      auto my_sensor = new MyCustomSensor();
      App.register_component(my_sensor);
      return {my_sensor};
    sensors:
      - name: Distance raw
        id: vl53l1x_value_raw
        accuracy_decimals: 0
        #unit_of_measurement: "mm"
        internal: true

yaml for your component (failing after 1-2 days or earlier)

external_components:
  - source:
      type: local
      path: external_components/mrtoy-me_esphome_components/components
    components: [vl53l1x]

i2c:
   - id: bus_a
     sda: 21
     scl: 22
     scan: true
  - platform: vl53l1x
    i2c_id: bus_a
    distance_mode: long
    update_interval: 1s # 60s
    distance:
      id: vl53l1x_value_raw
      internal: True
      on_value: []
    range_status:
      name: "Range Status"
      id: vl53l1x_range_status
      entity_category: "diagnostic"
      icon: mdi:list-status
      internal: true
mrtoy-me commented 1 month ago

Are you using IDF or Arduino framework ?

diplix commented 1 month ago

Are you using IDF or Arduino framework ?

default, so arduino framework. and it’s an esp32

esp32:
  board: nodemcu-32s 
mrtoy-me commented 1 month ago

I have been running mine and it seems to have stopped after a few days. Doing some more testing and searching if others have had similar issues - their should be no reason the component code failed after a few days so it is either the esp i2c or sensor failing. Doing some more testing but it takes a while when the fail takes a few days and I need to see if I can see errors when the fail occurs.

Did you use the previous all versions component and did it work ok or fail after a while as well?

diplix commented 1 month ago

no, i just used my version for at least 1 or 2 years without problems, but wanted to future proof my esp code and tried ot your (newer) version. i really suspect that the sensor doesn’t like a permanent low timing budget. as i recall, i also had problems with my version, until i set it to a higher value (66000 ← i guess those are microseconds, not milliseconds)

mrtoy-me commented 1 month ago

I will keep working on it because I want it to be stable - 66000us is still low compared to my component I am using 500ms - the st library I have converted can be set to 15, 20, 33, 50, 100, 200 or 500ms timing budget. I am going to look closer at the Pololu library though since it is working for you. I did notice that your code is running at a faster i2c speed of 400 compared to the esphome default of 50 - but that should make any i2c issues worse? If I think I have it working more stably I will let you know and maybe you would give my component another try.

mrtoy-me commented 1 month ago

Have not forgotten - I have been making incremental changes and testing along the way but it takes a few days to test each time to see if it fails - I am not on my usual test system and I am getting some fails after a while so still working on it.

I am also testing a sensor soft reset at startup which seems to be working fine.

Will let you know when I have something.

mrtoy-me commented 2 weeks ago

@diplix OK so I have changed quite a few things internally but what seems to have fixed the issue with the sensor stopping after a few days is running at a higher i2c frequency (default arduino is 50khz) - I have had a sensor running for nearly 5 days now at i2c frequency: 200khz which seems strange but your arduino was running at 400khz and there were comments by other in my searches that they had issues with 50khz. Also I have set timeout: 1ms which removes the component taking too long warnings.

i2c:
  - id: bus_a 
    sda: xx
    scl: yy
    frequency: 200kHz
    scan: true
    timeout: 1ms

So if you can I would appreciate if you could try above with the updated component and let me know how it goes. I will keep testing quite a few scenerios and cleanup the code when I am have done with the testing.

diplix commented 2 weeks ago

installed it again with the new version, but couldn’t get it to connect to the home assistant API (compiling fine). i have no time for further debugging today, will try to track down the source of the problem over the next couple of days.

mrtoy-me commented 2 weeks ago

Apologies, I have been offline - my sensor failed after just over 6 days on 200khz - I am trying 400khz now. So you might want your hold off testing for a while until I do more.

Starting to think it is a hardware issue because the i2c seems to stop working but I will persist. Since you had some success with the polulo library I am thinking of converting the polulo library to esphome component and will try the approach you did on resetting after n timeouts.