mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	[ESP32 ADC] Add option for raw uncalibrated output (#2663)
This commit is contained in:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							2ac232e634
						
					
				
				
					commit
					219b225ac0
				
			| @@ -91,17 +91,21 @@ void ADCSensor::dump_config() { | |||||||
| float ADCSensor::get_setup_priority() const { return setup_priority::DATA; } | float ADCSensor::get_setup_priority() const { return setup_priority::DATA; } | ||||||
| void ADCSensor::update() { | void ADCSensor::update() { | ||||||
|   float value_v = this->sample(); |   float value_v = this->sample(); | ||||||
|   ESP_LOGD(TAG, "'%s': Got voltage=%.2fV", this->get_name().c_str(), value_v); |   ESP_LOGD(TAG, "'%s': Got voltage=%.4fV", this->get_name().c_str(), value_v); | ||||||
|   this->publish_state(value_v); |   this->publish_state(value_v); | ||||||
| } | } | ||||||
|  |  | ||||||
| #ifdef USE_ESP8266 | #ifdef USE_ESP8266 | ||||||
| float ADCSensor::sample() { | float ADCSensor::sample() { | ||||||
| #ifdef USE_ADC_SENSOR_VCC | #ifdef USE_ADC_SENSOR_VCC | ||||||
|   return ESP.getVcc() / 1024.0f;  // NOLINT(readability-static-accessed-through-instance) |   int raw = ESP.getVcc();  // NOLINT(readability-static-accessed-through-instance) | ||||||
| #else | #else | ||||||
|   return analogRead(this->pin_->get_pin()) / 1024.0f;  // NOLINT |   int raw = analogRead(this->pin_->get_pin());  // NOLINT | ||||||
| #endif | #endif | ||||||
|  |   if (output_raw_) { | ||||||
|  |     return raw; | ||||||
|  |   } | ||||||
|  |   return raw / 1024.0f; | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| @@ -112,6 +116,9 @@ float ADCSensor::sample() { | |||||||
|     if (raw == -1) { |     if (raw == -1) { | ||||||
|       return NAN; |       return NAN; | ||||||
|     } |     } | ||||||
|  |     if (output_raw_) { | ||||||
|  |       return raw; | ||||||
|  |     } | ||||||
|     uint32_t mv = esp_adc_cal_raw_to_voltage(raw, &cal_characteristics_[(int) attenuation_]); |     uint32_t mv = esp_adc_cal_raw_to_voltage(raw, &cal_characteristics_[(int) attenuation_]); | ||||||
|     return mv / 1000.0f; |     return mv / 1000.0f; | ||||||
|   } |   } | ||||||
| @@ -135,10 +142,6 @@ float ADCSensor::sample() { | |||||||
|   if (raw0 == -1 || raw2 == -1 || raw6 == -1 || raw11 == -1) { |   if (raw0 == -1 || raw2 == -1 || raw6 == -1 || raw11 == -1) { | ||||||
|     return NAN; |     return NAN; | ||||||
|   } |   } | ||||||
|   // prevent divide by zero |  | ||||||
|   if (raw0 == 0 && raw2 == 0 && raw6 == 0 && raw11 == 0) { |  | ||||||
|     return 0; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   uint32_t mv11 = esp_adc_cal_raw_to_voltage(raw11, &cal_characteristics_[(int) ADC_ATTEN_DB_11]); |   uint32_t mv11 = esp_adc_cal_raw_to_voltage(raw11, &cal_characteristics_[(int) ADC_ATTEN_DB_11]); | ||||||
|   uint32_t mv6 = esp_adc_cal_raw_to_voltage(raw6, &cal_characteristics_[(int) ADC_ATTEN_DB_6]); |   uint32_t mv6 = esp_adc_cal_raw_to_voltage(raw6, &cal_characteristics_[(int) ADC_ATTEN_DB_6]); | ||||||
|   | |||||||
| @@ -31,6 +31,7 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage | |||||||
|   /// `HARDWARE_LATE` setup priority. |   /// `HARDWARE_LATE` setup priority. | ||||||
|   float get_setup_priority() const override; |   float get_setup_priority() const override; | ||||||
|   void set_pin(InternalGPIOPin *pin) { this->pin_ = pin; } |   void set_pin(InternalGPIOPin *pin) { this->pin_ = pin; } | ||||||
|  |   void set_output_raw(bool output_raw) { output_raw_ = output_raw; } | ||||||
|   float sample() override; |   float sample() override; | ||||||
|  |  | ||||||
| #ifdef USE_ESP8266 | #ifdef USE_ESP8266 | ||||||
| @@ -39,8 +40,7 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage | |||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   InternalGPIOPin *pin_; |   InternalGPIOPin *pin_; | ||||||
|   uint16_t read_raw_(); |   bool output_raw_{false}; | ||||||
|   uint32_t raw_to_microvolts_(uint16_t raw); |  | ||||||
|  |  | ||||||
| #ifdef USE_ESP32 | #ifdef USE_ESP32 | ||||||
|   adc_atten_t attenuation_{ADC_ATTEN_DB_0}; |   adc_atten_t attenuation_{ADC_ATTEN_DB_0}; | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ from esphome import pins | |||||||
| from esphome.components import sensor, voltage_sampler | from esphome.components import sensor, voltage_sampler | ||||||
| from esphome.const import ( | from esphome.const import ( | ||||||
|     CONF_ATTENUATION, |     CONF_ATTENUATION, | ||||||
|  |     CONF_RAW, | ||||||
|     CONF_ID, |     CONF_ID, | ||||||
|     CONF_INPUT, |     CONF_INPUT, | ||||||
|     CONF_NUMBER, |     CONF_NUMBER, | ||||||
| @@ -119,12 +120,18 @@ def validate_adc_pin(value): | |||||||
|     raise NotImplementedError |     raise NotImplementedError | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def validate_config(config): | ||||||
|  |     if config[CONF_RAW] and config.get(CONF_ATTENUATION, None) == "auto": | ||||||
|  |         raise cv.Invalid("Automatic attenuation cannot be used when raw output is set.") | ||||||
|  |     return config | ||||||
|  |  | ||||||
|  |  | ||||||
| adc_ns = cg.esphome_ns.namespace("adc") | adc_ns = cg.esphome_ns.namespace("adc") | ||||||
| ADCSensor = adc_ns.class_( | ADCSensor = adc_ns.class_( | ||||||
|     "ADCSensor", sensor.Sensor, cg.PollingComponent, voltage_sampler.VoltageSampler |     "ADCSensor", sensor.Sensor, cg.PollingComponent, voltage_sampler.VoltageSampler | ||||||
| ) | ) | ||||||
|  |  | ||||||
| CONFIG_SCHEMA = ( | CONFIG_SCHEMA = cv.All( | ||||||
|     sensor.sensor_schema( |     sensor.sensor_schema( | ||||||
|         unit_of_measurement=UNIT_VOLT, |         unit_of_measurement=UNIT_VOLT, | ||||||
|         accuracy_decimals=2, |         accuracy_decimals=2, | ||||||
| @@ -135,12 +142,14 @@ CONFIG_SCHEMA = ( | |||||||
|         { |         { | ||||||
|             cv.GenerateID(): cv.declare_id(ADCSensor), |             cv.GenerateID(): cv.declare_id(ADCSensor), | ||||||
|             cv.Required(CONF_PIN): validate_adc_pin, |             cv.Required(CONF_PIN): validate_adc_pin, | ||||||
|  |             cv.Optional(CONF_RAW, default=False): cv.boolean, | ||||||
|             cv.SplitDefault(CONF_ATTENUATION, esp32="0db"): cv.All( |             cv.SplitDefault(CONF_ATTENUATION, esp32="0db"): cv.All( | ||||||
|                 cv.only_on_esp32, cv.enum(ATTENUATION_MODES, lower=True) |                 cv.only_on_esp32, cv.enum(ATTENUATION_MODES, lower=True) | ||||||
|             ), |             ), | ||||||
|         } |         } | ||||||
|     ) |     ) | ||||||
|     .extend(cv.polling_component_schema("60s")) |     .extend(cv.polling_component_schema("60s")), | ||||||
|  |     validate_config, | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -155,6 +164,9 @@ async def to_code(config): | |||||||
|         pin = await cg.gpio_pin_expression(config[CONF_PIN]) |         pin = await cg.gpio_pin_expression(config[CONF_PIN]) | ||||||
|         cg.add(var.set_pin(pin)) |         cg.add(var.set_pin(pin)) | ||||||
|  |  | ||||||
|  |     if CONF_RAW in config: | ||||||
|  |         cg.add(var.set_output_raw(config[CONF_RAW])) | ||||||
|  |  | ||||||
|     if CONF_ATTENUATION in config: |     if CONF_ATTENUATION in config: | ||||||
|         if config[CONF_ATTENUATION] == "auto": |         if config[CONF_ATTENUATION] == "auto": | ||||||
|             cg.add(var.set_autorange(cg.global_ns.true)) |             cg.add(var.set_autorange(cg.global_ns.true)) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user