简介
在本文中,我们主要利用 ESP32-C5 的 ADC 模块 对 NTC 热敏电阻 输出的模拟信号进行采集,并结合热敏电阻的 B 值 与 K 值,计算出当前的环境温度。

根据乐鑫的文档得知ESP32-C5 具备一个12位的ADC,其分辨率为4096 (Power(2,12) 0-4095);

根据ESP-IDF指南得知,如果需要测量不同电压范围的模拟量则需要配置ADC的衰减,默认的测量0 - 1000MV (不知道为什么我在其他地方还见到过1.1V的)根据不同的衰减配置可以将其配置到3.3v的测量范围。(不确定,在其他的地方看到过是3.1V的)

可以看到上述的测量条件还是比较苛刻的。
NTC测温
我手头的这个NTC传感器是之前某宝买的。B值是3450, 10K。 根据串联的分压原理,我们只需要将电源接线 VCC -> NTC -ADC - 10K电阻 - GND . 我们就可以从ADC处读取到我们期望的电压(因为NTC会根据温度的不同电阻发生变化,从而电压发生变化)因此我手焊了一个板子。
正面

背面

代码如下
- #include <Arduino.h>
-
- #define ADC_PIN 6
- #define ADC_RESOLUTION 4095.0f
-
-
- const float ADC_SCALE = 1.0f;
- //
- const float ADC_OFFSET = 0.43f;
-
- float readTemperature()
- {
- const float Vref = 3.1f; // 实际参考电压(可测量确认)
- const float R_fixed = 9940.0f; // 实测上拉电阻
- const float T0 = 298.15f; // 25°C in Kelvin
- const float B = 3450.0f; // B值
- const float R0 = 10000.0f; // 25°C 时的阻值
- const float Ka = 273.15f;
-
-
- analogRead(ADC_PIN); // 虚读一次给采样电容充电
- delay(2);
-
- const int samples = 20;
- uint32_t sum = 0;
- for (int i = 0; i < samples; ++i) {
- sum += analogRead(ADC_PIN);
- delay(3);
- }
-
- float adc_avg = (float)sum / (float)samples;
-
- // ---- 原始电压 ----
- float V_raw = (adc_avg / ADC_RESOLUTION) * Vref;
-
- // ---- 应用校准(先比例后偏移) ----
- float V_corr = V_raw * ADC_SCALE + ADC_OFFSET;
-
- // ---- 限幅,避免除以0或负值 ----
- if (V_corr <= 0.001f) V_corr = 0.001f;
- if (V_corr >= (Vref - 0.001f)) V_corr = Vref - 0.001f;
-
- // ---- 计算 R_ntc(NTC 在下方)----
- // 电路:Vref → R_fixed → ADC_PIN → NTC → GND
- float R_ntc = R_fixed * (Vref - V_corr) / V_corr;
-
- // ---- 温度换算 ----
- float tempK = 1.0f / (1.0f / T0 + log(R_ntc / R0) / B);
- float tempC = tempK - Ka;
-
- // ---- 串口输出 ----
- Serial.print("adc_avg=");
- Serial.print(adc_avg, 1);
- Serial.print(" V_raw=");
- Serial.print(V_raw, 4);
- Serial.print(" V V_corr=");
- Serial.print(V_corr, 4);
- Serial.print(" V Rntc=");
- Serial.print(R_ntc, 1);
- Serial.print(" Ω T=");
- Serial.print(tempC, 2);
- Serial.println(" °C");
-
- return tempC;
- }
-
- void setup()
- {
- Serial.begin(115200);
- analogSetAttenuation(ADC_11db); // 允许测量 0~3.3V
- analogReadResolution(12); // 12 位分辨率(0~4095)
- delay(1000);
- Serial.println("ESP32-S2 NTC Temperature Test (NTC at bottom, corrected)");
- }
-
- void loop()
- {
- readTemperature();
- delay(1000);
- }
复制代码
这边实际测量出来的电压和ADC的读数完全对不上, 万用表测量大概在1.8V左右,但是ESP-32C5读取出来的仅仅只有1.4左右。误差非常大,这边尝试了ESP32-S2, ESP32-S3 和 C5. 都是一样的问题。 无奈只能手动减去一个误差值然后获得一个近似的电压进行计算。

实际的读数如下所示

|