温度检测模块
实时监测打印头温度,防止过热损坏
基于NTC热敏电阻的ADC采样与温度换算
📌 为什么需要温度检测?
热敏打印头在工作时会产生大量热量,如果温度过高:
- 打印头损坏:过热会导致热敏片永久性失效
- 打印质量下降:温度过高会使打印纸过度显色,模糊不清
- 安全隐患:极端情况下可能引燃纸张
因此,一个可靠的温度检测模块是打印机的安全卫士。
直观理解:
就像电脑CPU有温度传感器,过热时会降频或关机,我们的打印机也需要时刻“感知”自己的体温。
一、硬件原理简述
传感器类型
本例使用NTC热敏电阻(负温度系数),阻值随温度升高而降低。
电路连接
- 热敏电阻与一个10kΩ精密电阻串联,组成分压电路
- 分压中点接ESP32的ADC引脚GPIO36(即ADC1_CH0)
- VCC = 3.3V,GND接地
3.3V ──┬── 10kΩ ──┬── GPIO36
│ │
└── NTC ────┘
(Rt) GND
参数说明
| 参数 | 值 | 含义 |
|---|---|---|
| 上拉电阻 R | 10kΩ | 1%精度,与NTC串联 |
| 参考温度 T0 | 25℃ | NTC标称阻值对应的温度 |
| 标称阻值 Rp | 30kΩ | 25℃时NTC的阻值 |
| B值 | 3950K | 热敏指数,反映阻值随温度变化率 |
| ADC分辨率 | 12位 | 0 |
二、代码实现
以下代码实现了从ADC采样到温度换算的完整流程。
1. 引脚与参数定义
#include "Arduino.h"
#define PIN_TEMPERATRUE 36 // 温度传感器ADC引脚
#define TEMPERATRUE_ADC_BIT 12 // ADC分辨率位数
2. 热敏电阻阻值→温度换算函数
float em_temp_calculate(float Rt)
{
float T2 = 273.15 + 25; // 参考温度25℃对应的开尔文温度
float Rp = 30000; // 25℃时NTC标称阻值(30kΩ)
float Bx = 3950; // 热敏指数 B值
float Ka = 273.15; // 开氏与摄氏转换常数
float temp = 0.0f;
// 根据NTC阻值计算温度(摄氏度)
temp = 1 / (log(Rt / Rp) / Bx + 1 / T2) - Ka + 0.5;
return temp;
}
核心作用:
使用NTC热敏电阻的Steinhart-Hart方程近似公式,将当前阻值 Rt 转换为摄氏度温度。
公式推导:
1/T = 1/T0 + (1/B) * ln(Rt/R0),其中T为开尔文温度。最后减去273.15得到摄氏度,+0.5 是经验修正值(可调整)。
直观理解:
就像查字典——知道阻值(单词),通过公式(字典规则)查出温度(中文意思)。
3. ADC采样与温度获取函数
/**
* @brief 读取ADC电压,计算当前温度
* @return float 温度值(摄氏度)
*/
float get_adc_temperatrue(){
float temp = 0.0f;
float Rt = 0;
float vol = 0;
// 1. 读取ADC电压(毫秒转换为伏特)
vol = analogReadMilliVolts(PIN_TEMPERATRUE) / 1000.0;
// 2. 电压转换为热敏电阻阻值
// 分压公式:vol = VCC * (Rt / (R + Rt)) => Rt = (vol * R) / (VCC - vol)
// 这里 R = 10000Ω, VCC = 3.3V
Rt = (vol * 10000) / (3.3 - vol);
// 3. 阻值换算温度
temp = em_temp_calculate(Rt);
return temp;
}
核心作用:
完成ADC采样、电压转阻值、阻值转温度的全链路计算。
注意事项:
analogReadMilliVolts()返回毫伏,需除以1000转为伏特- 分压公式推导自电路图,确保极性正确(NTC接地,上拉接VCC)
4. ADC初始化
void adc_init() {
analogReadResolution(TEMPERATRUE_ADC_BIT); // 设置ADC分辨率(默认12位)
}
核心作用:
配置ESP32的ADC分辨率为12位(04095),对应03.3V。
三、代码使用示例
void setup() {
Serial.begin(115200);
adc_init(); // 初始化ADC
Serial.println("温度检测模块已初始化");
}
void loop() {
float temp = get_adc_temperatrue();
Serial.printf("当前温度: %.2f °C\n", temp);
delay(1000); // 每秒采样一次
}
四、代码分析
1. 优点
- 模块化:温度计算与ADC读取分离,便于调试和复用
- 参数清晰:热敏电阻的Rp、B值等定义为常量,修改方便
- 使用ESP32原生API:
analogReadMilliVolts直接返回毫伏,精度更高
2. 潜在问题
- 未做滤波:单次ADC采样可能受噪声影响,建议多次采样取平均
- 缺少异常处理:当
vol接近3.3V时,3.3 - vol可能为0,导致除零错误(实际中不会,但可加判断) - 经验修正值固定:
+0.5可能因硬件差异需要校准 - 阻值计算公式假设VCC=3.3V:若VCC波动,会影响精度
3. 改进方向(供参考)
- 增加滑动平均滤波
- 添加电压校准系数
- 用查表法替代公式计算,提高速度(但当前已足够)
五、使用总结
| 关键词/技巧 | 一句话记忆 |
|---|---|
analogReadMilliVolts() | 直接读毫伏,省去手动转换ADC值 |
analogReadResolution() | 设置ADC位数,精度可调 |
| 分压公式 | 电压转阻值,电路基础要记牢 |
| NTC计算公式 | 阻值转温度,B值和Rp是关键 |
| 经验修正 | 最后加个0.5,实测更准确 |
| 热敏电阻 | 温度一变阻值变,ADC采样把它现 |
六、写在最后
温度检测模块为打印机装上了“体温计”,是保障打印头长寿的关键。通过本文,您学会了:
- ✅ NTC热敏电阻的分压电路原理
- ✅ 用ESP32的ADC读取毫伏电压
- ✅ 电压转阻值、阻值转温度的计算方法
- ✅ 完整的代码实现与参数配置