御坂10032号 发表于 5 天前

FireBeetle 2 ESP32-C5 ADC + NTC实现测温功能

简介

在本文中,我们主要利用 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(" VV_corr=");
    Serial.print(V_corr, 4);
    Serial.print(" VRntc=");
    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. 都是一样的问题。 无奈只能手动减去一个误差值然后获得一个近似的电压进行计算。




实际的读数如下所示


页: [1]
查看完整版本: FireBeetle 2 ESP32-C5 ADC + NTC实现测温功能