第1章:体温传感器选型,我踩过的那些坑

做嵌入式体温计项目,第一步就是选传感器。这一步要是走偏了,后面全白干。我见过太多工程师,上来就盯着精度参数看,结果做出来的产品要么功耗超标,要么I2C死活调不通。

今天咱们就把市面上主流的四款体温传感器——MLX90614、TMP117、MAX30205、LMT70,掰开了揉碎了讲清楚。我会结合自己这些年踩过的坑,告诉你每个芯片到底适合什么场景。

1.1 四款芯片的核心参数对比

先上干货。这张表我反复核对过,都是datasheet里的真实数据。你直接拿去用就行。

参数 MLX90614 TMP117 MAX30205 LMT70
测量方式 非接触式(红外) 接触式 接触式 接触式
精度(典型) ±0.5°C(体温范围) ±0.1°C(-20~50°C) ±0.1°C(37~39°C) ±0.13°C(20~42°C)
分辨率 0.02°C 0.0078°C 0.0039°C 0.05°C(模拟输出)
接口类型 PWM / SMBus I2C I2C 模拟输出(NTC)
工作电压 2.6~3.6V 1.7~5.5V 2.7~3.6V 2.0~5.5V
功耗(典型) 1.5mA(连续测量) 3.5μA(1Hz采样) 600μA(连续测量) 12μA(连续测量)
封装 TO-39 WSON-6 TDFN-8 DSBGA-4

我的建议:如果做非接触式测温,MLX90614是唯一选择。但如果你做的是贴片式体温贴,TMP117和MAX30205才是正解。LMT70嘛,适合那些不想用I2C、想省成本的场景。

1.2 MLX90614:非接触式测温的老大哥

MLX90614我用了好几年。说实话,它最大的优点是——不用接触皮肤。这在疫情期间简直是刚需。你想想看,给婴儿测体温,或者做门禁测温,总不能让人家把传感器含嘴里吧?

但它有个坑,我当年就栽过。它的精度±0.5°C是在体温范围(32~42°C)内才能达到的。如果你测环境温度,精度会掉到±1°C左右。而且,它受环境温度影响很大。我做过实验,环境温度从25°C变到35°C,读数能漂0.3°C。

避坑指南:我曾经在一个项目中,直接把MLX90614装在塑料外壳里,结果测出来的体温总是偏低。后来才发现,红外传感器前面必须开窗,而且窗口材料要用锗玻璃或者聚乙烯薄膜。普通玻璃会阻挡红外线,测出来全是错的。

接口方面,它支持PWM和SMBus。我个人习惯用SMBus,因为可以读到更详细的温度数据。PWM模式虽然简单,但精度只有0.02°C,而且占CPU资源。

// MLX90614 SMBus读取温度示例
// 注意:SMBus地址是0x5A,左移一位后是0xB4
uint8_t read_mlx90614_temp(float *temp) {
    uint8_t data[3];
    // 发送读取RAM命令,地址0x07
    i2c_write(0xB4, 0x07, 1);
    delay_ms(50);  // 必须等待转换完成
    i2c_read(0xB4, data, 3);
    
    // 数据格式:高字节+低字节,单位0.02°C
    uint16_t raw = (data[0] << 8) | data[1];
    *temp = raw * 0.02 - 273.15;  // 开尔文转摄氏度
    return 0;
}

1.3 TMP117:精度之王,但别被它骗了

TMP117的精度是±0.1°C,这数据看着就让人放心。我有个做医疗级体温贴的朋友,全系列都用它。为什么?因为医疗标准要求精度在±0.2°C以内,TMP117完全满足。

但我要说个实话——它的高精度是有代价的。你得做好PCB布局。我见过有人把TMP117放在大功率器件旁边,结果测出来的温度比实际高了2°C。这芯片对热源特别敏感,因为它本身就是个高精度温度计。

布局技巧:TMP117底下要铺地铜皮,而且远离电源芯片和MCU。我一般会在芯片周围挖一圈隔离槽,把热传导路径切断。另外,它的WSON封装底部有散热焊盘,一定要焊接到地平面,不然精度会打折扣。

