通过NTC(负温度系数)热敏电阻采集温度是一种低成本且广泛应用的方案,尤其适合对精度要求不高、预算有限的场景。

NTC热敏电阻的特点
负温度系数:电阻值随温度升高而降低(非线性关系)。
低成本:单价通常仅几元人民币,远低于数字温度传感器(如DS18B20)。
灵敏度高:在低温区电阻变化更显著,适合检测微小温度变化。
非线性响应:需通过公式或查表法进行线性化处理。
用Ai-WB2搭建电路

- 原理:NTC与固定电阻组成分压电路,ADC读取分压值后转换为电阻,再通过公式计算温度。
- 固定电阻选择:建议与NTC在目标温度范围内的中值电阻匹配(例如NTC在25℃时为10kΩ,则选10kΩ固定电阻)
这里分压电阻选择了51K,是因为之前错误地以为手头的NTC是50K的,后来发现是150K的,就将错就错了。就是要注意查表法需要按照150K+50K分压计算对应关系。
实际电路:

软件部分
在applications\ble_slave例程基础上修改
1、增加temperature.h处理ADC采集NTC数据
#ifndef __TEMPERATURE_H__
#define __TEMPERATURE_H__
//temperature.h
void adc_temp_init(void);
int get_temp_value(void);
int get_temperature(void);
#endif
void adc_temp_init(void);//初始化ADC
int get_temp_value(void);//采集ADC数值(0-4095)
int get_temperature(void);//将ADC数值转化为温度
2、temperature.c实现
//
#include <stdio.h>
#include <string.h>
#include <FreeRTOS.h>
#include <task.h>
#include <hosal_adc.h>
#include <blog.h>
#define GPIO_ADC_PIN 11
#define ADC_CHANNEL 10
const unsigned int tempTable[][2] = {
{-30,114},
{-29,121},
{-28,128},
{-27,136},
{-26,144},
{-25,153},
{-24,162},
{-23,172},
{-22,182},
{-21,192},
{-20,203},
{-19,215},
{-18,227},
{-17,240},
{-16,253},
{-15,267},
{-14,281},
{-13,296},
{-12,312},
{-11,328},
{-10,345},
{-9,362},
{-8,381},
{-7,400},
{-6,419},
{-5,440},
{-4,461},
{-3,483},
{-2,505},
{-1,529},
{0,553},
{1,577},
{2,603},
{3,629},
{4,656},
{5,684},
{6,713},
{7,742},
{8,772},
{9,803},
{10,835},
{11,867},
{12,900},
{13,934},
{14,968},
{15,1003},
{16,1039},
{17,1075},
{18,1112},
{19,1149},
{20,1187},
{21,1225},
{22,1264},
{23,1304},
{24,1343},
{25,1383},
{26,1424},
{27,1465},
{28,1506},
{29,1547},
{30,1588},
{31,1630},
{32,1672},
{33,1713},
{34,1755},
{35,1797},
{36,1839},
{37,1881},
{38,1922},
{39,1964},
{40,2005},
{41,2047},
{42,2088},
{43,2128},
{44,2169},
{45,2209},
{46,2249},
{47,2288},
{48,2327},
{49,2366},
{50,2404},
{51,2442},
{52,2479},
{53,2516},
{54,2552},
{55,2588},
{56,2623},
{57,2658},
{58,2692},
{59,2726},
{60,2759},
{61,2791},
{62,2823},
{63,2854},
{64,2885},
{65,2915},
{66,2945},
{67,2973},
{68,3002},
{69,3029},
{70,3056},
{71,3083},
{72,3109},
{73,3134},
{74,3159},
{75,3183},
{76,3207},
{77,3230},
{78,3252},
{79,3274},
{80,3296},
{81,3317},
{82,3337},
{83,3357},
{84,3376},
{85,3395},
{86,3414},
{87,3432},
{88,3449},
{89,3466},
{90,3483},
{91,3499},
{92,3515},
{93,3530},
{94,3545},
{95,3559},
{96,3573},
{97,3587},
{98,3600},
{99,3613},
{100,3626},
{101,3638},
{102,3650},
{103,3662},
{104,3673},
{105,3684},
{106,3695},
{107,3705},
{108,3715},
{109,3725},
{110,3735},
{111,3744},
{112,3753},
{113,3762},
{114,3771},
{115,3779},
{116,3787},
{117,3795},
{118,3802},
{119,3810},
{120,3817},
{121,3824},
{122,3831},
{123,3838},
{124,3844},
{125,3850},
{126,3856},
{127,3862},
{128,3868},
{129,3874},
{130,3879},
{131,3885},
{132,3890},
{133,3895},
{134,3900},
{135,3904},
{136,3909},
{137,3914},
{138,3918},
{139,3922},
{140,3926},
{141,3930},
{142,3934},
{143,3938},
{144,3942},
{145,3946},
{146,3949},
{147,3952},
{148,3956},
{149,3959},
{150,3962},
{151,3965},
{152,3968},
{153,3971},
{154,3974},
{155,3977},
{156,3980},
{157,3982},
{158,3985},
{159,3987},
{160,3990},
{161,3992},
{162,3994},
{163,3997},
{164,3999},
{165,4001},
{166,4003},
{167,4005},
{168,4007},
{169,4009},
{170,4011},
{171,4013},
{172,4015},
{173,4016},
{174,4018},
{175,4020},
{176,4021},
{177,4023},
{178,4024},
{179,4026},
{180,4027},
{181,4029},
{182,4030},
{183,4032},
{184,4033},
{185,4034},
{186,4035},
{187,4037},
{188,4038},
{189,4039},
{190,4040},
{191,4041},
{192,4043},
{193,4044},
{194,4045},
{195,4046},
{196,4047},
{197,4048},
{198,4049},
{199,4050},
{200,4050},
{201,4051},
{202,4052},
{203,4053},
{204,4054},
{205,4055},
{206,4055},
{207,4056},
{208,4057},
{209,4058},
{210,4058},
{211,4059},
{212,4060},
{213,4061},
{214,4061},
{215,4062},
{216,4062},
{217,4063},
{218,4064},
{219,4064},
{220,4065},
{221,4065},
{222,4066},
{223,4067},
{224,4067},
{225,4068},
{226,4068},
{227,4069},
{228,4069},
{229,4070},
{230,4070},
{231,4070},
{232,4071},
{233,4071},
{234,4072},
{235,4072},
{236,4073},
{237,4073},
{238,4073},
{239,4074},
{240,4074},
};
hosal_adc_dev_t adc0 = {
.cb = NULL,
.config = {
.mode = HOSAL_ADC_ONE_SHOT,
.pin = GPIO_ADC_PIN,
.sampling_freq = 340,
},
.dma_chan = 0,
.p_arg = NULL,
.port = 0,
};
void adc_temp_init(void)
{
hosal_adc_init(&adc0);
hosal_adc_add_channel(&adc0, ADC_CHANNEL);
}
int get_temp_value(void)
{
int ret = hosal_adc_value_get(&adc0, ADC_CHANNEL, 100);
blog_info("ADC = %ld \r\n", ret);
return ret;
}
int get_temperature(void)
{
int adc_value;
const unsigned int tableSize = sizeof(tempTable) / sizeof(tempTable[0]);
unsigned int i;
adc_value=get_temp_value();
// 边界检查(注意与采样NTC时方向相反)
if(adc_value <= tempTable[0][1]) {
return tempTable[0][0]; // 低于最低温度-30℃
}
if(adc_value >= tempTable[tableSize-1][1]) {
return tempTable[tableSize-1][0]; // 高于最高温度50℃
}
// 查表(ADC值随温度升高而增大)
for(i = 0; i < tableSize-1; i++) {
if(adc_value >= tempTable[i][1] && adc_value < tempTable[i+1][1]) {
// 线性插值计算温度
return tempTable[i][0] + (int)((float)(tempTable[i+1][0] - tempTable[i][0]) *
(float)(adc_value - tempTable[i][1]) /
(float)(tempTable[i+1][1] - tempTable[i][1]));
}
}
return 0xFFFF; // 错误代码(正常情况不会执行到这里)
}
3、main.c修改
void main()
{
bl_sys_init();
adc_temp_init();
pwm_led_init();
puts("[OS] proc_main_entry task...\r\n");
xTaskCreate(TaskUart, "TaskUart", 2048, NULL, 15, NULL);
xTaskCreate(TaskTemp, "TempAdc", 1024, NULL, 15, NULL);
xTaskCreate(proc_main_entry, (char *)"main_entry", 1024, NULL, 15, NULL);
}
增加adc_temp_init();//ADC初始化
RTOS建立一个新的TASK,用于处理温度采集:
xTaskCreate(TaskTemp, "TempAdc", 1024, NULL, 15, NULL);
4、TaskTemp任务
void TaskTemp(void *param)
{
int tempval;
uint8_t data[5] = {0x4e,0x4f,0x60,0x01,0x00};
while (1)
{
tempval=get_temperature();
data[4]=(uint8_t)tempval;
UUID1_SendNotify(strlen((char *)data), data);
vTaskDelay(1000);
}
}
通过get_temperature()采集到温度数据
调用UUID1_SendNotify函数发送数据到已订阅UUID1的BLE主机设备(手机)
数据格式为
固定数据头 |
固定数据头 |
标识(表示后面是温度) |
未知 |
温度值 |
0x4e |
0x4f |
0x60 |
0x01 |
0x00 |
手机运行APP(友商软件,非安信可)

搜索BLE

连接后可以看到上报的温度数据
