背景简介
在半年前买了一个Mac mini, 然后由于硬盘容量不是很足于是购买了一个硬盘盒用于外接,但是外接的时候温度较高,必须使用USB风扇进行降温。 于是我购买了两个散热片进行辅助降温。在日常的使用过程中,一般在低负载的时候硬盘盒并不热。所以风扇应该是关着才对(因为稍微有点吵),所以我就想画个板子来整合一个NTC测温加个PID温控(风扇不是很暴力,所以感觉效果可能不是很好),所以便有了今天的这个帖子使用NTC对进行测温(基于ESP32C3-xiao )
NTC购买的是一个10K,B值为3450。(其在25摄氏度的时候阻值为10000欧姆)

采用的连接方法是对3.3V使用一个10K的电阻进行分压、然后连接NTC电阻,在两个电阻之间接单片机的ADC引脚,这样当温度发生变化的时候便会带动NTC的电阻发生变化,从而带动电压发生变化,然后被单片机采集到最终转换成温度被读取出来。

实际上风扇的USB线也已经拆开重新连接了一个N-MOS可以进行PID 动态输出PWM了。 但是我并不想直接把这个C3给焊接上去(其主要原因是因为焊接能力不行)且只有一个GND,要背部飞线。所以目前已经打算画一个PCB然后引出来必要的引脚。

然后便是程序代码
#include <Arduino.h>
#define ADC_PIN A0
#define ADC_RESOLUTION 4095.0f
const float ADC_OFFSET = -0.04;
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;
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_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);
}程序代码也比较简单即按照上面我陈述的原理进行NTC的测温和转换即可,需要注意的是分压电阻,如果购买的电阻精度不是很够的话,那么会直接的影响到温度的精度,所以最好焊接好之后使用万用表测量一样到底电阻是多少,然后修改程序中的电阻变量。其次就是ESP32的ADC并不是很好用,它内部的参考电压默认好像是1.1V,所以测量的时候要使用下述的函数来调整增益,使其支持更高的电压到3.1V(同理于ESP-IDF)
analogSetAttenuation()
还有一个点需要注意的就是误差值,实际上测量出来的ADC的值,并不会和万用表里测量出来的值相等,因此可能测量出来的温度偏大或者偏小。在这里可以通过hard code 的方式来手动减去这个误差,然后进行换算。也可以把这个误差值写到Flash里,在网页上或者通过串口动态调整。
效果如下所示

我要赚赏金
