Skip to content

Commit

Permalink
Merge pull request #4834 from TD-er/bugfix/read_temperature_ESP32
Browse files Browse the repository at this point in the history
[Internal temp] Fix crashes on ESP32-S2/S3/C3 + filter
  • Loading branch information
TD-er authored Sep 30, 2023
2 parents 8b76e3e + 3c8d617 commit 361894a
Showing 1 changed file with 80 additions and 9 deletions.
89 changes: 80 additions & 9 deletions src/src/Helpers/Hardware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -617,16 +617,27 @@ extern "C" {
uint8_t temprature_sens_read();
}
#elif defined(ESP32C3) || defined(ESP32S2) || defined(ESP32S3)
#include "driver/temp_sensor.h"
#include <driver/temp_sensor.h>
#if ESP_IDF_VERSION_MAJOR < 5
// Work-around for bug in ESP-IDF < 5.0
#if defined(ESP32S3) || defined(ESP32C3)
#include <esp_efuse_rtc_calib.h>
#elif defined(ESP32S2)
#include <esp_efuse_rtc_table.h>
#endif

#endif
#endif // ESP32_CLASSIC
#endif // ESP32

float getInternalTemperature() {
static float temperature = -273.15f; // Improbable value
int8_t retries = 2;
static float temperature_filtered = NAN; // Improbable value
float celsius{};
esp_err_t result = ESP_FAIL;
#ifdef ESP32
#if defined(ESP32_CLASSIC)
uint8_t raw = 128u;
int8_t retries = 2;
while ((128u == raw) && (0 != retries)) {
delay(0);
raw = temprature_sens_read(); // Each reading takes about 112 microseconds
Expand All @@ -636,21 +647,81 @@ float getInternalTemperature() {
addLog(LOG_LEVEL_DEBUG, concat(F("ESP32: Raw temperature value: "), raw));
#endif
if (raw != 128) {
temperature = (raw - 32) / 1.8f;
result = ESP_OK;
// Raw value is in Fahrenheit
celsius = (raw - 32) / 1.8f;
}
#elif defined(ESP32C3) || defined(ESP32S2) || defined(ESP32S3)

temp_sensor_config_t tsens = TSENS_CONFIG_DEFAULT();
temp_sensor_set_config(tsens);
float tmpTemp = 0.0f;
temp_sensor_start();
esp_err_t result = temp_sensor_read_celsius(&tmpTemp);

#if ESP_IDF_VERSION_MAJOR < 5
// Work-around for bug in ESP-IDF < 5.0
// Seems to be fixed in ESP_IDF5.1
// temp_sensor_get_config always returns ESP_OK
// Thus dac_offset can be just about anything
// dac_offset is used as index in an array without bounds checking
{
#if defined(ESP32S3) || defined(ESP32C3)
static float s_deltaT = (esp_efuse_rtc_calib_get_ver() == 1) ?
(esp_efuse_rtc_calib_get_cal_temp(1) / 10.0f) :
0.0f;
#elif defined(ESP32S2)
static uint32_t version = esp_efuse_rtc_table_read_calib_version();
static float s_deltaT = (version == 1 || version == 2) ?
(esp_efuse_rtc_table_get_parsed_efuse_value(RTCCALIB_IDX_TMPSENSOR, false) / 10.0f) :
0.0f;
#endif


/*
if (isnan(s_deltaT)) { //suggests that the value is not initialized
uint32_t version = esp_efuse_rtc_calib_get_ver();
if (version == 1) {
// fetch calibration value for temp sensor from eFuse
s_deltaT = esp_efuse_rtc_calib_get_cal_temp(version);
} else {
// no value to fetch, use 0.
s_deltaT = 0;
}
}
*/
#ifndef TSENS_ADC_FACTOR
#define TSENS_ADC_FACTOR (0.4386)
#endif
#ifndef TSENS_DAC_FACTOR
#define TSENS_DAC_FACTOR (27.88)
#endif
#ifndef TSENS_SYS_OFFSET
#define TSENS_SYS_OFFSET (20.52)
#endif
uint32_t tsens_raw{};
temp_sensor_read_raw(&tsens_raw);
celsius = (TSENS_ADC_FACTOR * tsens_raw) - s_deltaT - TSENS_SYS_OFFSET;
result = ESP_OK;
}

#else

result = temp_sensor_read_celsius(&celsius);

#endif

temp_sensor_stop();
#endif // ESP32_CLASSIC
if (result == ESP_OK) {
temperature = tmpTemp;
if (isnanf(temperature_filtered)) {
temperature_filtered = celsius;
} else {
constexpr float IIR_FACTOR = 5.0f;
constexpr float IIR_DIVIDER = IIR_FACTOR + 1.0f;
temperature_filtered = ((IIR_FACTOR * temperature_filtered) + celsius) / IIR_DIVIDER;
}
}
#endif // ESP32_CLASSIC
#endif // USE_ESP32
return temperature;
return temperature_filtered;
}
#endif // if FEATURE_INTERNAL_TEMPERATURE

Expand Down

0 comments on commit 361894a

Please sign in to comment.