Arduino UNO使用NTC热敏电阻测温+滤波

目录

一,硬件:

二,原理:

三,接线图:(本例使用了三个ntc,分别读取三个温度,图中只画出一个)

四,代码:

 五,实际效果:

六,实物展示

一,硬件:

  1. Arduino UNO 开发板
  2. 50K NTC 热敏电阻(参数:R值是50k,B值是3950)
  3. 10K电阻

二,原理:

通过读取串联电阻电压值,计算出NTC的阻值,然后根据NTC热敏电阻阻值与温度之间的转换公式,计算出当前的温度。但实际读取的温度会存在干扰,温度波动很大,所以要用滤波器,让输出的温度平稳。

三,接线图:(本例使用了三个ntc,分别读取三个温度,图中只画出一个)

四,代码:

//NTC温度计,通过10k电阻串联,adruino 10bit 读取电压,通过欧姆定律计算NTC的阻值,再通过公式计算出温度,该程序有滤波,是输出的值更稳定。
//精度为 0.26°C 满足正常使用
//动态滤波算法
#include <Arduino.h>

#define Threshold_1 5   //阈值1用于一阶带参滤波器,AD大于此值时,计数值 增加
#define Threshold_2 10  //阈值2用于一阶带参滤波器,计数值 大于此值时,增大参数K,增强滤波跟随

//二阶卡尔曼滤波器对象
class KLM_filter
{
public:
    int TR_NEW_DATA = 0;      //新值
    int TR_OLD_DATA = 85;    //旧值
    int NTC_yinjiao=A0;      //定义NTC引脚

    void temp_filter();
    KLM_filter(int yinjiao);
private:
    float K = 0.0;          //滤波系数
    uint8_t num_x = 0;      //滤波计数器
    boolean flag = 0;       //数据增减趋势
    int trsd_num0 = 0;
};

KLM_filter::KLM_filter(int yinjiao)
{
    NTC_yinjiao=yinjiao;
    TR_OLD_DATA=analogRead(NTC_yinjiao);
}

void KLM_filter::temp_filter()
{
    TR_NEW_DATA = analogRead(NTC_yinjiao);
    //判断变化方向是否一致 flag=1为一致,flag=0为不一致
    if (TR_NEW_DATA >= TR_OLD_DATA)
    {
        TR_NEW_DATA = analogRead(NTC_yinjiao);
        if (TR_NEW_DATA >= TR_OLD_DATA) flag = 1;
        else flag = 0;
    }
    else if (TR_NEW_DATA < TR_OLD_DATA)
    {
        TR_NEW_DATA = analogRead(NTC_yinjiao);
        if (TR_NEW_DATA < TR_OLD_DATA) flag = 1;
        else flag = 0;
    }

    if (flag)  //变化方向一致时执行
    {
        num_x++;
        if (abs(TR_NEW_DATA - TR_OLD_DATA) > Threshold_1)  //当变化大于Threshold_1的时候,进行计数器num快速增加,以达到快速增大K值,提高跟随性
        {
            num_x++;
        }
        if (num_x > Threshold_2)  //计数阈值设置,当递增或递减速度达到一定速率时,增大K值
        {
            K = K + 0.1;  //0.1为K的增长值,看实际需要修改
            num_x = 0;
        }
    }
    else
    {
        num_x = 0;
        K = 0.05;  //变化稳定时K值,看实际修改
    }
    TR_OLD_DATA = float((1 - K) * TR_OLD_DATA + K * TR_NEW_DATA);
}

KLM_filter ntc1KLM(A0);
KLM_filter ntc2KLM(A1);
KLM_filter ntc3KLM(A2);


//NTC 计算相关
const float balanceR[3] = { 9950, 10100, 10049 };  //参考电阻阻值,即与NTC串联的电阻,越精确越好
const float ADC_max = 1023.0;

/*使用beta方程计算阻值。*/
const float beta = 3950.0;        //商家给出的电阻对应25°C下的bata值
const float roomTemp = 298.15;    //以开尔文为单位的室温25°C
const float roomTempR = 50000.0;  //NTC热敏电阻在室温25°C下具有典型的电阻

//传入ADC的值,返回温度
float readThermistor(int adc_value,int rb_index)
{
    float rThermistor = 0;  //保存热敏电阻的电阻值
    float tKelvin = 0;      //以开尔文温度保存温度
    float tCelsius = 0;     //以摄氏温度保存温度
    switch(rb_index)
    {
        case 1:
            rThermistor = balanceR[0] * ((ADC_max / adc_value) - 1);
            break;
        case 2:
            rThermistor = balanceR[1] * ((ADC_max / adc_value) - 1);
            break;
        case 3:
            rThermistor = balanceR[2] * ((ADC_max / adc_value) - 1);
            break;
    }
    tKelvin = (beta * roomTemp) / (beta + (roomTemp * log(rThermistor / roomTempR)));
    tCelsius = tKelvin - 273.15;  //将开尔文转换为摄氏温度
    return tCelsius;
}

void setup()
{
    Serial.begin(115200);
}

void loop()
{
    ntc1KLM.temp_filter();
    ntc2KLM.temp_filter();
    ntc3KLM.temp_filter();

    Serial.print("a:");
    Serial.print(readThermistor(ntc1KLM.TR_OLD_DATA,1));
    Serial.print("; ");
    Serial.print("b:");
    Serial.print(readThermistor(ntc2KLM.TR_OLD_DATA,1));
    Serial.print("; ");
    Serial.print("C:");
    Serial.print(readThermistor(ntc3KLM.TR_OLD_DATA,1));
    Serial.println(";");
    delay(100);
}

 五,实际效果:

 温度稳定,能迅速响应温度变化。精度为0.26°C.

六,实物展示:

  • 2
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黎之名之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值