Temperature Sensor

Introduction

The ESP32-C6 has a built-in sensor used to measure the chip’s internal temperature. The temperature sensor module contains an 8-bit Sigma-Delta ADC and a DAC to compensate for the temperature offset.

Due to restrictions of hardware, the sensor has predefined measurement ranges with specific measurement errors. See the table below for details.

predefined range (°C)

error (°C)

50 ~ 125

< 3

20 ~ 100

< 2

-10 ~ 80

< 1

-30 ~ 50

< 2

-40 ~ 20

< 3

备注

The temperature sensor is designed primarily to measure the temperature changes inside the chip. The temperature value depends on factors like microcontroller clock frequency or I/O load. Generally, the chip’s internal temperature might be higher than the ambient temperature.

Functional Overview

Resource Allocation

The ESP32-C6 has just one built-in temperature sensor hardware. The temperature sensor instance is represented by temperature_sensor_handle_t, which is also the bond of the context. It would always be the parameter of the temperature APIs with the information of hardware and configurations, so user can just create a pointer of type temperature_sensor_handle_t and passing to APIs as needed.

In order to install a built-in temperature sensor instance, the first thing is to evaluate the temperature range in your detection environment (For example: if the testing environment is in a room, the range you evaluate might be 10 °C ~ 30 °C; if the testing in a lamp bulb, the range you evaluate might be 60 °C ~ 110 °C). Based on that, the following configuration structure should be defined in advance: temperature_sensor_config_t:

  • range_min. The minimum value of testing range you have evaluated.

  • range_max. The maximum value of testing range you have evaluated.

After the ranges are set, the structure could be passed to temperature_sensor_install(), which will instantiate the temperature sensor instance and return a handle.

As mentioned above, different measure ranges have different measurement errors. The user doesn’t need to care about the measurement error because we have an internal mechanism to choose the minimum error according to the given range.

If the temperature sensor is no longer needed, you need to call temperature_sensor_uninstall() to free the temperature sensor resource.

Creating a Temperature Sensor Handle

  • Step1: Evaluate the testing range. In this example, the range is 20 °C ~ 50 °C.

  • Step2: Configure the range and obtain a handle

temperature_sensor_handle_t temp_handle = NULL;
temperature_sensor_config_t temp_sensor = {
    .range_min = 20,
    .range_max = 50,
};
ESP_ERROR_CHECK(temperature_sensor_install(&temp_sensor, &temp_handle));

Enable and Disable Temperature Sensor

  1. Enable the temperature sensor by calling temperature_sensor_enable(). The internal temperature sensor circuit will start to work. The driver state will transit from init to enable.

  2. To Disable the temperature sensor, please call temperature_sensor_disable().

Get Temperature Value

After the temperature sensor is enabled by temperature_sensor_enable(), user can get the current temperature by calling temperature_sensor_get_celsius().

// Enable temperature sensor
ESP_ERROR_CHECK(temperature_sensor_enable(temp_handle));
// Get converted sensor data
float tsens_out;
ESP_ERROR_CHECK(temperature_sensor_get_celsius(temp_handle, &tsens_out));
printf("Temperature in %f °C\n", tsens_out);
// Disable the temperature sensor if it's not needed and save the power
ESP_ERROR_CHECK(temperature_sensor_disable(temp_handle));

Install Temperature Threshold Callback

ESP32-C6 supports automatically triggering to monitor the temperature value continuously. When temperature value reaches a given threshold, an interrupt will happen. Thus users can install their own interrupt callback functions to do what they want. (e.g. alarm, restart, etc.). Following information indicates how to prepare a threshold callback.

You can save your own context to temperature_sensor_register_callbacks() as well, via the parameter user_arg. The user data will be directly passed to the callback function.

IRAM_ATTR static bool temp_sensor_monitor_cbs(temperature_sensor_handle_t tsens, const temperature_sensor_threshold_event_data_t *edata, void *user_data)
{
    ESP_DRAM_LOGI("tsens", "Temperature value is higher or lower than threshold, value is %d\n...\n\n", edata->celsius_value);
    return false;
}

