基于Arduino与DS18B20的DIY儿童体温监测手表制作全攻略
1. 项目缘起为什么选择DIY儿童体温手表开学季临近家长们又开始为孩子的健康安全操心。每天上学前测体温成了很多家庭的例行公事。传统的额温枪或耳温枪虽然准确但需要家长操作对于已经上小学、开始追求独立的孩子来说总显得有些“被照顾”。市面上倒是有一些智能穿戴设备宣称有体温监测功能但要么价格不菲要么功能繁杂核心的体温监测反而成了配角数据准确性也存疑。于是一个想法冒了出来为什么不自己动手给孩子做一款专属的体温监测手表呢它不需要复杂的社交、支付功能核心任务就一个——准确、便捷地测量并显示体温。当孩子感觉不适或者家长想随时了解孩子状态时抬腕就能看到清晰的读数。更重要的是这个过程本身就是一次绝佳的亲子科技启蒙。我们可以一起挑选零件、焊接电路、设计外壳最后看着一个想法从无到有变成孩子手腕上独一无二的“健康卫士”。这个项目我们选择Arduino作为核心大脑。原因很简单它开源、易上手有庞大的社区和丰富的库支持非常适合快速原型开发。显示部分一块小巧的OLED屏幕足以清晰展示体温数字感知部分一个贴片的热敏传感器如NTC或DS18B20负责采集温度数据为了增加交互和提醒我们还会加入一个蜂鸣器在体温异常时发出提示音。最后为了让手表真正“可穿戴”我们会利用3D打印技术为孩子量身定制一个舒适、坚固且充满个性的外壳。整个项目硬件成本可控软件逻辑清晰制作过程充满乐趣。它不仅仅是一个工具更是一份充满心意的开学礼物。下面我就把从零开始制作这款体温手表的完整过程、踩过的坑以及积累的经验毫无保留地分享出来。2. 核心器件选型与电路设计逻辑动手之前理清思路是关键。一款体温手表我们需要考虑几个核心问题测量哪里如何保证相对准确如何供电如何佩戴围绕这些问题我们来逐一敲定器件。2.1 主控板为什么是Arduino Nano在Arduino家族中Uno板固然经典但用于可穿戴设备显得过于庞大笨重。Arduino Nano成为了更优的选择。它核心的ATmega328P芯片与Uno相同性能完全够用但体积小巧长约45mm宽约18mm非常适合嵌入到手表外壳中。其丰富的数字和模拟IO口也足以驱动本项目所需的屏幕、传感器和蜂鸣器。注意市面上有不同版本的Nano板建议选择带有Type-C接口的版本充电和编程都更方便。同时确保板载的5V稳压芯片能提供足够的电流通常500mA以上以稳定驱动所有外设。2.2 温度传感器DS18B20与NTC热敏电阻的抉择这是影响测量准确性的核心。我们有两个主流选择数字传感器DS18B20和模拟传感器NTC热敏电阻。DS18B20它的优势是“数字”。它内部集成了ADC模数转换器和计算单元直接通过单总线One-Wire协议输出数字温度值精度可达±0.5°C。抗干扰能力强传输距离远且每个传感器有唯一ID理论上可以一线挂多个。但它的缺点是响应速度相对慢一些且需要特定的库支持。NTC热敏电阻这是一种模拟器件其电阻值随温度变化。我们需要通过Arduino的模拟输入引脚读取其分压值再根据公式换算成温度。它的优点是成本极低响应速度快。但缺点也很明显精度受自身精度、参考电压稳定性、上拉电阻精度等多重因素影响需要复杂的校准过程且易受电磁干扰。对于儿童体温监测我们追求的是相对稳定、可靠的读数而非实验室级的绝对精度。考虑到手腕温度本身受环境、血液循环影响较大±0.5°C的误差在可接受范围内。更重要的是DS18B20的“即插即用”特性极大简化了我们的软件开发和校准工作。因此我强烈推荐使用防水封装型的DS18B20。我们可以将其用导热硅胶固定在外壳内侧使其紧贴皮肤并用海绵或软胶进行隔离缓冲避免硬物硌到孩子的手腕。2.3 显示模块OLED屏幕的优势显示部分OLED屏幕是不二之选。相比于传统的LCD屏OLED具有自发光、对比度高、视角广、响应速度快、功耗低显示深色内容时等优点。对于手表这种小型设备一块0.96英寸、128x64分辨率的I2C接口OLED模块正合适。它只需要四根线VCC, GND, SCL, SDA就能驱动节省了宝贵的IO口。I2C通信也相对简单稳定。在编程时我们可以利用Adafruit_GFX和Adafruit_SSD1306这两个强大的库轻松地在屏幕上绘制大号数字、文字甚至简单的图标让体温读数一目了然。2.4 提醒与交互无源蜂鸣器蜂鸣器分为有源和无源两种。有源蜂鸣器内部有振荡电路通电就响频率固定无源蜂鸣器内部没有振荡源需要外部提供一定频率的方波驱动才能发声因此可以演奏不同音调。这里我们选择无源蜂鸣器。原因在于我们不仅需要“嘀”一声的简单提示可能还需要设计不同的提示音调来区分“测量中”、“测量完成”、“体温正常”、“体温偏高”等不同状态。通过Arduino的tone()函数我们可以轻松控制无源蜂鸣器发出不同频率的声音实现更丰富的交互反馈。2.5 供电与续航考量可穿戴设备的续航是痛点。Arduino Nano的工作电压是5V我们可以使用一枚常见的3.7V、500mAh左右的锂电池供电并通过一个微型TP4056充电管理模块进行充电。Nano板载的AMS1117稳压芯片可以将电池电压稳定到5V。但这里有个关键点为了延长续航我们不能让设备一直全功率运行。我们需要在软件上实现“抬手亮屏”或“按键唤醒”功能。这可以通过一个微动开关或者更理想的——一个**数字震动传感器SW-420**来实现。当检测到手腕震动抬手动作时才唤醒系统进行测量和显示持续无操作一段时间后自动进入深度休眠。Arduino Nano本身支持低功耗模式结合外部中断唤醒可以大幅降低待机功耗。根据我的实测在每天测量20-30次的情况下500mAh的电池可以轻松支撑一周以上的续航。2.6 电路连接原理图将所有器件连接起来并不复杂。下面是一个简洁的连接示意图用文字描述电源部分锂电池正负极接TP4056模块的B和B-。TP4056的OUT和OUT-分别接Nano的VIN和GND。这样USB口可以充电电池可以供电。DS18B20VCC接Nano的5VGND接GNDDQ数据线接一个数字引脚如D2同时在该引脚与5V之间接一个4.7KΩ的上拉电阻。OLEDVCC接Nano的5VGND接GNDSCL接A5Nano的I2C时钟线SDA接A4Nano的I2C数据线。无源蜂鸣器正极接一个数字引脚如D3负极接GND。震动传感器用于唤醒VCC接Nano的5VGND接GNDDO数字输出接一个支持外部中断的引脚如D2注意与DS18B20分时复用或使用其他引脚如D3。提示在实际焊接时建议先在一块面包板上搭建测试电路确保所有功能正常后再使用杜邦线或更专业的PCB穿孔板进行最终焊接这样更可靠。3. 软件编程从数据采集到智能提醒硬件是骨架软件是灵魂。我们的程序需要稳定地读取温度、处理数据、控制显示和发声。整个逻辑可以分为初始化、低功耗休眠、中断唤醒、测量循环、显示与提醒几个部分。3.1 开发环境搭建与库管理首先你需要安装Arduino IDE。建议去官网下载最新版本安装过程很简单。安装完成后我们需要导入本项目必需的库。打开Arduino IDE依次点击“工具” - “管理库...”在库管理器中搜索并安装以下库DallasTemperature用于驱动DS18B20传感器。OneWireDallasTemperature库依赖的单总线协议库。Adafruit_GFX图形库。Adafruit_SSD1306用于驱动SSD1306芯片的OLED屏。安装完成后在代码开头通过#include语句引入它们。3.2 核心代码逻辑剖析下面我分段解释核心代码的逻辑而不是直接扔出一整段。理解逻辑比复制代码更重要。第一部分全局定义与初始化#include OneWire.h #include DallasTemperature.h #include Adafruit_GFX.h #include Adafruit_SSD1306.h #include avr/sleep.h // 用于低功耗模式 // 引脚定义 #define ONE_WIRE_BUS 2 // DS18B20数据线接D2 #define BUZZER_PIN 3 // 蜂鸣器接D3 #define VIBRATION_PIN 2 // 震动传感器接D2 (外部中断0) // 温度相关 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(oneWire); float currentTempC 0.0; const float HIGH_TEMP_THRESHOLD 37.5; // 高体温阈值单位°C // OLED对象定义 (128x64分辨率I2C地址一般为0x3C) Adafruit_SSD1306 display(128, 64, Wire, -1); // 状态标志 volatile bool isWokenUp false; // 中断唤醒标志 unsigned long lastActiveTime 0; const unsigned long SLEEP_DELAY_MS 10000; // 无操作10秒后休眠 void setup() { Serial.begin(9600); pinMode(BUZZER_PIN, OUTPUT); pinMode(VIBRATION_PIN, INPUT_PULLUP); // 启用内部上拉电阻 // 初始化OLED if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F(SSD1306 allocation failed)); for(;;); // 死循环初始化失败 } display.clearDisplay(); display.setTextSize(2); display.setTextColor(SSD1306_WHITE); display.setCursor(0,0); display.println(Hello!); display.display(); delay(1000); // 初始化温度传感器 sensors.begin(); // 配置外部中断震动传感器引脚下降沿触发传感器震动时输出低电平 attachInterrupt(digitalPinToInterrupt(VIBRATION_PIN), wakeUp, FALLING); // 开机提示音 beep(1000, 200); }这段代码完成了硬件的初始化。关键点在于配置了外部中断attachInterrupt当震动传感器触发手腕抬起时会调用wakeUp函数。volatile关键字告诉编译器isWokenUp变量可能被中断服务程序修改需要特殊处理。第二部分中断服务与低功耗管理// 中断服务程序 void wakeUp() { isWokenUp true; } // 进入低功耗模式 void enterSleepMode() { display.clearDisplay(); display.display(); // 关闭显示以省电 display.ssd1306_command(SSD1306_DISPLAYOFF); // 彻底关闭OLED电源 set_sleep_mode(SLEEP_MODE_PWR_DOWN); // 设置最省电的模式 sleep_enable(); attachInterrupt(digitalPinToInterrupt(VIBRATION_PIN), wakeUp, FALLING); // 重新绑定中断唤醒后需重新绑定 sleep_mode(); // 进入睡眠 // 程序在此暂停直到被中断唤醒 sleep_disable(); // 唤醒后继续执行 detachInterrupt(digitalPinToInterrupt(VIBRATION_PIN)); // 解除中断防止测量过程中误触发 display.ssd1306_command(SSD1306_DISPLAYON); // 重新开启OLED beep(800, 100); // 唤醒提示音 }enterSleepMode函数是省电的关键。它先关闭屏幕然后让Arduino进入最深度的休眠模式SLEEP_MODE_PWR_DOWN此时CPU和大部分外设都停止工作功耗可降至微安级别。只有外部中断等少数功能可以唤醒它。第三部分主循环与体温测量void loop() { if (isWokenUp) { isWokenUp false; lastActiveTime millis(); // 记录最后一次活动时间 measureAndDisplayTemp(); } // 检查是否超时超时则进入休眠 if (millis() - lastActiveTime SLEEP_DELAY_MS) { enterSleepMode(); } delay(100); // 短暂延时降低CPU占用 } void measureAndDisplayTemp() { display.clearDisplay(); display.setTextSize(1); display.setCursor(0, 0); display.println(Measuring...); display.display(); sensors.requestTemperatures(); // 发送测温命令 delay(750); // 等待DS18B20转换完成12位精度下最大需750ms currentTempC sensors.getTempCByIndex(0); // 获取第一个传感器的温度值 // 显示结果 display.clearDisplay(); display.setTextSize(3); // 大号字体显示温度 display.setCursor(10, 15); display.print(currentTempC, 1); // 显示一位小数 display.println( C); display.setTextSize(1); display.setCursor(0, 50); if (currentTempC HIGH_TEMP_THRESHOLD) { display.println(Temp HIGH!); display.display(); alertHighTemp(); // 触发高温警报 } else { display.println(Temp Normal); display.display(); beep(600, 300); // 正常提示音 } }主循环loop()不断检查是否被唤醒。一旦唤醒就执行一次完整的测量和显示流程并重置活动计时器。如果一段时间没有新的唤醒则自动进入休眠。measureAndDisplayTemp函数是核心它控制测温流程并根据结果在屏幕上显示不同信息、播放不同提示音。第四部分声音提示函数void beep(int frequency, int duration) { tone(BUZZER_PIN, frequency, duration); delay(duration 50); // 等待发声完成 noTone(BUZZER_PIN); } void alertHighTemp() { for (int i 0; i 3; i) { tone(BUZZER_PIN, 800, 300); delay(400); noTone(BUZZER_PIN); delay(200); } }这里实现了两种声音提示beep用于一般提示alertHighTemp用于高温警报采用三次急促的蜂鸣更容易引起注意。将以上代码段组合起来就是一个完整的、具备低功耗唤醒功能的体温测量程序。你可以根据实际硬件连接修改引脚定义并调整阈值、延时等参数。4. 外壳设计与3D打印实战电路和代码都跑通了但一堆裸露的线路板还不能戴在手上。一个舒适、安全、美观的外壳至关重要。这就是3D打印大显身手的地方。4.1 设计前的关键测量与构思设计外壳不是天马行空首先要“量体裁衣”。测量孩子手腕用软尺测量孩子手腕最细处的周长以及手腕的宽度和厚度。这决定了表带的长度和宽度。测量核心组件用游标卡尺精确测量Arduino Nano、OLED屏幕、电池、充电模块等所有需要放入外壳的元件的长、宽、高。别忘了留出连接线和焊点的高度空间。确定佩戴方式是传统的表扣式还是更简单的魔术贴式对于儿童魔术贴调节更方便也更安全避免表扣刮伤。我选择了魔术贴方案。基于以上我构思了一个两段式结构上盖和底壳。底壳主要容纳电路板和电池上盖则固定OLED屏幕并开有显示窗口。两者通过螺丝或卡扣固定。表带部分与底壳一体打印末端预留穿魔术贴的孔洞。4.2 使用Fusion 360进行建模我推荐使用AutodeskFusion 360进行建模它对个人用户免费且功能强大。建模过程可以概括为“从内到外”创建基础草图根据核心组件Nano板的尺寸绘制一个矩形作为底壳的内部基准。推拉成型与抽壳将草图拉伸成实体然后使用“抽壳”命令挖空内部形成盒状。壁厚建议在1.5mm-2mm之间以保证强度同时节省材料。添加定位柱和螺丝柱在底壳内部角落创建几个圆柱体高度与PCB板上的安装孔匹配用于固定PCB。同时在底壳四角创建更高的螺丝柱用于和上盖固定。开孔为USB接口、充电指示灯、复位按钮、蜂鸣器出声孔等开出对应的孔洞。这里务必反复核对尺寸宁小勿大后期可以慢慢打磨扩大。创建上盖同样方法创建上盖实体并在对应OLED屏幕的位置开出显示窗口。上盖内侧可以设计一些卡扣或定位边使其能与底壳精准扣合。设计表带从底壳两侧延伸出表带。表带截面可以设计成弧形更贴合手腕。在末端设计穿魔术贴的方孔或圆孔。倒圆角对所有外边缘特别是接触手腕的部分进行倒圆角处理避免划伤皮肤。提示在Fusion 360中善用“参数”功能。将手腕尺寸、PCB尺寸等设为用户参数这样后期修改尺寸时只需修改参数值整个模型会自动更新非常高效。4.3 切片与打印参数设置模型建好后导出为STL格式导入到切片软件如Cura、PrusaSlicer中。材料选择推荐使用PLA材料。它打印容易无异味强度足够且有多种颜色可选适合儿童佩戴。如果追求更好的柔韧性和耐用性可以考虑PETG。打印方向将底壳的开口面朝上打印。这样内部的支撑结构更容易去除。表带部分可以平放打印。层高与填充层高选择0.2mm在精度和速度间取得平衡。填充密度15%-20%即可既能保证强度又节省材料和时间。支撑设置对于底壳内部的悬空部分如螺丝柱顶部必须生成支撑。支撑类型选择“树状支撑”或“线材支撑”接触面更小更容易拆除。首层附着开启裙边Skirt或 brim底垫防止打印件翘边确保打印成功。切片完成后将生成的Gcode文件发送给3D打印机就可以开始打印了。打印时间根据模型大小可能在4-8小时左右。4.4 后处理与装配打印完成小心取下模型用工具钳仔细去除所有支撑材料。然后用小锉刀或砂纸打磨掉毛刺和粗糙的边缘特别是表带内侧和所有开孔边缘务必打磨光滑。接下来就是最激动人心的装配环节电路总装将焊接好的核心电路Nano、传感器、蜂鸣器用螺丝固定在底壳的定位柱上。电池可以用双面胶或扎带固定。屏幕安装将OLED屏幕从内侧装入上盖的显示窗口可以用少量热熔胶或强力双面胶在四周固定。连接与测试将屏幕的排线穿过底壳的走线槽与主板连接。此时可以先不盖上盖通电测试所有功能是否正常。最终合盖测试无误后理好内部线材用短螺丝将上盖和底壳拧紧。注意螺丝不要拧得过紧以免压坏内部元件或撑裂塑料柱。安装表带将魔术贴的钩面硬面和毛面软面分别穿过表带两端的孔反折粘贴固定。根据孩子手腕粗细调整粘贴位置。至此一个功能完整、外观独特的DIY儿童体温手表就诞生了你可以和孩子一起为它涂装颜色贴上喜欢的贴纸让它成为独一无二的专属物品。5. 校准、测试与日常使用心得硬件组装完成软件也烧录进去了但别急着给孩子戴上。最后的校准和测试环节决定了这款手表的可靠性和实用性。5.1 体温传感器的校准虽然DS18B20出厂有精度标定但不同的安装位置是否紧贴皮肤、不同的外壳材料塑料的隔热性都会引入系统误差。因此进行简单的对比校准非常必要。你需要准备一个可靠的医用电子体温计最好是口腔或腋下用的精度较高作为参考。具体步骤如下将做好的手表和参考体温计同时置于一个稳定的环境温度下比如室内静止空气静置10分钟记录两者的读数。这个差值可以看作是“环境偏移”。将手表戴在自己手腕上确保传感器贴紧皮肤同时用参考体温计测量腋下温度腋下温度更接近核心体温但比手腕温度高约0.5-1°C。静坐15分钟后同时读取两个值。重复步骤2多次取平均值。你会发现手腕温度稳定后与参考体温计存在一个相对固定的差值比如手腕温度比腋下低0.8°C。得到这个系统差值后我们可以在代码中进行补偿。修改measureAndDisplayTemp函数中的温度读取部分currentTempC sensors.getTempCByIndex(0) CALIBRATION_OFFSET; // 增加校准偏移量CALIBRATION_OFFSET就是你计算出的差值例如0.8。注意这个校准是针对特定佩戴方式和个体的如果手表佩戴松紧度变化很大会影响测量结果。5.2 功能与压力测试校准后需要进行全面测试唤醒测试反复模拟抬手动作检查震动传感器是否能稳定唤醒设备屏幕点亮和提示音是否正常。测量稳定性测试将手表静置在桌面上连续测量10次观察温度读数波动。DS18B20在静止空气中读数应该非常稳定波动在0.1°C以内。续航测试充满电后模拟日常使用频率如每小时唤醒测量一次记录从满电到自动关机的时间评估实际续航是否符合预期。高温警报测试用手握住传感器部位使其温度升高超过设定阈值如37.5°C检查是否触发蜂鸣警报和屏幕提示。佩戴舒适度测试让孩子试戴一段时间询问是否有硌手感表带松紧是否合适魔术贴是否容易刮到衣服。5.3 日常使用注意事项与优化建议经过一段时间的使用我总结出以下几点心得佩戴是关键测量准确性极度依赖传感器与皮肤的接触。要教会孩子将手表戴在腕骨上方稍微紧一点但以不影响血液循环为准。运动后或刚从室外进入室内需要等待几分钟待皮肤温度稳定后再测量。理解读数意义要和孩子及家人说明手腕温度是体表温度受环境影响大通常比腋下或口腔温度低。它的主要作用是趋势监测和快速筛查。如果手表显示体温偏高如超过37.8°C应该用更准确的医用体温计进行复核。不要把它当作诊断工具。充电与维护建议固定时间充电比如每周日晚。充电时使用5V1A的普通手机充电器即可。避免长时间阳光直射或接触水尽管DS18B20是防水的但其他电路不防。可能的升级方向蓝牙传输可以增加一个HC-05或HM-10蓝牙模块将测量数据发送到手机App实现历史记录和曲线查看。触摸唤醒用触摸传感器替代震动传感器实现更精准的点击唤醒。充电指示在外壳上为TP4056的充电指示灯开一个透光孔方便查看充电状态。更优的电源管理使用带有使能端的低压差稳压器LDO在休眠时彻底切断屏幕、传感器等外围电路的电源进一步省电。这个DIY项目从构思到实现充满了探索和解决问题的乐趣。它给出的不仅仅是一个体温数字更是一份关于健康、科技和动手创造的启蒙。当孩子骄傲地向小伙伴展示“这是我爸爸/妈妈和我一起做的手表”时那种成就感远比买一个现成的产品要珍贵得多。希望这份详细的指南能帮助你顺利打造出属于你和孩子的健康小助手。