Hey EspHomies,
I am trying to use VL53L1X Time Of Flight Distance Sensor with ESPHome on an ESP8266 D1 Mini (hopefully to turn on drawer illumination when I open a drawer but that is mostly irrelevant for now).
I have this model (data sheet: https://www.st.com/resource/en/datasheet/vl53l1x.pdf ) which I bought from a reliable retailer here in the Netherlands. I bought the D1 Mini from the same source. I have everything setup and can see the sensor on address 0x29
when a scan is conducted:
[13:27:52][C][i2c.arduino:072]: SDA Pin: GPIO4
[13:27:52][C][i2c.arduino:073]: SCL Pin: GPIO5
[13:27:52][C][i2c.arduino:074]: Frequency: 50000 Hz
[13:27:52][C][i2c.arduino:086]: Recovery: bus successfully recovered
[13:27:52][I][i2c.arduino:096]: Results from i2c bus scan:
[13:27:52][I][i2c.arduino:102]: Found i2c device at address 0x29
But then later in the log it shows:
[13:27:52][E][component:082]: Component vl53l0x.sensor is marked FAILED
and sure enough, I’m not seeing any values from the sensor.
My yaml file looks like:
substitutions:
name: esphome-web-0f11d8
friendly_name: Desk Distance
esphome:
name: ${name}
friendly_name: ${friendly_name}
min_version: 2024.6.0
name_add_mac_suffix: false
project:
name: esphome.web
version: '1.0'
esp8266:
board: esp01_1m
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "top secret"
ota:
platform: esphome
password: "no peeking"
# Allow provisioning Wi-Fi via serial
improv_serial:
wifi:
# Set up a wifi access point
ap: {}
# In combination with the `ap` this allows the user
# to provision wifi credentials to the device via WiFi AP.
captive_portal:
dashboard_import:
package_import_url: github://esphome/example-configs/esphome-web/esp8266.yaml@main
import_full_config: true
# To have a "next url" for improv serial
web_server:
i2c:
sda: GPIO4
scl: GPIO5
scan: True
id: bus_a
sensor:
- platform: vl53l0x
name: "Distance A"
# address: 0x29
# enable_pin: GPIO02
update_interval: 10s
long_range: false
I have the sensor wired up to 3v and GND and SCL to D1 (GPIO5) and SDA to D2 (GPIO4). I do not have XSHUT or GPIO1 on the sensor connected to anything. I did have XSHUT connected to D4 originally but it would not appear on the I2C scan until after I disconnected that wire.
I’m not really sure where to go from here. If anyone has any suggestions to help point me in the right direction, I would really appreciate it.
Thanks!
Strange. I only wire up sda & sdl. Here’s my basic config and it works every time:
..... other stuff, then:
ota:
- platform: esphome
i2c: # For time of flight sensor
sda: GPIO7
scl: GPIO8
sensor:
- platform: vl53l0x
name: "TOF v5310 sensor"
address: 0x29
long_range: false
timeout: 200us
update_interval: 60s
unit_of_measurement: "m"
accuracy_decimals: 1
Im using an esp32 D1 mini, but it should work just fine with an 8266 D1. Try different gpios. You never know…
Also, try removing webserver: - it’s a giant memory hog.
Thanks for the reply, tried using your YAML in place of mine but I still got the same error. Tried turning off web server but that didin’t solve it either. I’m confident the pins are right because I can see the device on the i2c bus during the boot sequence.
Hmmmm, I just realised the sensor I have is a “VL53L1X” but it seems ESPHome supports the " VL53L0X". I’m not totally sure how different they are
So I did some more digging… there seems to be an “unofficial” library for this sensor which you can find here:
I had to manually add the file tof_vl53l1x.h
to my esphome directory and then update my yaml using the code above (I also needed to add wire.h to the libraries in the yaml which wasn’t included in the example code provided on the github!
I’m now getting actual distance readings in my log but it’s slow… updating about every 15 seconds. I need to figure out how to get it refreshing faster.
1 Like
Fixed that too… in the tof_vl53l1x.h
file there is a line as such:
MyCustomSensor() : PollingComponent(15000) {} // polling every 15s
You can just adjust this to whatever you want in ms (I changed it to 500 for every half second.
MyCustomSensor() : PollingComponent(500) {} // polling every 15s
Hello, that´s great you have made it to work. I am trying to edit code, but still having problem with this lines:
sensor:
- platform: custom
lambda: |-
auto my_sensor = new MyCustomSensor();
App.register_component(my_sensor);
return {my_sensor};
sensors:
name: "Distance"
accuracy_decimals: 0
unit_of_measurement: "mm"
should these lines be re-edited some way? Would you please post your exact code? Thank you!
Do you have the I2C section? I’m on mobile at the moment and can’t seem to select the code in esphome but here’s a screenshot:
Hi… thank you for your reply!
This is my yaml:
substitutions:
devicename: my-custom-sensor
esphome:
name: '${devicename}'
friendly_name: My custom sensor
platform: ESP32
board: esp32dev
includes:
- tof_vl53l1x.h
libraries:
- "Wire"
- "VL53L1x"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: xxx.xxx.xxx.xxx
gateway: xxx.xxx.xxx.xxx
subnet: xxx.xxx.xxx.xxx
ap:
ssid: "My-Custom-Sensor"
password: "xxx.xxx.xxx.xxx"
captive_portal:
web_server:
port: 80
# Enable logging
logger:
level: DEBUG
# Enable Home Assistant API
api:
encryption:
key: "xxx.xxx.xxx.xxx"
ota:
- platform: esphome
password: "xxx.xxx.xxx.xxx"
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"
this is my tof_vl53l1x.h :
#include "esphome.h"
#include <Wire.h>
#include <VL53L1X.h>
class VL53L1XCustomSensor : public PollingComponent, public Sensor {
private:
VL53L1X tof_sensor;
public:
// constructor
VL53L1XCustomSensor() : PollingComponent(10000) {} // polling every 10s
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().");
}
}
};```
And after lot of attempts changing some details the result is the same:
INFO ESPHome 2024.6.3
INFO Reading configuration /config/esphome/my-custom-sensor.yaml...
INFO Generating C++ source...
INFO Compiling app...
Processing my-custom-sensor (board: esp32dev; framework: arduino; platform: platformio/[email protected] )
--------------------------------------------------------------------------------
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
- toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch5
Dependency Graph
|-- AsyncTCP-esphome @ 2.1.3
|-- Wire @ 2.0.0
|-- VL53L1X @ 1.3.1
|-- WiFi @ 2.0.0
|-- FS @ 2.0.0
|-- Update @ 2.0.0
|-- ESPAsyncWebServer-esphome @ 3.2.2
|-- DNSServer @ 2.0.0
|-- ESPmDNS @ 2.0.0
|-- noise-c @ 0.1.4
|-- ArduinoJson @ 6.18.5
Compiling .pioenvs/my-custom-sensor/src/esphome/components/i2c/i2c_bus_arduino.cpp.o
Compiling .pioenvs/my-custom-sensor/src/esphome/components/logger/logger_esp8266.cpp.o
Compiling .pioenvs/my-custom-sensor/src/esphome/components/logger/logger_host.cpp.o
Compiling .pioenvs/my-custom-sensor/src/esphome/components/logger/logger_libretiny.cpp.o
Compiling .pioenvs/my-custom-sensor/src/esphome/components/logger/logger_rp2040.cpp.o
Compiling .pioenvs/my-custom-sensor/src/esphome/components/md5/md5.cpp.o
Compiling .pioenvs/my-custom-sensor/src/esphome/components/mdns/mdns_component.cpp.o
Compiling .pioenvs/my-custom-sensor/src/esphome/components/mdns/mdns_esp32.cpp.o
In file included from src/esphome/components/i2c/i2c_bus_arduino.cpp:3:
src/esphome/components/i2c/i2c_bus_arduino.h:38:3: error: 'TwoWire' does not name a type; did you mean 'TwoWire_h'?
TwoWire *wire_;
^~~~~~~
TwoWire_h
Compiling .pioenvs/my-custom-sensor/src/esphome/components/mdns/mdns_esp8266.cpp.o
Compiling .pioenvs/my-custom-sensor/src/esphome/components/mdns/mdns_host.cpp.o
src/esphome/components/i2c/i2c_bus_arduino.cpp: In member function 'virtual void esphome::i2c::ArduinoI2CBus::setup()':
src/esphome/components/i2c/i2c_bus_arduino.cpp:21:5: error: 'wire_' was not declared in this scope
wire_ = &Wire;
^~~~~
src/esphome/components/i2c/i2c_bus_arduino.cpp:21:5: note: suggested alternative: 'writev'
wire_ = &Wire;
^~~~~
writev
src/esphome/components/i2c/i2c_bus_arduino.cpp:21:14: error: 'Wire' was not declared in this scope
wire_ = &Wire;
^~~~
src/esphome/components/i2c/i2c_bus_arduino.cpp:21:14: note: suggested alternative: 'pipe'
wire_ = &Wire;
^~~~
pipe
src/esphome/components/i2c/i2c_bus_arduino.cpp:23:5: error: 'wire_' was not declared in this scope
wire_ = new TwoWire(next_bus_num); // NOLINT(cppcoreguidelines-owning-memory)
^~~~~
src/esphome/components/i2c/i2c_bus_arduino.cpp:23:5: note: suggested alternative: 'writev'
wire_ = new TwoWire(next_bus_num); // NOLINT(cppcoreguidelines-owning-memory)
^~~~~
writev
src/esphome/components/i2c/i2c_bus_arduino.cpp:23:17: error: expected type-specifier before 'TwoWire'
wire_ = new TwoWire(next_bus_num); // NOLINT(cppcoreguidelines-owning-memory)
^~~~~~~
src/esphome/components/i2c/i2c_bus_arduino.cpp: In member function 'void esphome::i2c::ArduinoI2CBus::set_pins_and_clock_()':
src/esphome/components/i2c/i2c_bus_arduino.cpp:53:3: error: 'wire_' was not declared in this scope
wire_->begin(static_cast<int>(sda_pin_), static_cast<int>(scl_pin_));
^~~~~
src/esphome/components/i2c/i2c_bus_arduino.cpp:53:3: note: suggested alternative: 'writev'
wire_->begin(static_cast<int>(sda_pin_), static_cast<int>(scl_pin_));
^~~~~
writev
Compiling .pioenvs/my-custom-sensor/src/esphome/components/mdns/mdns_libretiny.cpp.o
src/esphome/components/i2c/i2c_bus_arduino.cpp: In member function 'virtual esphome::i2c::ErrorCode esphome::i2c::ArduinoI2CBus::readv(uint8_t, esphome::i2c::ReadBuffer*, size_t)':
src/esphome/components/i2c/i2c_bus_arduino.cpp:125:16: error: 'wire_' was not declared in this scope
size_t ret = wire_->requestFrom((int) address, (int) to_request, 1);
^~~~~
src/esphome/components/i2c/i2c_bus_arduino.cpp:125:16: note: suggested alternative: 'writev'
size_t ret = wire_->requestFrom((int) address, (int) to_request, 1);
^~~~~
writev
src/esphome/components/i2c/i2c_bus_arduino.cpp: In member function 'virtual esphome::i2c::ErrorCode esphome::i2c::ArduinoI2CBus::writev(uint8_t, esphome::i2c::WriteBuffer*, size_t, bool)':
src/esphome/components/i2c/i2c_bus_arduino.cpp:179:3: error: 'wire_' was not declared in this scope
wire_->beginTransmission(address);
^~~~~
src/esphome/components/i2c/i2c_bus_arduino.cpp:179:3: note: suggested alternative: 'writev'
wire_->beginTransmission(address);
^~~~~
writev
Compiling .pioenvs/my-custom-sensor/src/esphome/components/mdns/mdns_rp2040.cpp.o
Compiling .pioenvs/my-custom-sensor/src/esphome/components/network/util.cpp.o
Compiling .pioenvs/my-custom-sensor/src/esphome/components/ota/ota_backend.cpp.o
*** [.pioenvs/my-custom-sensor/src/esphome/components/i2c/i2c_bus_arduino.cpp.o] Error 1
========================= [FAILED] Took 20.34 seconds =========================
scraja69
(Scraja69)
September 26, 2024, 12:17am
11
Can you please publish your ESPhome code. I have tried many times but got errors.
Stefos
(Stefanos)
October 1, 2024, 6:32am
12
Just made it yesterday. The code for esphome
name: radar
friendly_name: Radar
includes:
- tof_vl53l1x.h
libraries:
- "Wire"
- "VL53L1x"
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "xxxxx"
ota:
- platform: esphome
password: "xxxx"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Catradar Fallback Hotspot"
password: "xxxx"
captive_portal:
i2c: # example for Wemos LOLIN D2 mini
sda: GPIO21
scl: GPIO22
scan: True
#VL53L1X, 0x29
frequency: 400kHz
sensor:
- platform: custom
lambda: |-
auto my_sensor = new MyCustomSensor();
App.register_component(my_sensor);
return {my_sensor};
sensors:
name: "Distance"
accuracy_decimals: 0
unit_of_measurement: "mm"
Create a file Wire.h with the following code
#include <Wire.h>
#include <VL53L1X.h>
VL53L1X tof_sensor;
class MyCustomSensor : public PollingComponent, public Sensor {
public:
// constructor
MyCustomSensor() : PollingComponent(5000) {} // polling every 5s
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!");
while (1);
}
tof_sensor.setDistanceMode(VL53L1X::Short);
tof_sensor.setMeasurementTimingBudget(500000);
tof_sensor.startContinuous(50);
}
void update() override {
uint16_t mm = tof_sensor.read();
if (!tof_sensor.timeoutOccurred()) {
publish_state(mm);
} else {
ESP_LOGE("VL53L1X custom sensor", "Timeout during read().");
}
}
};
Download the tof_vl53l1x.h
file from this link GitHub - jardous/tof_vl53l1x: ESPHome custom sensor utilizing the VL53L1X Time of Flight distance module
and add both files under /homeassistant/esphome/ folder where your yaml are and then install it to your esp.
Oh… thank you so much… I will try it and let you know
filikun
(Filikun)
October 23, 2024, 2:14pm
14
Hmm can someone explain to a noob why we use both the tof_vl53l1x.h and the Wire.h they seem to contain almost the exact same information?
If I want to change the polling interval and long/short settings for example, where can I do that? And can I set any delta not spam HA with insignificant changes?
See Add the STM VL53L1X sensor (4m version of the VL53L0X) · Issue #836 · esphome/feature-requests · GitHub for a custom components. Both components mentioned in my comment there have distance_mode
which might help you. For delta, you can use all existing ESPHome sensor filters.