// Callback configurations
temperature_sensor_abs_threshold_config_t threshold_cfg = {
    .high_threshold = 50,
    .low_threshold = -10,
};
// Set absolute value monitor threshold.
temperature_sensor_set_absolute_threshold(temp_sensor, &threshold_cfg);
// Register interrupt callback
temperature_sensor_event_callbacks_t cbs = {
    .on_threshold = temp_sensor_monitor_cbs,
};
// Install temperature callback.
temperature_sensor_register_callbacks(temp_sensor, &cbs, NULL);

Power Management

When power management is enabled (i.e. CONFIG_PM_ENABLE is on), temperature sensor will still keep working because it uses XTAL clock (on ESP32-C3) or RTC clock (on ESP32-S2/S3).

IRAM Safe

By default, the temperature sensor interrupt will be deferred when the Cache is disabled for reasons like writing/erasing Flash. Thus the event callback functions will not get executed in time, which is not expected in a real-time application.

There’s a Kconfig option CONFIG_TEMP_SENSOR_ISR_IRAM_SAFE that will:

  1. Enable the interrupt being serviced even when cache is disabled.

  2. Place all functions that used by the ISR into IRAM.

This will allow the interrupt to run while the cache is disabled but will come at the cost of increased IRAM consumption.

Thread Safety

In temperature sensor we don’t add any protection to keep the thread safe. Because from the common usage, temperature sensor should only be called in one task. If you must use this driver in different tasks, please add extra locks to protect it.

Unexpected Behaviors

  1. The value user gets from the chip is usually different from the ambient temperature. It is because the temperature sensor is built inside the chip. To some extent, it measures the temperature of the chip.

  2. When installing the temperature sensor, the driver gives a ‘the boundary you gave cannot meet the range of internal temperature sensor’ error feedback. It is because the built-in temperature sensor has testing limit. The error due to setting temperature_sensor_config_t:

    1. Totally out of range, like 200 °C ~ 300 °C.

    2. Cross the boundary of each predefined measurement. like 40 °C ~ 110 °C.

Application Example

API Reference

Header File

Functions

esp_err_t temperature_sensor_install(const temperature_sensor_config_t *tsens_config, temperature_sensor_handle_t *ret_tsens)

Install temperature sensor driver.

参数
  • tsens_config – Pointer to config structure.

  • ret_tsens – Return the pointer of temperature sensor handle.

返回

  • ESP_OK if succeed

esp_err_t temperature_sensor_uninstall(temperature_sensor_handle_t tsens)

Uninstall the temperature sensor driver.

参数

tsens – The handle created by temperature_sensor_install().

返回

  • ESP_OK if succeed.

esp_err_t temperature_sensor_enable(temperature_sensor_handle_t tsens)

Enable the temperature sensor.

参数

tsens – The handle created by temperature_sensor_install().

返回

  • ESP_OK Success

  • ESP_ERR_INVALID_STATE if temperature sensor is enabled already.

esp_err_t temperature_sensor_disable(temperature_sensor_handle_t tsens)

Disable temperature sensor.

参数

tsens – The handle created by temperature_sensor_install().

返回

  • ESP_OK Success

  • ESP_ERR_INVALID_STATE if temperature sensor is not enabled yet.

esp_err_t temperature_sensor_get_celsius(temperature_sensor_handle_t tsens, float *out_celsius)

Read temperature sensor data that is converted to degrees Celsius.

备注

Should not be called from interrupt.

参数
  • tsens – The handle created by temperature_sensor_install().

  • out_celsius – The measure output value.

返回

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG invalid arguments

  • ESP_ERR_INVALID_STATE Temperature sensor is not enabled yet.

  • ESP_FAIL Parse the sensor data into ambient temperature failed (e.g. out of the range).