功耗方面,TMP117在1Hz采样率下只有3.5μA,这数据非常漂亮。如果你做电池供电的体温贴,它比MAX30205省电得多。但注意,它有个转换时间——每次测量需要15.5ms,这期间不能读数据。

// TMP117 I2C读取示例
// 地址:0x48(默认)
float read_tmp117_temp(void) {
    uint8_t buf[2];
    // 读取温度寄存器(0x00)
    i2c_write(0x48, 0x00, 1);
    delay_ms(20);  // 等待转换完成
    i2c_read(0x48, buf, 2);
    
    int16_t raw = (buf[0] << 8) | buf[1];
    return raw * 0.0078125;  // 分辨率0.0078°C
}

1.4 MAX30205:医疗级专用,但功耗偏高

MAX30205是美信(现在叫ADI)专门为医疗体温监测设计的。它的精度在37~39°C范围内能达到±0.1°C,这个范围正好覆盖人体正常体温和发烧温度。说白了,它就是为体温计量身定做的。

但它有个明显的短板——功耗。连续测量模式下要600μA,比TMP117高了两个数量级。如果你做的是需要长时间佩戴的体温贴,电池会很快耗光。我建议只在需要高精度、短时间测量的场景用,比如医院病房的临时监测。

注意:MAX30205的I2C地址是固定的0x48、0x49、0x4A、0x4B四个选项,通过引脚配置。我当年犯过一个低级错误——把两个MAX30205都设成0x48,结果I2C总线上两个设备地址冲突,数据全乱了。记得每个设备要分配不同的地址。

另外,MAX30205有个很实用的功能——过温报警。你可以设置一个阈值,比如38.5°C,当体温超过这个值时,ALERT引脚会拉低。这个功能在做发烧报警器时特别方便,不用MCU一直轮询。

1.5 LMT70:模拟输出的另类选择

LMT70是个模拟输出的温度传感器。说白了,它输出的是电压,你需要用ADC去读。这听起来有点复古,但在某些场景下反而有优势。

我为什么这么说?因为模拟输出不需要I2C协议,不占用I2C总线。如果你MCU的I2C接口已经挂了很多设备,或者你用的是没有I2C的廉价MCU,LMT70就是个好选择。

它的精度是±0.13°C,比TMP117差一点,但比MLX90614好。功耗只有12μA,介于TMP117和MAX30205之间。不过要注意,它的输出是负温度系数——温度越高,电压越低。公式是:

// LMT70温度计算公式
// Vout 单位mV
// 温度范围:-55°C ~ 150°C
float temp = (Vout - 2285.5) / (-5.5);
// 或者用查表法,精度更高

我的经验:用LMT70时,ADC的精度很关键。如果你用10位ADC,分辨率只有0.2°C左右,浪费了传感器的精度。我建议至少用12位ADC,最好用16位的。另外,走线要短,避免引入噪声。我曾经因为走线太长,测出来的温度波动有0.5°C,后来加了RC滤波才解决。

1.6 选型总结:到底该用哪个?

说了这么多,我直接给你个选型建议:

  • 非接触式测温(门禁、婴儿测温):选MLX90614,没得选
  • 医疗级接触式(体温贴、病房监测):TMP117首选,MAX30205备选
  • 低成本、简单接口(玩具、简易体温计):LMT70
  • 需要过温报警(发烧报警器):MAX30205,自带ALERT引脚
  • 超低功耗(纽扣电池供电):TMP117,3.5μA无敌

最后说一句——别只看datasheet上的参数。实际用起来,PCB布局、电源噪声、环境温度都会影响精度。我建议你拿到芯片后,先做个简单的测试板,用恒温水槽校准一下。这一步省不了,真的。

下一章,咱们会深入讲接口设计,包括I2C的时序问题、模拟信号的抗干扰处理,还有怎么用MCU的ADC去读LMT70。到时候见。