• Arduino ADC + 模拟温度传感器LM35D


    LM35是美国国家半导体(后被TI收购)推出的精密温度传感IC系列,其信号输出方式为模拟输出,输出电压值与摄氏温度值呈正比,且用户不需额外的校正就能获得较高的测量精度。其主要特性有:

    • 供电电压:4~30V
    • 测量范围:与芯片相关,单个正电源供电时最大+2~+150°C
    • 测量精度:与芯片、测量温度有关,如下图。可见室温附近误差典型值大约在+/-0.5°C,最大值在+/-0.5°C到+/-1.5°C不等。本文中使用的LM35D是精度最差的芯片,误差最大值约+/-1.5°C。

    • 功耗:与测量电路、温度有关,大约在50~100μA范围。
    • Sensor Gain:10mV/°C,电压与温度的关系为 Vout = Temperature × 10mV/°C。
    • 长期稳定性:量程最高温度下1000小时漂移+-0.08°C。
    • 封装:有TO-92、Metal Can、SOIC-8、TO-220。本文使用的LM35D为TO-92封装。

     

    电路连接

    LM35D采用Arduino UNO板上的5V电压供电,信号输出端与A0管脚相连。

     

    简单的电压读取和转换

    转换采用Arduino的ADC功能实现,测量电压与AD采样值的关系为:

    其中,Vin是被测量(输入)电压;Vref是参考电压,若不特殊设置的话即为供电电压,对于UNO板为5V;resolution是ADC的比特数(不含符号位),对于atmega328p为10比特;ADC为读取的转换结果。严格来讲,上式的分母应该再减去1,但是否减1对结果的影响可以忽略不计。实现的代码非常简单:

     1 /*
     2 Measuring the temperature using the LM35 sensor
     3 Connection:
     4 LM35        UNO
     5 Vs <------> 5V
     6 GND <-----> GND
     7 Vout <----> A0
     8 
     9 */
    10 
    11 const int PIN_LM35 = A0; //pin connection
    12 
    13 float sensorVolt; //unit: mV
    14 float temperature; //unit: centigrade
    15 
    16 void setup()
    17 {
    18     Serial.begin(115200); //initialize serial communication
    19 }
    20 
    21 void loop()
    22 {
    23     sensorVolt = analogRead(PIN_LM35)*5000.0/1023; //do conversion
    24     temperature = sensorVolt/10.0;
    25     
    26     Serial.print("Temperature: "); //print the result
    27     Serial.print(temperature);    
    28     Serial.println(" *C"); 
    29     
    30     delay(1000); //delay 1s
    31 }

     

    获得更高分辨率

    除了采用电源电压作为基准源外,atmega328p提供了1.1V的内部基准源。在室温条件下测量时,LM35的输出电压在几百mV量级,因此可以利用内部基准源获得更高的测量分辨率。

    此外,由于板上3.3V是通过稳压芯片获得(精度+/-1%),将Vref管脚与3.3V相连,使用3.3V作为基准电压,亦可以获得较高的分辨率及精度。

    • 若使用5V的电源电压作为基准源时,测量分辨率为5000mV/1023 = ~4.9mV,对应温度0.49°C;
    • 改进方法一. 在5V电压作为基准源基础上,通过测量板上3.3V电源来估算5V电源(仅USB供电时)的误差
    • 改进方法二. 直接使用3.3V的稳压芯片电源输出作为基准源,测量分辨率为3300mV/1023 = ~3.2mV,对应温度0.32°C;
    • 改进方法三. 使用1.1V的内部基准源,测量分辨率为1100mV/1023 = ~1.1mV,对应温度0.11°C,分辨能力有明显的提高。

    代码也很简单,只需增加analogReference()语句及更改转换参数即可,以方法三为例:

     1 /*
     2 Measuring the temperature using the LM35 sensor
     3 Connection:
     4 LM35        UNO
     5 Vs <------> 5V
     6 GND <-----> GND
     7 Vout <----> A0
     8 
     9 */
    10 
    11 const int PIN_LM35 = A0; //pin connection
    12 
    13 float sensorVolt; //unit: mV
    14 float temperature; //unit: centigrade
    15 
    16 void setup()
    17 {
    18     analogReference(INTERNAL); //use internal voltage reference
    19     Serial.begin(115200); //initialize serial communication
    20 }
    21 
    22 void loop()
    23 {
    24     sensorVolt = analogRead(PIN_LM35)*1100.0/1023; //do conversion
    25     temperature = sensorVolt/10.0;
    26     
    27     Serial.print("Temperature: "); //print the result
    28     Serial.print(temperature);    
    29     Serial.println(" `C"); 
    30     
    31     delay(1000); //delay 1s
    32 }

    atmega328p的手册中描述内部基准源本身的误差有+-9%左右。因此,使用内部基准源在提高分辨能力的同时,也引入了额外的测量误差。更好的方法是利用3.3V板上电源,或者采用外部的高精度基准源

     

    参考资料

    datasheet: LM35 Precision Centigrade Temperature Sensors - TI
    Tutorial: Analog to Digital Conversion - Thanks to SparkFun
    How to Build a LM35 Temperature Sensor Circuit
    Arduino LM35 Sensor (包含利用Processing实现结果可视化的程序)
    TMP36 Temperature Sensor - from Adafruit

  • 相关阅读:
    查看系统运行时间和系统当前时间
    根据端口查进程信息
    SELinux深入理解
    nginx配置文件
    centos7 nginx配置httpsCenos(6.6/7.1)下从源码安装Python+Django+uwsgi+nginx环境部署(二)
    Linux的加密认证功能以及openssl详解
    linux中shell变量$#,$@,$0,$1,$2的含义解释
    理解GRUB2工作原理及配置选项与方法
    在用busybox制作系统过程中遇到的问题
    内核编译选配(VMware篇)
  • 原文地址:https://www.cnblogs.com/zlbg/p/4014506.html
Copyright © 2020-2023  润新知