前言:
家里的一个儿童澡盆附带的温度计坏掉了,拆解后发现这东西做的真垃圾!索性自己做一个。拆下了里面的NTC热敏电阻,但是不知道NTC的性能参数,经过测量与查资料后,采用用中位值滤波
、 Steinhart-Hart方程法
测温。只需要测量电阻在 20℃、40℃、60℃时候的NTC阻值代入公式计算出A 、B、 C参数即可。
电源:TP4056
MCU :航顺HK32HK32F030MF4P6
显示驱动:TM16244位数码管驱动
传感器:NTC温度传感器
NTC:负温度系数
NTC热敏电阻: 阻值随温度升高而减小
1% B3950/3470 5/10/50K 制冷空调冰箱探头
NTC热敏电阻的阻值与温度对照表主要关注几个方面:温度、NTC阻值、阻值公差及B值。
NTC热敏电阻随着温度的升高而降低了电阻,并提供各种基本电阻和曲线。大多数情况下即25℃时的阻值,它提供了一个方便的参考点。例如,10K的NTC热敏电阻即它在25℃时的阻值为10KΩ。
另一个重要特征是“B”值。B值是材料常数,其由制成它的陶瓷材料确定,并描述在两个温度点之间的特定温度范围内的电阻(R/T)曲线的梯度。每个热敏电阻材料将具有不同的材料常数,因此具有不同的电阻与温度曲线。然后,B值将定义第一温度或基点(通常为25℃)的热敏电阻电阻值(称为T1),以及第二温度点(例如50℃,称为T2 )的热敏电阻电阻值。因此,B值将使热敏电阻材料在T1和T2的范围内保持恒定。即B:T1/T2或B:25/85,典型的NTC热敏电阻B值在约3000和约5000之间。
两个重要参数:
25摄氏度时候的阻值10KΩ
)例如:25摄氏度时候的额定零功率阻值10KΩ,热敏指数3950。
#include "NTC.h"
#include "config.h"
#include
#define Vref 2.5
float CalculationTemperature(u16 adc)
{
float Temper=0.0; // 温度
float Rt=0.0; // NTC热敏电阻阻值
float R25=10000.0; // NTC热敏电阻25℃时的阻值:10K
float T2=298.15; // 273.15+25;
float B=3950.0; // 热敏指数3950
float K=273.15; // 绝对温度
float RtV=0.0; // NTC热敏电阻电压
RtV = (adc*(Vref/4096)); // NTC电压
Rt = (RtV*R25)/(Vref-RtV); // NTC阻值
Temper = 1.0/(log(Rt/R25)/B + 1.0/T2)-K; // 经验公式计算温度
return Temper; // 返回温度值
}
#include "NTC.h"
#include "config.h"
extern u16 adc_result; // ADC转换结果;
u16 temp_table[]={ //10KB3950
3983, //0:-40℃
3975, //1: -39℃
3967, //2:-38℃
3958, //3:-37℃
3949, //4:-36℃
3940, //5:-35℃
3929, //6:-34℃
3919, //7:-33℃
3907, //8:-32℃
3896, //9:-31℃
3883, //10:-30℃
3870, //11:-29℃
3856, //12:-28℃
3842, //13:-27℃
3827, //14:-26℃
3811, //15:-25℃
3795, //16:-24℃
3777, //17:-23℃
3759, //18:-22℃
3740, //19:-21℃
3721, //20:-20℃
3700, //21:-19℃
3679, //22:-18℃
3656, //23:-17℃
3633, //24:-16℃
3609, //25:-15℃
3585, //26:-14℃
3559, //27:-13℃
3532, //28:-12℃
3505, //29:-11℃
3476, //30:-10℃
3447, //31:-9℃
3416, //32:-8℃
3385, //33:-7℃
3353, //34:-6℃
3320, //35:-5℃
3286, //36:-4℃
3251, //37:-3℃
3215, //38:-2℃
3179, //39:-1℃
3142, //40: 0℃
3104, //41: 1℃
3065, //42: 2℃
3025, //43: 3℃
2985, //44: 4℃
2944, //45: 5℃
2902, //46: 6℃
2860, //47: 7℃
2817, //48: 8℃
2774, //49: 9℃
2730, //50: 10℃
2686, //51: 11℃
2641, //52: 12℃
2596, //53: 13℃
2551, //54: 14℃
2505, //55: 15℃
2460, //56: 16℃
2414, //57: 17℃
2368, //58: 18℃
2322, //59: 19℃
2276, //60: 20℃
2230, //61: 21℃
2184, //62: 22℃
2139, //63: 23℃
2093, //64: 24℃
2048, //65: 25℃
2003, //66: 26℃
1958, //67: 27℃
1914, //68: 28℃
1870, //69: 29℃
1826, //70: 30℃
1783, //71: 31℃
1741, //72: 32℃
1699, //73: 33℃
1657, //74: 34℃
1616, //75: 35℃
1576, //76: 36℃
1536, //77: 37℃
1497, //78: 38℃
1459, //79: 39℃
1421, //80: 40℃
1384, //81: 41℃
1347, //82: 42℃
1311, //83: 43℃
1277, //84: 44℃
1242, //85: 45℃
1209, //86: 46℃
1176, //87: 47℃
1144, //88: 48℃
1112, //89: 49℃
1082, //90: 50℃
1052, //91: 51℃
1022, //92: 52℃
994, //93: 53℃
966, //94: 54℃
939, //95: 55℃
912, //96: 56℃
886, //97: 57℃
861, //98: 58℃
837, //99: 59℃
813, //100: 60℃
790, //101: 61℃
767, //102: 62℃
745, //103: 63℃
724, //104: 64℃
703, //105: 65℃
683, //106: 66℃
663, //107: 67℃
644, //108: 68℃
626, //109: 69℃
608, //110: 70℃
590, //111: 71℃
573, //112: 72℃
557, //113: 73℃
541, //114: 74℃
525, //115: 75℃
510, //116: 76℃
496, //117: 77℃
481, //118: 78℃
468, //119: 79℃
454, //120: 80℃
441, //121: 81℃
429, //122: 82℃
417, //123: 83℃
405, //124: 84℃
394, //125: 85℃
382, //126: 86℃
372, //127: 87℃
361, //128: 88℃
351, //129: 89℃
341, //130: 90℃
332, //131: 91℃
323, //132: 92℃
314, //133: 93℃
305, //134: 94℃
297, //135: 95℃
289, //136: 96℃
280, //137: 97℃
273, //138: 98℃
265, //139: 99℃
258, //140: 100℃
251, //141: 101℃
245, //142: 102℃
238, //143: 103℃
231, //144: 104℃
225, //145: 105℃
219, //146: 106℃
214, //147: 107℃
208, //148: 108℃
202, //149: 109℃
197, //150: 110℃
192, //151: 111℃
187, //152: 112℃
182, //153: 113℃
177, //154: 114℃
173, //155: 115℃
168, //156: 116℃
164, //157: 117℃
159, //158: 118℃
156, //159: 119℃
151 //160:120℃
};
float CalculationTemperature(u16 adc)
{
float temper,temper_float;
u16 min,middle,max;
float temp1,temp2;
min = 0; //-40度
max = 160; //120度
if(adc == temp_table[min]) temper = min - 40;
else if(adc == temp_table[max]) temper = max - 40;
while(min <= max) // 二分搜索法
{
middle = (min + max) / 2;
if(adc == temp_table[middle]) temper = middle - 40;
if(adc > temp_table[middle]) max = middle - 1;
else min = middle + 1;
if(min >= max)
{
temp1 = temp_table[max]-adc;
temp2 = temp_table[max-1] - temp_table[max];
temper_float = temp1 / temp2;
temper = max + temper_float - 40;
}
}
return temper;
}
#include "NTC.h"
#include "config.h"
#include "math.h"
#define Vref 2.5
float CalculationTemperature(u16 adc)
{
float A = 1.14E-3,B = 2.34E-4,C = 7.54E-8;
float Ka = 273.15;
float temper;
float Rt = 0.0;
float RtV = 0.0;
float R25 = 10000;
RtV = (adc*(Vref/4096)); // NTC电压
Rt = (RtV*R25)/(Vref-RtV); // NTC阻值
temper = 1/(A + B*log(Rt) + C*pow(log(Rt),3))-Ka; // Steinhart-Hart方程
return temper;
}
方法:连续采样N次(N取奇数)把N次采样值按大小排列取中间值为本次有效值
优点:能有效克服因偶然因素引起的波动干扰;对温度、液位等变化缓慢的被测参数有良好的滤波效果
缺点:对流量,速度等快速变化的参数不宜
//中值滤波算法
int middleValueFilter(int N)
{
int value_buf[N];
int i,j,k,temp;
for( i = 0; i < N; ++i)
{
value_buf[i] = HAL_ADC_GetValue(&hadc1);
}
for(j = 0 ; j < N-1; ++j)
{
for(k = 0; k < N-j-1; ++k)
{
//从小到大排序,冒泡法排序
if(value_buf[k] > value_buf[k+1])
{
temp = value_buf[k];
value_buf[k] = value_buf[k+1];
value_buf[k+1] = temp;
}
}
}
return value_buf[(N-1)/2];
}
中值滤波对消除异常值和平稳化AD采样都具有十分有效的结果。
核心思想:根据当前的仪器"测量值" 和上一刻的 “预测量” 和 “误差”,计算得到当前的最优量,再预测下一刻的量。里面比较突出的是观点是:把误差纳入计算,而且分为预测误差和测量误差两种,通称为噪声。还有一个非常大的特点是:误差独立存在,始终不受测量数据的影响。
优点:巧妙的融合了观测数据与估计数据,对误差进行闭环管理,将误差限定在一定范围。适用性范围很广,时效性和效果都很优秀。
缺点:需要调参,参数的大小对滤波的效果影响较大。
//卡尔曼滤波
int KalmanFilter(int inData)
{
static float prevData = 0; //先前数值
static float p = 10, q = 0.001, r = 0.001, kGain = 0; // q控制误差 r控制响应速度
p = p + q;
kGain = p / ( p + r ); //计算卡尔曼增益
inData = prevData + ( kGain * ( inData - prevData ) ); //计算本次滤波估计值
p = ( 1 - kGain ) * p; //更新测量方差
prevData = inData;
return inData; //返回滤波值
}
HK32F030MF4P6 用户手册
内部参考电压
[1] 【CSDN@混分巨兽龙某某
】基于STM32的ADC采样及各式滤波实现(HAL库,含VOFA+教程)
[2] 【CSDN@Q大帅】ADC滤波的10种经典算法
[3] 【@布丁橘长】 第62期-ADC模数转换-NTC测温-经验公式法、查表法、Steinhart-Hart
[4] 【STC论坛@布丁橘长】https://www.stcaimcu.com/forum.php?mod=viewthread&tid=463&highlight=%E5%B8%83%E4%B8%81%E6%A9%98%E9%95%BF