mirror of
https://github.com/esphome/esphome.git
synced 2024-11-25 08:28:12 +01:00
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:
parent
92b36720b6
commit
b91723344e
4 changed files with 107 additions and 12 deletions
|
@ -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({
|
||||
|
||||
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,
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x29))
|
||||
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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue