基于 ESP32 系列芯片的 NTC 热敏电阻温度采集示例:从 ntc_driver 组件到实战应用
2026/9/20 4:35:30 网站建设 项目流程

基于 ESP32 系列芯片的 NTC 热敏电阻温度采集示例:从 ntc_driver 组件到实战应用

【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution

本指南围绕 esp-iot-solution 仓库中的 ntc_temperature_sensor 示例 展开,讲解如何在 ESP32-C2 / ESP32-C3 / ESP32 / ESP32-C6 / ESP32-S3 系列芯片上使用ntc_driver组件驱动 NTC 热敏电阻完成温度采集。读完本文,你将掌握 NTC 分压电路两种接法(CIRCUIT_MODE_NTC_VCC/CIRCUIT_MODE_NTC_GND)的选择方法、ntc_config_t全字段配置含义、idf.py编译烧写与串口监视的完整流程,以及驱动内部从 ADC 原始值到摄氏温度的完整换算链路与滤波机制。

示例概述

该示例演示了基于ntc_driver组件开发热敏电阻温度读取应用程序的三种典型能力:

  • 基于最底层驱动 API 的控制:直接调用ntc_driver.h暴露的ntc_dev_create/ntc_dev_get_temperature/ntc_dev_delete等接口,不依赖任何上层业务框架;
  • 基于热敏电阻 CMFA103J3950HANT 驱动的演示:示例以 CMFA103J3950HANT(B 值 3950K、25℃ 电阻 10kΩ)为默认传感器进行完整演示;
  • 可选择配置不同的热敏电阻驱动:所有电参数均通过ntc_config_t结构体配置,只需修改b_valuer25_ohmfixed_ohmvdd_mv等字段即可无缝切换到其他型号热敏电阻。

示例主体代码位于 ntc_temperature_example_main.c,依赖声明见 idf_component.yml,其中通过override_pathntc_driver指向仓库内的 components/sensors/ntc_driver 组件。

硬件电路原理:两种分压接法

NTC(负温度系数)热敏电阻的阻值随温度升高而下降。驱动组件通过一个固定电阻Rref与热敏电阻Rt串联分压,将电阻变化转换为电压变化,再经 ADC 采样换算成温度。组件支持两种电路接法:

Vcc --------> Rt --------> Rref --------> GND 对应 CIRCUIT_MODE_NTC_VCC Vcc --------> Rref --------> Rt --------> GND 对应 CIRCUIT_MODE_NTC_GND

Rref是分压电阻;Rt是热敏电阻在当前温度下的电阻。

两种接法的电压极性相反,理解这一点对电路设计至关重要:

  • NTC 在上方(NTC_VCC):温度升高 → NTC 电阻下降 → NTC 端电压下降、固定电阻端电压上升,采样点电压随温度升高而下降;
  • NTC 在下方(NTC_GND):温度升高 → NTC 电阻下降 → NTC 端电压上升、固定电阻端电压下降,采样点电压随温度升高而上升。

因此在ntc_config_t中必须通过circuit_mode字段如实声明实际电路接法,驱动才能正确反推热敏电阻阻值(详见下文"电压到温度的换算"一节),这一点在 ntc_driver 组件文档 中有明确说明。

示例接线图(CMFA103J3950HANT)

示例文档给出基于 ESP8684-DevKitM-1(ESP32-C2)开发板的接线示意:

ESP8684-DevKitM-1 CMFA103J3950HANT -- [ADC1 CHANEL3] --------> | || NTC IO --

即将 NTC 的信号引脚接入ADC1 的通道 3ADC_UNIT_1+ADC_CHANNEL_3),与示例源码中的默认配置一致。

如何使用该示例

硬件需求与准备

  1. 驱动选择与配置:通过idf.py menuconfig选择需要演示的驱动并进行配置。ntc_driver组件提供了独立的 Kconfig 菜单(见 Kconfig),可配置 ADC 滤波功能:
配置项类型默认值说明
ENABLE_NTC_ADC_FILTERbooly使能 NTC 的 ADC 滤波,驱动会多次采样并滤波以抑制 ADC 噪声
NTC_FILTER_WINDOW_SIZEint50滤波前采集的 ADC 采样次数;取值越大,读数越稳定,但更新越慢
  1. 硬件连接:对于 CMFA103J3950HANT 驱动,仅需将信号端口连接到所配置的 GPIO 上即可(本例为 ADC1_CH3)。

编译与烧写

进入示例目录:

cd ./esp-iot-solution/examples/sensors/ntc_temperature_sensor

使用idf.py工具设置目标芯片,随后编译下载:

# 设置编译芯片 idf.py set-target esp32c2 # 编译并下载 idf.py -p PORT build flash

请将PORT替换为当前使用的串口端口号(如/dev/ttyUSB0)。项目根级构建配置见 CMakeLists.txt,示例要求 ESP-IDF 版本不低于 5.0(idf: ">=5.0")。

查看运行输出

编译烧写完成后,可使用monitor查看程序输出:

idf.py -p PORT monitor

示例输出结果

以下为 CMFA103J3950HANT 驱动测试 log(示例 README_CN.md 原始输出):

I (333) app_start: Starting scheduler on CPU0 I (337) app_start: Starting scheduler on CPU1 I (337) main_task: Started on CPU0 I (347) main_task: Calling app_main() I (347) ntc driver: IoT Ntc Driver Version: 0.1.0 I (347) ntc driver: calibration scheme version is Line Fitting I (357) ntc driver: Calibration Success I (367) NTC demo: NTC temperature = 23.44 ℃ I (367) NTC demo: NTC temperature = 23.47 ℃ I (377) NTC demo: NTC temperature = 23.47 ℃ I (377) NTC demo: NTC temperature = 23.47 ℃ I (387) NTC demo: NTC temperature = 23.50 ℃ I (387) NTC demo: NTC temperature = 23.50 ℃ I (397) NTC demo: NTC temperature = 23.44 ℃ I (397) NTC demo: NTC temperature = 23.44 ℃ I (407) NTC demo: NTC temperature = 23.43 ℃ I (407) NTC demo: NTC temperature = 23.43 ℃

日志中可以看到驱动版本号、ADC 校准方案类型、校准是否成功,以及每秒多次输出的温度读数。由于示例开启了默认的 ADC 滤波(滤波窗口 50 次采样),同一温度下多次读数的波动被抑制在小数点后两位以内。

示例源码逐段解析

示例的app_main完整实现了"初始化 → 创建驱动 → 循环读取 → 删除驱动"的典型生命周期:

#include "ntc_driver.h" const static char *TAG = "NTC demo"; void app_main(void) { //Select the NTC sensor and initialize the hardware parameters ntc_config_t ntc_config = { .b_value = 3950, .r25_ohm = 10000, .fixed_ohm = 10000, .vdd_mv = 3300, .circuit_mode = CIRCUIT_MODE_NTC_GND, .atten = ADC_ATTEN_DB_11, .channel = ADC_CHANNEL_3, .unit = ADC_UNIT_1 }; //Create the NTC Driver and Init ADC ntc_device_handle_t ntc = NULL; adc_oneshot_unit_handle_t adc_handle = NULL; ESP_ERROR_CHECK(ntc_dev_create(&ntc_config, &ntc, &adc_handle)); ESP_ERROR_CHECK(ntc_dev_get_adc_handle(ntc, &adc_handle)); float temp = 0.0; for (int i = 0; i < 10; i++) { if (ntc_dev_get_temperature(ntc, &temp) == ESP_OK) { ESP_LOGI(TAG, "NTC temperature = %.2f ℃", temp); } } ESP_ERROR_CHECK(ntc_dev_delete(ntc)); }

配置结构体ntc_config_t字段详解

ntc_config_t定义于 ntc_driver.h,各字段含义如下:

字段类型示例值含义与注意事项
circuit_modentc_circuit_mode_tCIRCUIT_MODE_NTC_GND分压电路接法,必须与实物电路一致,否则温度换算方向相反。枚举CIRCUIT_MODE_NTC_VCC = 1CIRCUIT_MODE_NTC_GND = 2
unitadc_unit_tADC_UNIT_1ADC 外设单元(ADC1/ADC2)
attenadc_atten_tADC_ATTEN_DB_11ADC 输入衰减,决定可测量电压量程;ADC_ATTEN_DB_11对应约 0~3.3V 量程
channeladc_channel_tADC_CHANNEL_3ADC 采样通道,需与硬件接线一致
b_valueuint32_t3950NTC 的 B 值(单位 K),由传感器数据手册给出,用于温度换算
r25_ohmuint32_t10000NTC 在 25℃ 时的标称电阻(单位 Ω)
fixed_ohmuint32_t10000分压固定电阻Rref的阻值(单位 Ω),需与电路实物一致
vdd_mvuint32_t3300分压电路供电电压(单位 mV)

更换其他型号热敏电阻时,只需按数据手册更新b_valuer25_ohm,并保证fixed_ohmvdd_mvcircuit_mode与实际电路匹配,即可复用同一套代码。

驱动底层实现:从 ADC 原始值到摄氏温度

ntc_driver组件源码位于 ntc_driver.c,下面拆解其关键实现,帮助你理解示例日志背后的完整链路。

1. 创建驱动并初始化 ADC(ntc_dev_create

  • 打印驱动版本号IoT Ntc Driver Version: %d.%d.%d(对应示例日志第一行);
  • 分配并保存ntc_config_t配置;
  • 若调用方未传入有效的adc_handle,驱动内部通过adc_oneshot_new_unit创建 ADC 单次采样单元,并将句柄回传给调用方(这就是示例中ntc_dev_create之后又调用ntc_dev_get_adc_handle的原因);
  • 通过adc_oneshot_config_channel配置通道衰减atten与位宽ADC_BITWIDTH_DEFAULT
  • 调用内部函数adc_calibration_init创建 ADC 校准句柄。

2. ADC 电压校准(adc_calibration_init

校准方案按芯片能力自动选择,与示例日志输出一一对应:

  • 优先尝试Curve FittingADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED),失败或未支持时回退到Line FittingADC_CALI_SCHEME_LINE_FITTING_SUPPORTED);
  • 校准成功打印Calibration Success;若芯片 eFuse 未烧录校准参数,则打印eFuse not burnt, skip software calibration