esp_err_t temperature_sensor_set_absolute_threshold(temperature_sensor_handle_t tsens, const temperature_sensor_abs_threshold_config_t *abs_cfg)

Set temperature sensor absolute mode automatic monitor.

备注

This function should not be called with temperature_sensor_set_delta_threshold.

参数
返回

  • ESP_OK: Set absolute threshold successfully.

  • ESP_ERR_INVALID_STATE: Set absolute threshold failed because of wrong state.

  • ESP_ERR_INVALID_ARG: Set absolute threshold failed because of invalid argument.

esp_err_t temperature_sensor_set_delta_threshold(temperature_sensor_handle_t tsens, const temperature_sensor_delta_threshold_config_t *delta_cfg)

Set temperature sensor differential mode automatic monitor.

备注

This function should not be called with temperature_sensor_set_absolute_threshold

参数
返回

  • ESP_OK: Set differential value threshold successfully.

  • ESP_ERR_INVALID_STATE: Set absolute threshold failed because of wrong state.

  • ESP_ERR_INVALID_ARG: Set differential value threshold failed because of invalid argument.

esp_err_t temperature_sensor_register_callbacks(temperature_sensor_handle_t tsens, const temperature_sensor_event_callbacks_t *cbs, void *user_arg)

Install temperature sensor interrupt callback. Temperature sensor interrupt will be enabled at same time.

参数
  • tsens – The handle created by temperature_sensor_install().

  • cbs – Pointer to the group of temperature sensor interrupt callbacks.

  • user_arg – Callback argument.

返回

  • ESP_OK: Set event callbacks successfully

  • ESP_ERR_INVALID_ARG: Set event callbacks failed because of invalid argument

  • ESP_FAIL: Set event callbacks failed because of other error

Structures

struct temperature_sensor_config_t

Configuration of measurement range for the temperature sensor.

备注

If you see the log the boundary you gave cannot meet the range of internal temperature sensor. You may need to refer to predefined range listed doc api-reference/peripherals/Temperature sensor.

Public Members

int range_min

the minimum value of the temperature you want to test

int range_max

the maximum value of the temperature you want to test

temperature_sensor_clk_src_t clk_src

the clock source of the temperature sensor.

struct temperature_sensor_threshold_event_data_t

Temperature sensor event data.

Public Members

int celsius_value

Celsius value in interrupt callback.

struct temperature_sensor_event_callbacks_t

Group of temperature sensor callback functions, all of them will be run in ISR.

Public Members

temperature_thres_cb_t on_threshold

Temperature value interrupt callback

struct temperature_sensor_abs_threshold_config_t

Config options for temperature value absolute interrupt.

Public Members

float high_threshold

High threshold value(Celsius). Interrupt will be triggered if temperature value is higher than this value

float low_threshold

Low threshold value(Celsius). Interrupt will be triggered if temperature value is lower than this value

struct temperature_sensor_delta_threshold_config_t

Config options for temperature value delta interrupt.

Public Members

float increase_delta

Interrupt will be triggered if the temperature increment of two consecutive samplings if larger than increase_delta

float decrease_delta

Interrupt will be triggered if the temperature decrement of two consecutive samplings if smaller than decrease_delta

Macros

TEMPERATURE_SENSOR_CONFIG_DEFAULT(min, max)

temperature_sensor_config_t default constructure

Type Definitions

typedef struct temperature_sensor_obj_t *temperature_sensor_handle_t

Type of temperature sensor driver handle.

typedef bool (*temperature_thres_cb_t)(temperature_sensor_handle_t tsens, const temperature_sensor_threshold_event_data_t *edata, void *user_data)

Callback for temperature sensor threshold interrupt.

Param tsens

[in] The handle created by temperature_sensor_install().

Param edata

[in] temperature sensor event data, fed by driver.

Param user_data

[in] User data, set in temperature_sensor_register_callbacks().

Return

Whether a high priority task has been waken up by this function.