Vl53l0x change address (#1126)

* Added vl53l0x change address and timeout

* Added vl53l0x change address and timeout

* vl53l0x code cleanup and update test

* remove executable bit

* lint code cleanup

* code review fixes including timeout default to 10ms

* Code review cleanup and change a WARN log level message to DEBUG

* Fix issue where warn should be temporary

* Added name of sensor to warning message

* Fix blacklist lint issue

* Remove unused import
This commit is contained in:
Kurt Kellner 2021-02-25 15:12:06 -07:00 committed by GitHub
parent 92b36720b6
commit b91723344e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 107 additions and 12 deletions

View file

@ -1,7 +1,9 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import i2c, sensor
from esphome.const import CONF_ID, UNIT_METER, ICON_ARROW_EXPAND_VERTICAL
from esphome.const import (CONF_ID, UNIT_METER, ICON_ARROW_EXPAND_VERTICAL, CONF_ADDRESS,
CONF_TIMEOUT, CONF_ENABLE_PIN)
from esphome import pins
DEPENDENCIES = ['i2c']
@ -12,12 +14,31 @@ VL53L0XSensor = vl53l0x_ns.class_('VL53L0XSensor', sensor.Sensor, cg.PollingComp
CONF_SIGNAL_RATE_LIMIT = 'signal_rate_limit'
CONF_LONG_RANGE = 'long_range'
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_METER, ICON_ARROW_EXPAND_VERTICAL, 2).extend({
cv.GenerateID(): cv.declare_id(VL53L0XSensor),
cv.Optional(CONF_SIGNAL_RATE_LIMIT, default=0.25): cv.float_range(
min=0.0, max=512.0, min_included=False, max_included=False),
cv.Optional(CONF_LONG_RANGE, default=False): cv.boolean,
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x29))
def check_keys(obj):
if obj[CONF_ADDRESS] != 0x29 and CONF_ENABLE_PIN not in obj:
msg = "Address other then 0x29 requires enable_pin definition to allow sensor\r"
msg += "re-addressing. Also if you have more then one VL53 device on the same\r"
msg += "i2c bus, then all VL53 devices must have enable_pin defined."
raise cv.Invalid(msg)
return obj
def check_timeout(value):
value = cv.positive_time_period_microseconds(value)
if value.total_seconds > 60:
raise cv.Invalid("Maximum timeout can not be greater then 60 seconds")
return value
CONFIG_SCHEMA = cv.All(sensor.sensor_schema(UNIT_METER, ICON_ARROW_EXPAND_VERTICAL, 2).extend({
cv.GenerateID(): cv.declare_id(VL53L0XSensor),
cv.Optional(CONF_SIGNAL_RATE_LIMIT, default=0.25): cv.float_range(
min=0.0, max=512.0, min_included=False, max_included=False),
cv.Optional(CONF_LONG_RANGE, default=False): cv.boolean,
cv.Optional(CONF_TIMEOUT, default='10ms'): check_timeout,
cv.Optional(CONF_ENABLE_PIN): pins.gpio_output_pin_schema,
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x29)), check_keys)
def to_code(config):
@ -25,5 +46,11 @@ def to_code(config):
yield cg.register_component(var, config)
cg.add(var.set_signal_rate_limit(config[CONF_SIGNAL_RATE_LIMIT]))
cg.add(var.set_long_range(config[CONF_LONG_RANGE]))
cg.add(var.set_timeout_us(config[CONF_TIMEOUT]))
if CONF_ENABLE_PIN in config:
enable = yield cg.gpio_pin_expression(config[CONF_ENABLE_PIN])
cg.add(var.set_enable_pin(enable))
yield sensor.register_sensor(var, config)
yield i2c.register_i2c_device(var, config)

View file

@ -14,20 +14,55 @@ namespace esphome {
namespace vl53l0x {
static const char *TAG = "vl53l0x";
std::list<VL53L0XSensor *> VL53L0XSensor::vl53_sensors;
bool VL53L0XSensor::enable_pin_setup_complete = false;
VL53L0XSensor::VL53L0XSensor() { VL53L0XSensor::vl53_sensors.push_back(this); }
void VL53L0XSensor::dump_config() {
LOG_SENSOR("", "VL53L0X", this);
LOG_UPDATE_INTERVAL(this);
LOG_I2C_DEVICE(this);
if (this->enable_pin_ != nullptr) {
LOG_PIN(" Enable Pin: ", this->enable_pin_);
}
ESP_LOGCONFIG(TAG, " Timeout: %u%s", this->timeout_us_, this->timeout_us_ > 0 ? "us" : " (no timeout)");
}
void VL53L0XSensor::setup() {
ESP_LOGD(TAG, "'%s' - setup BEGIN", this->name_.c_str());
if (!esphome::vl53l0x::VL53L0XSensor::enable_pin_setup_complete) {
for (auto &vl53_sensor : vl53_sensors) {
if (vl53_sensor->enable_pin_ != nullptr) {
// Disable the enable pin to force vl53 to HW Standby mode
ESP_LOGD(TAG, "i2c vl53l0x disable enable pins: GPIO%u", (vl53_sensor->enable_pin_)->get_pin());
// Set enable pin as OUTPUT and disable the enable pin to force vl53 to HW Standby mode
vl53_sensor->enable_pin_->setup();
vl53_sensor->enable_pin_->digital_write(false);
}
}
esphome::vl53l0x::VL53L0XSensor::enable_pin_setup_complete = true;
}
if (this->enable_pin_ != nullptr) {
// Enable the enable pin to cause FW boot (to get back to 0x29 default address)
this->enable_pin_->digital_write(true);
delayMicroseconds(100);
}
// Save the i2c address we want and force it to use the default 0x29
// until we finish setup, then re-address to final desired address.
uint8_t final_address = address_;
this->set_i2c_address(0x29);
reg(0x89) |= 0x01;
reg(0x88) = 0x00;
reg(0x80) = 0x01;
reg(0xFF) = 0x01;
reg(0x00) = 0x00;
stop_variable_ = reg(0x91).get();
this->stop_variable_ = reg(0x91).get();
reg(0x00) = 0x01;
reg(0xFF) = 0x00;
@ -52,8 +87,15 @@ void VL53L0XSensor::setup() {
reg(0x94) = 0x6B;
reg(0x83) = 0x00;
while (reg(0x83).get() == 0x00)
this->timeout_start_us_ = micros();
while (reg(0x83).get() == 0x00) {
if (this->timeout_us_ > 0 && ((uint16_t)(micros() - this->timeout_start_us_) > this->timeout_us_)) {
ESP_LOGE(TAG, "'%s' - setup timeout", this->name_.c_str());
this->mark_failed();
return;
}
yield();
}
reg(0x83) = 0x01;
uint8_t tmp = reg(0x92).get();
@ -205,11 +247,22 @@ void VL53L0XSensor::setup() {
return;
}
reg(0x01) = 0xE8;
// Set the sensor to the desired final address
// The following is different for VL53L0X vs VL53L1X
// I2C_SXXXX_DEVICE_ADDRESS = 0x8A for VL53L0X
// I2C_SXXXX__DEVICE_ADDRESS = 0x0001 for VL53L1X
reg(0x8A) = final_address & 0x7F;
this->set_i2c_address(final_address);
ESP_LOGD(TAG, "'%s' - setup END", this->name_.c_str());
}
void VL53L0XSensor::update() {
if (this->initiated_read_ || this->waiting_for_interrupt_) {
this->publish_state(NAN);
this->status_set_warning();
this->status_momentary_warning("update", 5000);
ESP_LOGW(TAG, "%s - update called before prior reading complete - initiated:%d waiting_for_interrupt:%d",
this->name_.c_str(), this->initiated_read_, this->waiting_for_interrupt_);
}
// initiate single shot measurement
@ -217,7 +270,7 @@ void VL53L0XSensor::update() {
reg(0xFF) = 0x01;
reg(0x00) = 0x00;
reg(0x91) = stop_variable_;
reg(0x91) = this->stop_variable_;
reg(0x00) = 0x01;
reg(0xFF) = 0x00;
reg(0x80) = 0x00;
@ -246,7 +299,7 @@ void VL53L0XSensor::loop() {
this->waiting_for_interrupt_ = false;
if (range_mm >= 8190) {
ESP_LOGW(TAG, "'%s' - Distance is out of range, please move the target closer", this->name_.c_str());
ESP_LOGD(TAG, "'%s' - Distance is out of range, please move the target closer", this->name_.c_str());
this->publish_state(NAN);
return;
}

View file

@ -1,5 +1,7 @@
#pragma once
#include <list>
#include "esphome/core/component.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/i2c/i2c.h"
@ -20,6 +22,8 @@ struct SequenceStepTimeouts {
class VL53L0XSensor : public sensor::Sensor, public PollingComponent, public i2c::I2CDevice {
public:
VL53L0XSensor();
void setup() override;
void dump_config() override;
@ -30,6 +34,8 @@ class VL53L0XSensor : public sensor::Sensor, public PollingComponent, public i2c
void set_signal_rate_limit(float signal_rate_limit) { signal_rate_limit_ = signal_rate_limit; }
void set_long_range(bool long_range) { long_range_ = long_range; }
void set_timeout_us(uint32_t timeout_us) { this->timeout_us_ = timeout_us; }
void set_enable_pin(GPIOPin *enable) { this->enable_pin_ = enable; }
protected:
uint32_t get_measurement_timing_budget_() {
@ -249,10 +255,17 @@ class VL53L0XSensor : public sensor::Sensor, public PollingComponent, public i2c
float signal_rate_limit_;
bool long_range_;
GPIOPin *enable_pin_{nullptr};
uint32_t measurement_timing_budget_us_;
bool initiated_read_{false};
bool waiting_for_interrupt_{false};
uint8_t stop_variable_;
uint16_t timeout_start_us_;
uint16_t timeout_us_{};
static std::list<VL53L0XSensor *> vl53_sensors;
static bool enable_pin_setup_complete;
};
} // namespace vl53l0x

View file

@ -229,6 +229,8 @@ sensor:
name: 'VL53L0x Distance'
address: 0x29
update_interval: 60s
enable_pin: GPIO13
timeout: 200us
- platform: apds9960
type: clear
name: APDS9960 Clear