ESPHome  2024.11.0
internal_temperature.cpp
Go to the documentation of this file.
1 #include "internal_temperature.h"
2 #include "esphome/core/log.h"
3 
4 #ifdef USE_ESP32
5 #if defined(USE_ESP32_VARIANT_ESP32)
6 // there is no official API available on the original ESP32
7 extern "C" {
8 uint8_t temprature_sens_read();
9 }
10 #elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6) || \
11  defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32H2) || \
12  defined(USE_ESP32_VARIANT_ESP32C2)
13 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
14 #include "driver/temp_sensor.h"
15 #else
16 #include "driver/temperature_sensor.h"
17 #endif // ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
18 #endif // USE_ESP32_VARIANT
19 #endif // USE_ESP32
20 #ifdef USE_RP2040
21 #include "Arduino.h"
22 #endif // USE_RP2040
23 #ifdef USE_BK72XX
24 extern "C" {
25 uint32_t temp_single_get_current_temperature(uint32_t *temp_value);
26 }
27 #endif // USE_BK72XX
28 
29 namespace esphome {
30 namespace internal_temperature {
31 
32 static const char *const TAG = "internal_temperature";
33 #ifdef USE_ESP32
34 #if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)) && \
35  (defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32S2) || \
36  defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32H2) || defined(USE_ESP32_VARIANT_ESP32C2))
37 static temperature_sensor_handle_t tsensNew = NULL;
38 #endif // ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) && USE_ESP32_VARIANT
39 #endif // USE_ESP32
40 
42  float temperature = NAN;
43  bool success = false;
44 #ifdef USE_ESP32
45 #if defined(USE_ESP32_VARIANT_ESP32)
46  uint8_t raw = temprature_sens_read();
47  ESP_LOGV(TAG, "Raw temperature value: %d", raw);
48  temperature = (raw - 32) / 1.8f;
49  success = (raw != 128);
50 #elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6) || \
51  defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32H2) || \
52  defined(USE_ESP32_VARIANT_ESP32C2)
53 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
54  temp_sensor_config_t tsens = TSENS_CONFIG_DEFAULT();
55  temp_sensor_set_config(tsens);
56  temp_sensor_start();
57 #if defined(USE_ESP32_VARIANT_ESP32S3) && (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 4, 3))
58 #error \
59  "ESP32-S3 internal temperature sensor requires ESP IDF V4.4.3 or higher. See https://github.com/esphome/issues/issues/4271"
60 #endif
61  esp_err_t result = temp_sensor_read_celsius(&temperature);
62  temp_sensor_stop();
63  success = (result == ESP_OK);
64 #else
65  esp_err_t result = temperature_sensor_get_celsius(tsensNew, &temperature);
66  success = (result == ESP_OK);
67  if (!success) {
68  ESP_LOGE(TAG, "Failed to get temperature: %d", result);
69  }
70 #endif // ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
71 #endif // USE_ESP32_VARIANT
72 #endif // USE_ESP32
73 #ifdef USE_RP2040
74  temperature = analogReadTemp();
75  success = (temperature != 0.0f);
76 #endif // USE_RP2040
77 #ifdef USE_BK72XX
78  uint32_t raw, result;
80  success = (result == 0);
81 #if defined(USE_LIBRETINY_VARIANT_BK7231N)
82  temperature = raw * -0.38f + 156.0f;
83 #elif defined(USE_LIBRETINY_VARIANT_BK7231T)
84  temperature = raw * 0.04f;
85 #else // USE_LIBRETINY_VARIANT
86  temperature = raw * 0.128f;
87 #endif // USE_LIBRETINY_VARIANT
88 #endif // USE_BK72XX
89  if (success && std::isfinite(temperature)) {
90  this->publish_state(temperature);
91  } else {
92  ESP_LOGD(TAG, "Ignoring invalid temperature (success=%d, value=%.1f)", success, temperature);
93  if (!this->has_state()) {
94  this->publish_state(NAN);
95  }
96  }
97 }
98 
100 #ifdef USE_ESP32
101 #if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)) && \
102  (defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32S2) || \
103  defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32H2) || defined(USE_ESP32_VARIANT_ESP32C2))
104  ESP_LOGCONFIG(TAG, "Setting up temperature sensor...");
105 
106  temperature_sensor_config_t tsens_config = TEMPERATURE_SENSOR_CONFIG_DEFAULT(-10, 80);
107 
108  esp_err_t result = temperature_sensor_install(&tsens_config, &tsensNew);
109  if (result != ESP_OK) {
110  ESP_LOGE(TAG, "Failed to install temperature sensor: %d", result);
111  this->mark_failed();
112  return;
113  }
114 
115  result = temperature_sensor_enable(tsensNew);
116  if (result != ESP_OK) {
117  ESP_LOGE(TAG, "Failed to enable temperature sensor: %d", result);
118  this->mark_failed();
119  return;
120  }
121 #endif // ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) && USE_ESP32_VARIANT
122 #endif // USE_ESP32
123 }
124 
125 void InternalTemperatureSensor::dump_config() { LOG_SENSOR("", "Internal Temperature Sensor", this); }
126 
127 } // namespace internal_temperature
128 } // namespace esphome
uint8_t raw[35]
Definition: bl0939.h:19
uint8_t temprature_sens_read()
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:39
uint16_t temperature
Definition: sun_gtil2.cpp:26
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:118
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
bool has_state() const
Return whether this sensor has gotten a full state (that passed through all filters) yet...
Definition: sensor.cpp:97
uint32_t temp_single_get_current_temperature(uint32_t *temp_value)