DIY红外测温笔:从MLX90614传感器到3D打印外壳的完整制作指南
1. 项目概述与核心思路
红外测温笔,听起来像是个专业工具,但它的核心原理其实离我们并不遥远。想象一下,你用手靠近一个刚熄灭的灯泡,即使不接触,也能感受到它散发的热量。红外测温技术就是基于这个原理,任何温度高于绝对零度的物体都会向外辐射红外能量,温度越高,辐射越强。MLX90614这类红外测温传感器,就像一个高度灵敏的“电子皮肤”,它能捕捉到这种肉眼不可见的红外辐射,并将其转换为微弱的电信号。我们的任务,就是用一个“大脑”(微控制器)来解读这个信号,把它翻译成我们熟悉的摄氏度或华氏度,并显示出来。
这个项目的魅力在于,它把一个看似专业的工业检测工具,变成了一个可以亲手打造、功能完备的便携设备。我做的这款ThermoPen,目标很明确:要足够小巧,能像一支笔一样握在手里;要足够精准,能快速定位电路板上发热异常的芯片;还要足够“聪明”,能记录最高最低温度、显示电量,甚至用声音提醒你温度超标。它不是为了替代昂贵的工业级测温仪,而是为电子爱好者、创客、甚至是对技术好奇的学生,提供一个从原理到实物的完整学习与实践案例。你会发现,从画电路图到3D打印外壳,每一个环节都充满了工程实践的乐趣和挑战。
2. 核心硬件选型与设计解析
2.1 微控制器:为何选择ATmega328P
在核心“大脑”的选择上,我直接采用了与Arduino Uno/Nano同款的ATmega328P微控制器。这几乎是一个无需纠结的决定。首先,它的生态极其成熟。Arduino庞大的社区意味着你遇到的几乎所有问题,都能找到现成的库函数和解决方案。对于本项目需要用到的I2C通信(驱动OLED屏)、模拟输入(读取传感器)以及普通的数字IO(控制激光、按钮、蜂鸣器),ATmega328P都游刃有余。其次,它的功耗对于电池供电设备来说相对友好,尤其是在我们采用16MHz外部晶振(而非内部RC振荡器)并优化代码后,足以满足便携设备的续航要求。最后,从PCB设计角度讲,它的封装(TQFP-32)尺寸适中,手工焊接虽有挑战但完全可行,且相关的电源、复位、晶振电路都有非常成熟且经过验证的参考设计,大大降低了硬件设计的风险。
注意:虽然Arduino生态方便,但在最终产品中,我们是用ATmega328P作为独立MCU来设计的,并非直接使用Arduino开发板。这意味着我们需要在PCB上为其搭建最小系统,包括电源、晶振、复位电路和编程接口。这样做的好处是极大缩小了体积,并去掉了开发板上不必要的部分。
2.2 红外传感器:MLX90614的关键特性
MLX90614是本案的“眼睛”。我选择它的原因主要有三点:非接触测量、集成度高、接口简单。它内部已经集成了红外热电堆传感器、低噪声放大器和17位ADC,甚至还有一个DSP单元进行信号处理。这意味着它输出给微控制器的,已经是经过内部校准和线性化处理的数字温度值,极大简化了我们软件端的复杂度。它通过标准的I2C接口通信,只需要两根线(SDA, SCL)就能读取数据,节省了宝贵的IO口。
这里有一个非常重要的细节:测量视角(Field of View, FOV)。MLX90614有不同的FOV版本,常见的有90°和10°。对于测温笔这种需要“指哪打哪”的应用,必须选择小视角版本(如MLX90614ESF-BAA-10°)。90°的视角太广,测到的是一个大面积的平均温度,无法精确定位到某个微小的电阻或芯片引脚。小视角版本才能实现我们想要的“点测温”效果。在PCB布局时,传感器必须紧贴外壳前端的开孔,并且开孔大小要与传感器的感光区域匹配,避免外壳遮挡视野。
2.3 电源管理:锂电池充电与升降压电路
便携设备的核心是电源。我设计了一套完整的电源管理系统:
- 锂电池充电:采用了基于TP4056芯片的经典线性充电电路。通过Micro-USB接口输入5V,TP4056会以恒定电流/恒定电压方式为单节3.7V锂电池安全充电。板上的双色LED(红/蓝)能直观显示充电状态(充电中/充满)。
- 升降压电路:这是整个系统的“心脏”。锂电池的电压在3.0V-4.2V之间波动,而ATmega328P和OLED屏需要稳定的5V或3.3V工作电压。我选择了一颗同步升降压(Buck-Boost)芯片,例如TI的TPS63020。它能在输入电压高于、等于或低于输出电压时,都输出一个稳定的5V。这确保了即使电池电量即将耗尽(电压降至3.3V),设备仍能正常工作,榨干电池的最后一分能量,而不是像单纯的降压电路那样,电池电压一低于5V就关机。
实操心得:升降压芯片的PCB布局是重中之重。它的开关频率很高,输入和输出电容必须紧贴芯片引脚放置,电感要选择饱和电流足够的型号,并且反馈电阻的走线要短而粗,远离噪声源。我第一次打样就栽在这里,因为电容放远了,导致输出纹波巨大,系统不稳定。务必参考芯片数据手册的“PCB布局指南”章节,一字不落地照做。
2.4 人机交互:OLED屏、按钮与蜂鸣器
人机交互决定了产品的使用体验。我选用了一块0.96英寸的128x64像素的OLED屏(SSD1306驱动)。它功耗极低、无需背光、对比度高,在阳光下也有不错的可视性。通过I2C驱动,仅需4根线(VCC, GND, SCL, SDA)。屏幕上同时显示物体温度、环境温度、最高/最低温以及一个简单的电池图标,信息集中,一目了然。
按钮设计有一个巧思:它不是普通的常开按钮,而是作为整个系统的“电源开关”。电路设计上,按钮直接控制一个MOS管,用来连通电池与主电路。按下按钮,系统通电;松开按钮,由于大电容的储能,系统还会维持供电4-5秒,然后自动关机。这实现了“即按即用,松手延时关”的便捷操作,避免了频繁开关机,也防止了用户忘记关机导致电池耗尽。
蜂鸣器则用于提供音频反馈。开机时有一声短促的“嘀”提示,当测量温度超过预设的报警阈值(例如120°C,针对电子维修中元件过热预警)时,会发出连续的“滴滴”声,即使用户没看屏幕,也能及时得到提醒。
3. 从原理图到PCB的实战设计
3.1 原理图绘制:在KiCad中搭建系统框架
我使用KiCad进行所有电子设计,它是开源免费的,功能却毫不逊色。首先,根据功能模块划分原理图:
- MCU最小系统:放置ATmega328P,连接16MHz晶振及两个22pF负载电容、10k上拉复位电路、电源去耦电容(一个10uF电解电容搭配一个0.1uF陶瓷电容紧贴VCC引脚)。
- 传感器与外围接口:放置MLX90614的符号,连接其SDA、SCL至MCU的对应引脚(并分别接4.7k上拉电阻至3.3V),VDD接3.3V。为OLED屏、激光二极管、蜂鸣器分别预留连接器(排针或焊盘)。
- 电源模块:绘制TP4056充电电路和TPS63020升降压电路。特别注意,TP4056的PROG引脚需连接一个1.2k电阻到地来设定充电电流(约1000mA),其CE(使能)引脚通常上拉。TPS63020的反馈电阻需根据公式
Vout = 0.8V * (1 + R1/R2)计算,以得到5V输出。 - 按钮控制电路:使用一个PMOS管(如AO3401)。按钮一端接地,另一端接PMOS的栅极并通过一个大电阻(如100k)上拉到电池正极。当按钮按下,栅极被拉低,PMOS导通,电池电压供给后级电路。
绘制时,每一个网络(Net)都要清晰命名,例如+5V,+3V3,BAT+,GND,I2C_SDA,I2C_SCL。这为后续的PCB布局和检查提供了巨大便利。
3.2 PCB布局:在二维平面上进行三维思考
将原理图导入PCB编辑器后,真正的挑战开始。PCB尺寸被严格限制在“笔杆”的横截面内,因此布局必须极度紧凑。
- 板框与定位:首先根据3D模型确定PCB的精确外形和所有固定孔、接口开孔的位置。
- 模块化布局:遵循“信号流”方向。电源输入(USB口)放在板子一端,经过充电芯片、电池接口,再到升降压芯片,最后输出到各模块。MCU作为核心,放在板子中央。I2C设备(传感器、OLED)尽量靠近MCU以减少走线长度。
- 电源优先:先布置电源路径。电源走线要宽!电池输入、5V、3.3V的主干道,我使用了至少0.5mm(约20mil)的线宽。所有IC的电源引脚附近,都必须紧贴放置一个0.1uF的陶瓷去耦电容,这个电容的回路要尽可能小。
- 敏感信号处理:晶振电路是高频噪声源。晶振要紧贴MCU的XTAL引脚,其下方的PCB层最好有一个完整的地平面屏蔽,走线要短而直,并用地线包围。
- 散热考虑:TP4056和TPS63020在工作时会有发热。我在它们的芯片底部(Thermal Pad)打了多个过孔连接到背面的大面积铜皮上,利用整个PCB作为散热器。
- 连接器与焊接:考虑到后续组装,所有需要外接的部件(屏幕、激光头、电池触点)我都用了通孔焊盘或排母,这样可以用导线连接,比直接焊接FPC排线更灵活,也便于维修。
布局完成后,进行DRC(设计规则检查),设置好最小线宽/线距(我设为0.2mm/0.2mm)、过孔尺寸等规则,确保没有短路、断路的错误。
3.3 打样与物料准备
PCB设计文件(Gerber)发送给制板厂打样。同时,根据原理图生成BOM(物料清单)。我习惯用表格管理,包含:位号、型号、参数、封装、数量、采购链接、单价。对于MLX90614、TPS63020这类关键芯片,务必从官方授权代理商或信誉好的平台购买,避免买到翻新或假货。电阻电容等无源器件,选择0603(1608公制)封装,这个尺寸手工焊接难度适中,也能有效节省空间。
4. 焊接、编程与调试全记录
4.1 手工焊接与回流焊接的混合工艺
面对这块高密度的双面贴片PCB,我采用了混合焊接工艺:
- 回流焊接:对于QFN封装(底部有散热焊盘)的TPS63020和微型晶振,必须使用焊膏和热风枪或回流焊炉。我先用钢网(如果打样时选择了SMT服务,可以向板厂要)或直接用注射器针头,小心翼翼地在焊盘上涂上少量焊膏,然后用镊子将元件对准放好。使用热风枪时,温度曲线很关键:先整体预热(150°C左右),然后对准芯片区域加热至焊膏熔化(约220-230°C),看到芯片微微下沉(self-alignment effect)后移开风枪,自然冷却。切记要等完全冷却后再移动板子。
- 手工烙铁焊接:对于电阻、电容、LED、连接器等,使用尖头烙铁和细焊丝(0.3mm-0.5mm)。焊接时遵循“先矮后高、先小后大”的原则。给焊盘上一点锡,用镊子夹住元件一端固定并焊接,再焊接另一端。焊接完成后,必须用放大镜或手机微距模式仔细检查,防止桥接(短路)或虚焊。
踩坑实录:第一次焊接升降压芯片后,一上电芯片就发烫冒烟。排查后发现是芯片底部的散热焊盘(必须接地)没有焊接好,呈悬空状态,导致芯片无法散热且电气连接异常。解决方法是在PCB设计时,就在该焊盘上多打几个大过孔。焊接时,先在焊盘上上锡,然后用热风枪加热,让焊锡通过过孔流到背面,形成牢固的焊接和散热通道。
4.2 固件开发:让硬件“活”起来
硬件焊接检查无误后,就可以开始编程了。代码结构清晰:
#include <Wire.h> // I2C库 #include <Adafruit_MLX90614.h> // 红外传感器库 #include <Adafruit_SSD1306.h> // OLED屏库 Adafruit_MLX90614 mlx = Adafruit_MLX90614(); Adafruit_SSD1306 display(128, 64, &Wire, -1); float objTemp, ambTemp, maxTemp = -273.15, minTemp = 200.0; // 初始化极值 int batteryVoltage; void setup() { // 初始化串口、I2C、屏幕 Serial.begin(9600); Wire.begin(); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); // 播放开机提示音 tone(BUZZER_PIN, 1000, 100); delay(1000); // 开启激光指示器 digitalWrite(LASER_PIN, HIGH); // 初始化传感器 if (!mlx.begin()) { Serial.println("Error connecting to MLX90614!"); while (1); } } void loop() { // 1. 读取温度 objTemp = mlx.readObjectTempC(); ambTemp = mlx.readAmbientTempC(); // 2. 更新最高/最低温度 if (objTemp > maxTemp) maxTemp = objTemp; if (objTemp < minTemp) minTemp = objTemp; // 3. 读取电池电压(通过MCU的ADC分压测量) batteryVoltage = readBatteryVoltage(); // 4. 在OLED上显示所有信息 display.clearDisplay(); display.setTextSize(1); display.setCursor(0,0); display.print("Obj: "); display.print(objTemp); display.println(" C"); display.print("Amb: "); display.print(ambTemp); display.println(" C"); display.print("Max: "); display.print(maxTemp); display.println(" C"); display.print("Min: "); display.print(minTemp); display.println(" C"); display.drawBitmap(100, 0, getBatteryIcon(batteryVoltage), 16, 8, WHITE); // 绘制电池图标 display.display(); // 5. 高温报警判断 if (objTemp > 120.0) { tone(BUZZER_PIN, 2000, 500); } delay(200); // 刷新率约5Hz }编程使用“Arduino as ISP”方式。需要另一块Arduino开发板(如Uno)作为编程器,将其连接到ThermoPen PCB上的ISP接口(MOSI, MISO, SCK, RESET, VCC, GND),然后在Arduino IDE中选择编程器为“Arduino as ISP”,点击“上传”即可将代码烧录到我们自制的PCB上的ATmega328P中。
4.3 系统集成与功能验证
所有部件焊接并编程后,进入最激动人心的组装测试阶段:
- 分模块测试:先不装壳,用杜邦线连接OLED屏、激光头、电池,按下按钮,看屏幕是否点亮、激光是否射出、蜂鸣器有无开机声。用万用表测量5V和3.3V电压是否稳定。
- 传感器校准:这是保证精度的关键。MLX90614出厂已校准,但为了验证,我准备了两个已知温度的热源:一个是冰水混合物(0°C),一个是沸腾的水(当地沸点,约99°C)。将传感器对准这些目标(注意距离和视角),读取数值并与理论值对比。如果偏差是固定的,可以在代码里添加一个偏移量进行软件补偿。我的传感器在室温下表现很好,在高温段略有偏差,属于可接受范围。
- 整机装配:按照设计,先将电池放入笔壳下半部分,再将PCB板卡入定位槽。接着,将OLED屏的排线、激光二极管的导线、电池触点等逐一焊接或插接到PCB对应接口上。这个过程中要格外小心导线的长度和走向,避免挤压或短路。最后盖上后盖。
- 最终验证:
- 充电测试:插入USB线,观察侧面充电指示灯是否为红色,充满后是否变蓝。用万用表监测电池电压,看能否充至4.2V左右。
- 测温测试:对准不同温度的物体(手心、电脑散热口、一杯热水),观察读数是否合理、响应是否迅速。
- 激光对准测试:激光点是否与传感器视场中心重合?我通过微调激光管在孔内的位置,确保激光点指示的位置就是实际测量的中心点。
- 续航测试:充满电后连续使用,记录从满电到低压报警自动关机的时间。我的设计在正常间歇使用下,可以坚持数周。
5. 外壳设计与3D打印的工程实现
5.1 在Solidworks中构建三维模型
产品设计不仅仅是做个盒子把电路装进去,它关乎手感、人机工程学和可靠性。我在Solidworks中从内部开始建模:
- 核心骨架:首先导入PCB和电池的精确3D模型(可从元器件供应商网站下载STEP文件)。以它们为基准,设计内部的支撑结构。电池仓需要设计弹性的卡扣,既能固定电池防止晃动,又便于更换。PCB则通过四周的卡槽和底部的支柱固定,避免任何方向的移动。
- 人机交互面:屏幕窗口、按钮孔、激光/传感器开孔、充电指示灯孔的位置必须精确。按钮设计是难点:我设计了一个内凹的按钮槽,将一个小巧的贴片微动开关放在PCB上,然后加工了一个独立的圆形铝制按钮帽。按钮帽内径略小于开关,外径略大于外壳开孔,利用塑料的弹性将其卡在中间,按下时触发开关,手感清晰且耐用。
- 分体与装配:采用前后壳对扣的方式。在分型面上设计了一圈相互咬合的卡扣,并在关键位置预留了螺丝柱(虽然最终没用螺丝,但作为加强筋)。后盖设计成滑动式,底部有一个小凸起作为开启的着力点。装配顺序是:放入电池 -> 放入PCB -> 连接导线 -> 盖上后盖。整个过程无需工具。
- 细节优化:所有边角都做了倒圆角处理,避免刮手。在握持区域增加了一些细微的防滑纹理。激光管和传感器开孔处设计了导光柱结构,让激光点更集中清晰。
5.2 3D打印:从数字模型到物理实体
我将STL文件用PrusaSlicer软件进行切片,材料选择ABS,因为它强度较好,且耐温性比PLA强(考虑到内部可能有元件发热)。打印参数设置如下:
- 层高:0.2mm(平衡精度与速度)
- 填充密度:25%(提供足够强度又不至于太重)
- 支撑:对于按钮孔、内部悬空结构等,启用“仅在打印床接触面生成支撑”
- 打印方向:为了让笔身主体有最好的表面质量(减少层纹对握感的影响),我选择让笔“躺”着打印,而不是竖起来。这虽然增加了支撑,但获得了更光滑的侧面。
打印完成后,需要仔细去除支撑材料,特别是内部狭小空间的支撑,可以用尖头镊子和小刀耐心清理。第一次打印出来的外壳,按钮孔尺寸偏小,铝按钮装不进去;电池仓也略紧,电池放入费力。这就是原型迭代的意义。我回到CAD软件,将相关尺寸放大0.2mm,再次打印测试。通常需要3-5次迭代,才能得到松紧度恰到好处的配合。
进阶技巧:如果想要更精致的外观,可以对打印件进行后处理。用砂纸(从400目到1000目)逐步打磨表面,去除层纹。然后使用丙烯酸补土(俗称“水补土”)喷涂填充细微划痕,最后喷上哑光或半光的手工漆。这不仅美观,还能为ABS提供一层保护。不过对于功能原型,打磨和喷漆可能不是必须的。
6. 常见问题排查与优化建议
在制作和后续使用中,你可能会遇到以下问题,这里提供我的排查思路和解决方案:
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 上电无任何反应 | 1. 电池没电或接反。 2. 电源开关(按钮/MOS管)电路故障。 3. 升降压电路不工作。 4. MCU未正确编程或损坏。 | 1. 用万用表测电池电压,检查极性。 2. 按下按钮,测量MOS管输出端是否有电池电压。检查按钮、电阻、MOS管是否焊接良好。 3. 测量升降压芯片输入/输出电压。检查电感、电容、反馈电阻值及焊接。 4. 尝试通过ISP接口重新烧录Bootloader和程序。 |
| 屏幕亮但无数据显示/花屏 | 1. OLED屏与MCU的I2C通信失败。 2. 屏幕供电异常。 3. 代码中I2C地址或初始化错误。 | 1. 检查SDA、SCL线路是否连通,上拉电阻是否焊上。 2. 测量屏幕VCC引脚电压是否为3.3V或5V(取决于屏的型号)。 3. 使用I2C扫描程序(Arduino IDE示例中有)确认屏幕的I2C地址(通常是0x3C或0x3D),并修改代码。 |
| 测温读数不准或跳动大 | 1. 传感器与被测物体距离/角度不对。 2. 传感器视窗被污染。 3. 电源噪声干扰传感器模拟部分。 4. 代码读取速度过快,传感器未稳定。 | 1. 确保使用小视角传感器,并正对被测点,距离在几厘米内。 2. 用棉签蘸酒精轻轻清洁传感器表面的透光窗。 3. 检查传感器VDD引脚旁的滤波电容(通常10uF+0.1uF)是否焊好且靠近引脚。 4. 在两次读取间增加延时(如 delay(100))。MLX90614的刷新率通常为2Hz或更高,无需过快读取。 |
| 激光点与测温点不重合 | 激光管与传感器光路不平行。 | 在组装前进行光学校准。固定传感器,点亮激光,在固定距离(如5cm)的墙上标记激光点。然后用测温笔测量该标记点的温度,同时微调激光管角度,直到读数达到峰值,此时即为对准。最后用胶固定激光管。 |
| 耗电极快 | 1. 程序未进入低功耗模式。 2. 激光管或屏幕常亮。 3. 升降压电路静态电流过大。 | 1. 优化代码,在松手延时结束后,让MCU进入深度睡眠(powerDown模式),仅通过外部中断(按钮按下)唤醒。2. 确保激光和屏幕仅在按下按钮后点亮,并在延时结束后关闭。 3. 选择低静态电流的升降压芯片,并检查是否有元件漏电。 |
项目优化与扩展思路:
- 低功耗升级:当前版本松开按钮后靠电容维持供电,仍有功耗。可以修改电路,使按钮直接控制一个低压差稳压器(LDO)的使能端,松开按钮后彻底切断所有电路的供电,实现真正的零待机功耗。
- 数据记录:增加一个微型SD卡模块,可以将温度读数连同时间戳一起保存下来,用于长时间监测温度变化。
- 蓝牙传输:集成HC-05或HM-10蓝牙模块,将实时温度数据发送到手机APP,实现远程监测和数据可视化。
- 多点测温:使用多个MLX90614传感器,或者使用带阵列的红外传感器(如MLX90640),实现简单的热成像功能,在屏幕上以灰度图或伪彩图显示温度分布。
制作这样一个项目,最大的收获不是最终拿到手里的那支“笔”,而是从需求定义、电路设计、软件编程、结构设计到调试测试的完整流程体验。每一个环节的坑,都是宝贵的经验。当你按下按钮,激光亮起,屏幕上跳出准确的温度读数时,那种将想法变为现实的成就感,是无可替代的。希望这份详细的记录,能帮你少走些弯路,更顺利地完成属于自己的创作。