示例日志中calibration scheme version is Line Fitting+Calibration Success说明目标芯片走的是线性拟合校准路径且校准成功。

3. 电压到温度的换算(ntc_voltage_to_temperature

这是温度计算的数学核心,其实现与circuit_mode直接相关:

if (ndd->s_ntc_config.circuit_mode == CIRCUIT_MODE_NTC_VCC) { r_ntc_ohm = (vdd_mv - voltage_mv) * fixed_ohm / voltage_mv; } else if (ndd->s_ntc_config.circuit_mode == CIRCUIT_MODE_NTC_GND) { r_ntc_ohm = voltage_mv * fixed_ohm / (vdd_mv - voltage_mv); } *temperature = 1.0 / (log(1.0 * r_ntc_ohm / r25_ohm) / b_value + 1.0 / 298.15) - 273.0;
  • 先由采样电压与已知的vdd_mvfixed_ohm反推当前热敏电阻阻值r_ntc_ohm(两种接法的公式互为倒数关系,接法配置错误会直接导致温度方向颠倒或数值异常);
  • 再代入B 值公式(β 参数方程)计算温度:T = 1 / (ln(Rt/R25)/B + 1/298.15) - 273.15(源码中以 298.15 为 25℃ 的开尔文温度、273.0 为偏移做近似换算)。

4. 温度读取(ntc_dev_get_temperature

每次调用按以下链路执行:

  • 开启滤波时CONFIG_ENABLE_NTC_ADC_FILTER,默认开启):调用adc_oneshot_get_filtered_result连续采样CONFIG_NTC_FILTER_WINDOW_SIZE(默认 50)次,先计算均值与标准差,再将偏离均值超过一个标准差的异常采样丢弃后重新求平均,从而滤除 ADC 噪声尖峰;
  • 关闭滤波时:单次adc_oneshot_read读取原始值 →adc_cali_raw_to_voltage校准为电压;
  • 最终校验电压非零后调用电压转温度函数。源码对adc_raw == 0voltage == 0等边界情况均有显式保护(返回ESP_FAIL并打印告警)。

5. 资源释放(ntc_dev_delete

按创建顺序的逆序清理:删除校准方案句柄(Curve Fitting / Line Fitting 二选一)→ 若 ADC 单元由驱动内部创建则adc_oneshot_del_unit释放 →free驱动结构体。组件还配套了内存泄漏测试(见 test_ntd_driver.c),通过setUp/tearDown对比MALLOC_CAP_8BIT/MALLOC_CAP_32BIT堆变化来断言驱动创建-删除循环不产生泄漏,开发者可据此放心在长时间运行的固件中反复创建/释放 NTC 设备。

API 一览

ntc_driver对外仅暴露 4 个 API(定义见 ntc_driver.h):

API功能返回值
ntc_dev_create(config, ntc_handle, adc_handle)初始化 NTC 与 ADC 通道配置,创建驱动句柄ESP_OK/ESP_FAIL/ESP_ERR_INVALID_ARG/ESP_ERR_NO_MEM
ntc_dev_get_adc_handle(ntc_handle, adc_handle)从驱动句柄取出内部 ADC 句柄,供上层复用ESP_OK/ESP_ERR_INVALID_ARG
ntc_dev_get_temperature(ntc_handle, temperature)读取当前温度(单位 ℃),结果写入float *ESP_OK/ESP_FAIL/ESP_ERR_INVALID_ARG
ntc_dev_delete(ntc_handle)删除驱动设备并释放 ADC 资源ESP_OK/ESP_FAIL/ESP_ERR_INVALID_ARG

组件结构速览

  • 组件文档:电路原理、两种接法说明与最小示例代码;
  • 公共头文件:类型定义与 API 声明;
  • 驱动实现:ADC 初始化、校准、滤波与温度换算全流程;
  • Kconfig:ADC 滤波开关与窗口大小配置;
  • 测试应用:与示例完全相同的默认配置(CMFA103J3950HANT,B=3950),并附带内存泄漏检测;
  • 构建配置:依赖esp_adc组件。

常见问题与排查建议

  • 温度读数方向相反或数值异常:优先核对circuit_mode是否与实际电路一致(NTC 在 Rref 上方选CIRCUIT_MODE_NTC_VCC,下方选CIRCUIT_MODE_NTC_GND);
  • 日志提示eFuse not burnt, skip software calibration:芯片 eFuse 未烧录校准数据,驱动会跳过软件校准,温度精度可能下降;
  • 读数跳动较大:确认ENABLE_NTC_ADC_FILTER已开启(默认开启),可适当调大NTC_FILTER_WINDOW_SIZE换取更稳定读数,代价是更新周期变长;
  • 更换开发板/芯片:通过idf.py set-target切换目标芯片(示例已覆盖 ESP32-C2 / ESP32-C3 / ESP32 / ESP32-C6 / ESP32-S3),并核对unit/channel/atten是否在目标芯片上可用。

【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询