mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00: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:
		| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user