1. 项目概述:当水龙头有了“感知”与“思考”

你有没有想过,家里最不起眼的水龙头,也能变得聪明起来?我说的不是那种简单的感应出水,而是能根据水温、环境甚至你的习惯,主动调节水流和灯光,带来更舒适、更节能体验的智能水龙头。这次,我就要分享一个基于Sensirion SHT45温湿度传感器打造的“智能温感光控水龙头”项目。这不仅仅是一个简单的DIY,更像是一次对传统家居用品的“智慧化”改造实践。

Sensirion的SHT系列传感器在业界口碑一直很好,尤其是其最新的SHT45,以其高精度、低功耗和出色的长期稳定性著称。这个项目的核心思路,就是利用SHT45精准测量水温(通过接触或近场测量)和环境温湿度,再结合一个微控制器(比如常见的ESP32或Arduino)和LED灯带,实现水温可视化(用灯光颜色表示水温高低)以及基于环境条件的智能节水逻辑。它适合对智能家居、嵌入式开发感兴趣的朋友,无论你是想学习传感器应用、PWM调光控制,还是想打造一个真正实用的智能小装置,这个项目都能给你带来从硬件选型、电路设计到软件逻辑的全流程实战经验。接下来,我就带你一步步拆解这个“会思考”的水龙头是如何诞生的。

2. 核心器件选型与设计思路解析

2.1 为什么是Sensirion SHT45?

在众多温湿度传感器中,选择SHT45是经过深思熟虑的。首先,对于水龙头应用, 测量精度和响应速度 至关重要。SHT45在0-65°C范围内的典型温度精度可达±0.1°C,湿度精度±1.5%RH,这个精度足以区分细微的水温变化,让你清楚知道流出来的是舒适的温水还是可能烫手的开水。其次,它的 功耗极低 ,平均测量电流仅1.7μA,这对于可能采用电池供电或希望长期待机的水龙头设计来说是个巨大优势。最后,Sensirion传感器特有的 抗冷凝设计和出色的长期稳定性 ,能很好地应对浴室、厨房等高温高湿的恶劣环境,确保数据可靠,不会用一段时间就漂移得厉害。

当然,市面上也有像DHT22、AM2320这类更便宜的选项。但DHT22精度较低(温度±0.5°C),响应慢,且单总线协议在复杂电磁环境下可能不稳定。AM2320是I2C接口,精度尚可,但其长期稳定性和在液态水环境附近的可靠性未经广泛验证。对于直接关乎使用体验和安全的水温提示功能,我愿意为SHT45的“靠谱”多付一点成本。它的I2C数字接口也简化了与主控的连接,只需要两根数据线加电源和地,布线非常清爽。

2.2 系统架构与功能定义

整个系统的架构可以看作一个典型的感知-决策-执行闭环。 感知层 的核心是SHT45,负责采集水温(通过一个导热良好的金属外壳包裹传感器探头,并紧密贴合在水龙头出水口内部或外部管壁)以及环境温湿度。 决策层 是一块微控制器,我选择了ESP32-C3,因为它兼具Arduino的易用性和Wi-Fi/蓝牙能力,为未来联网升级留有余地,且价格亲民。 执行层 则包括两部分:一是用于水流控制的电磁阀(可选,实现自动节水),二是WS2812B可寻址RGB LED灯带,用于灯光提示。

我们定义的核心功能有三个:

  1. 水温灯光可视化 :这是最直观的功能。通过编程,让LED灯带根据实测水温显示不同颜色。例如,低于20°C显示蓝色(冷),20-35°C显示绿色(舒适),35-45°C显示黄色(温热),高于45°C显示红色(烫)。颜色区间和阈值完全可以自定义。
  2. 环境自适应节水 :利用SHT45测量的环境温湿度,可以智能判断是否需要预放冷水。例如,在寒冷冬季,水管中的存水温度很低,系统可以提示“正在预热”或通过灯光闪烁表示水温未达舒适区间,避免用户长时间放水等待。
  3. 用水数据记录(进阶) :结合ESP32的联网能力,可以将每次用水的水温、时长、环境条件匿名上传到私有服务器,用于分析家庭用水习惯,甚至估算热水能耗。

这个设计思路的优势在于模块化。你可以先实现基础的灯光提示功能,再逐步添加电磁阀控制和联网模块,循序渐进地完善你的智能水龙头。

3. 硬件连接与电路设计要点

3.1 SHT45与微控制器的连接

SHT45采用标准的I2C接口,连接非常简单。你需要准备四根导线:

  • VDD :连接3.3V电源。 特别注意 :SHT45的工作电压范围是1.08V至3.6V,绝对不可以接到5V上,否则会永久损坏传感器。ESP32-C3的3.3V输出引脚是完美的选择。
  • GND :连接电源地。
  • SCL :串行时钟线,连接ESP32-C3的任意一个I2C时钟引脚,例如GPIO6。
  • SDA :串行数据线,连接ESP32-C3的任意一个I2C数据引脚,例如GPIO5。

为了信号的稳定性,建议在SDA和SCL线上各连接一个 4.7kΩ的上拉电阻到3.3V 。虽然ESP32内部有可配置的上拉电阻,但外置物理电阻通常更可靠,尤其是在导线较长或有干扰的环境中。传感器本身很小,你可以将其焊接在一个小的 breakout 板上,或者直接用杜邦线连接,但要做好防水绝缘处理。

3.2 水温测量的物理安装方案

这是本项目的一个 关键难点 。SHT45本身不是潜水式传感器,不能直接接触流动的水。我们需要采用间接测量法。我试验了两种方案:

  • 方案A:接触式导热 。找一个小的铜质或铝质散热片,将SHT45的感温部分用导热硅脂紧密贴合在散热片上,然后将整个散热片用金属卡箍或高导热胶带紧密固定在水龙头的金属出水嘴上。这样,水流温度会通过金属传导到传感器。优点是响应相对较快,缺点是与“活水”仍有隔阂,且安装需要一定技巧,要确保接触良好。
  • 方案B:近场空气测量 。将SHT45放置在非常靠近出水口的位置(例如,在水龙头下方设计一个容纳传感器的腔体,有小孔正对水流)。流动的水会迅速影响其周围微小空气层的温湿度,传感器通过测量这层空气来近似水温。优点是安装简单、完全非接触,安全;缺点是响应有延迟,且容易受环境气流干扰。

我最终选择了 方案A ,并进行了改良:使用一个薄壁黄铜管套在水龙头出口螺纹上,SHT45用导热环氧树脂固化在铜管外壁。实测下来,对于缓慢温度变化,跟踪效果很好;对于急速冷热水切换,约有2-3秒的延迟,这在可接受范围内。

3.3 供电与执行单元设计

整个系统供电,如果水龙头附近有USB电源(比如智能马桶旁边),最简单的是用一个5V/1A的USB适配器给ESP32-C3供电。ESP32-C3的Vin引脚可以接受5V输入,其板载LDO会降压到3.3V供自身和SHT45使用。

对于 LED灯带 ,WS2812B使用5V供电,每个LED在全白光亮时约消耗60mA电流。如果灯带较长(比如超过10个灯珠),就不能直接从ESP32板载的5V引脚取电了,必须为灯带单独提供一路5V电源,并与ESP32共地。数据线连接ESP32的某个GPIO口(如GPIO8)。

电磁阀 (如果需要)通常需要12V或24V驱动,电流较大(几百mA)。绝对不能直接用单片机GPIO口驱动!必须使用 继电器模块 MOSFET管 配合驱动电路。例如,用一个5V驱动的继电器模块,其控制端接ESP32的GPIO,被控端接电磁阀和其专属电源。这是一个强电弱电隔离的典型设计,务必注意安全,接线规范,防止漏电。

4. 核心软件逻辑与代码实现

4.1 开发环境与库配置

我使用PlatformIO插件配合VSCode进行开发,它比Arduino IDE更专业,库管理更方便。你也可以使用Arduino IDE。首先,需要安装两个核心库:

  1. Sensirion的I2C驱动库 。在PlatformIO的库管理中搜索“Sensirion SHT4x”,安装由Sensirion官方维护的 arduino-i2c-sht4x 库。这个库封装了所有底层通信和CRC校验,使用起来非常简洁。
  2. FastLED库 :用于高效驱动WS2812B灯带。搜索并安装“FastLED”。

项目配置 platformio.ini 文件示例如下:

[env:esp32-c3-devkitm-1]
platform = espressif32
board = esp32-c3-devkitm-1
framework = arduino
monitor_speed = 115200
lib_deps =
    sensirion-i2c-sht4x
    fastled/FastLED@^3.6.0

4.2 数据读取与温度映射逻辑

主程序的核心是定期读取SHT45的数据,并将其映射为灯光颜色。下面是一个精简的核心代码逻辑:

#include <Arduino.h>
#include <Wire.h>
#include <sht4x.h>
#include <FastLED.h>

#define NUM_LEDS 8
#define DATA_PIN 8
CRGB leds[NUM_LEDS];

SHT4x sht4;

// 温度颜色映射阈值
#define TEMP_COLD 20.0
#define TEMP_COMFORT_LOW 20.0
#define TEMP_COMFORT_HIGH 35.0
#define TEMP_WARM 45.0

void setup() {
  Serial.begin(115200);
  Wire.begin(); // 初始化I2C
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(50); // 设置亮度,避免刺眼

  if (sht4.begin(&Wire) != 0) {
    Serial.println("SHT45初始化失败!");
    while(1);
  }
  sht4.setPrecision(SHT4X_HIGH_PRECISION); // 设置高精度模式
  sht4.setHeater(SHT4X_NO_HEATER);
}

void loop() {
  float temperature, humidity;
  int err = sht4.measureHighPrecision(temperature, humidity);
  
  if (err == 0) {
    Serial.printf("温度: %.2f °C, 湿度: %.2f %%RH\n", temperature, humidity);
    updateLEDsBasedOnTemp(temperature);
  } else {
    Serial.printf("测量错误: %d\n", err);
    // 错误处理,例如让LED闪烁红色
  }
  
  delay(1000); // 每秒更新一次
}

void updateLEDsBasedOnTemp(float temp) {
  CRGB color;
  if (temp < TEMP_COLD) {
    color = CRGB::Blue; // 冷
  } else if (temp >= TEMP_COMFORT_LOW && temp <= TEMP_COMFORT_HIGH) {
    color = CRGB::Green; // 舒适
  } else if (temp > TEMP_COMFORT_HIGH && temp < TEMP_WARM) {
    color = CRGB::Yellow; // 温热
  } else {
    color = CRGB::Red; // 烫
  }
  
  fill_solid(leds, NUM_LEDS, color);
  FastLED.show();
}

这段代码实现了最基本的温度-颜色映射。 SHT4X_HIGH_PRECISION 模式提供了最精确的测量,但耗时稍长(约8.5ms)。对于水龙头应用,这个速度完全足够。

4.3 进阶功能:平滑滤波与状态机

在实际使用中,直接使用原始温度值可能会导致灯光颜色在阈值边缘频繁跳变,体验不好。我们需要加入 软件滤波 。一个简单有效的一阶低通滤波(指数加权平均)可以平滑数据:

float filteredTemp = 0.0;
const float alpha = 0.2; // 平滑系数,0<alpha<1,越小越平滑

void loop() {
  // ... 读取温度 rawTemp ...
  filteredTemp = alpha * rawTemp + (1 - alpha) * filteredTemp;
  updateLEDsBasedOnTemp(filteredTemp);
}

此外,可以引入一个简单的 状态机 来处理“预放水”逻辑。例如,当检测到用户打开水龙头(可通过一个额外的触摸传感器或水流传感器判断)且当前水温低于舒适温度时,系统可以进入“预热”状态,让LED灯带呈现呼吸效果的蓝色,提示用户稍等。当水温进入舒适区间后,再切换到常亮绿色。

5. 外壳制作、防水与安装实战

5.1 3D打印外壳设计

为了让项目看起来更成品化,我使用Fusion 360设计了一个两件式的外壳。 下壳 主要容纳ESP32开发板、电源模块和接线端子,侧面留有USB供电口和I2C扩展口。 上壳 则是一个透明的亚克力盖板(也可以打印,但透明度差),用于展示LED灯带。外壳需要为水龙头管径设计一个合适的 卡箍结构 ,我采用了带有橡胶内衬的“喉箍”式设计,通过螺丝收紧,能适应不同直径的龙头。

设计要点:

  • 散热 :在主板区域和靠近SHT45铜质导热块的位置,设计通风孔。
  • 防水 :这是重中之重。所有接缝处设计了凹槽,用于嵌入 硅胶密封圈 。螺丝孔采用沉头设计,并在内部点胶防水。
  • 线缆出口 :为电源线和可能的电磁阀线设计带橡胶护套的出口孔,防止线材被割伤。

5.2 防水处理细节

电子设备近水安装,防水必须万无一失。

  1. 电路板防护 :给整个ESP32开发板(除了必要接口)喷涂三遍 电路板专用三防漆 。这能有效防潮、防腐蚀。注意USB口和GPIO排针不要喷到,可以用胶带提前遮盖。
  2. 传感器防水 :SHT45本身有一定抗冷凝能力,但为了保险,我在其焊接点和 breakout 板上涂抹了一层 中性硅酮密封胶 (如704胶),形成一层保护膜。注意不要涂到传感器的感应窗上。
  3. 接缝密封 :组装外壳时,在密封圈和所有接缝处均匀涂抹一层薄薄的 硅脂 ,能极大增强防水效果。
  4. 线缆处理 :线缆出入口使用 防水电缆接头(PG头) ,或者用热缩管和防水胶带多层缠绕密封。

5.3 现场安装与调试

安装时,首先确保水龙头表面清洁干燥。将带有SHT45的导热铜管用高温导热胶固定在水龙头最佳测温点(通常是最靠近混合阀的出水嘴根部)。然后,将主外壳卡箍套上,初步拧紧。连接好所有线缆(电源、LED灯带)后,通电测试。通过手机连接到ESP32的Wi-Fi热点(如果编写了配网功能)或串口监视器,观察温度读数是否合理。可以用手触摸龙头不同部位,看温度变化和灯光反馈是否灵敏、符合预期。最后,彻底拧紧卡箍螺丝,并检查所有防水环节。

6. 常见问题排查与优化心得

6.1 典型问题与解决方案

在实际制作和调试中,我遇到了以下几个典型问题:

问题现象 可能原因 排查与解决方案
SHT45读数全为0或-40 I2C通信失败 1. 检查VCC是否为3.3V。
2. 检查SDA/SCL线是否接反、虚焊。
3. 用逻辑分析仪或示波器抓取I2C波形,看是否有应答。
4. 确认I2C地址(SHT45默认0x44)。
温度变化响应极慢 传感器物理安装不良 1. 检查导热硅脂是否涂匀,接触面是否紧密无空气间隙。
2. 尝试改用导热系数更高的材料(如铜替换铝)。
3. 确认传感器感应窗没有被胶水或污物覆盖。
LED灯带部分不亮或颜色错乱 信号干扰或供电不足 1. 首要检查电源 :确保LED灯带单独使用足够粗的5V导线供电,并在首端并联一个1000μF的电解电容滤波。
2. 数据线过长:数据线尽量短(<0.5米),或在靠近LED输入端的数据线上加一个 330-470Ω的串联电阻
3. 共地问题:确保LED电源地与ESP32的GND可靠连接。
系统运行一段时间后死机 电源不稳定或程序跑飞 1. 测量5V输入电压在ESP32高负载(如Wi-Fi传输)时是否跌落严重。
2. 在程序中加入看门狗(Watchdog)定时器复位功能。
3. 检查是否有内存泄漏(频繁动态内存分配)。
灯光颜色在阈值附近闪烁 温度测量噪声或水流本身波动 1. 如前所述, 启用软件低通滤波
2. 可以设置一个“迟滞区间”,例如,从蓝变绿需要温度>22°C,从绿变回蓝则需要温度<18°C,避免临界点抖动。

6.2 性能优化与扩展思考

  1. 功耗优化 :如果考虑电池供电,需要大幅优化。将ESP32设置为深度睡眠模式,每10秒由定时器唤醒一次,测量温度并快速更新LED(LED本身也很耗电,可改为只有检测到水流或触摸时才亮起),然后立即再次休眠。SHT45也支持单次测量后自动进入休眠。这样,整体平均电流可以控制在几十微安级别。
  2. 用户体验优化 :可以增加一个电容式触摸传感器,实现“挥手切换模式”。例如,触摸一下切换温度显示模式(摄氏/华氏),长触摸进入亮度调节模式。灯光效果也可以更丰富,比如用流水灯效果表示当前水温在舒适区间内的相对位置。
  3. 联网与智能联动 :这是ESP32的强项。通过Wi-Fi接入家庭物联网平台(如Home Assistant、MQTT服务器),可以实现更多功能:远程查看水温、设置温度告警(当水温过高时手机推送通知)、与家庭其他设备联动(如打开水龙头时自动开灯)。代码上需要引入Wi-Fi管理和MQTT客户端库,并处理好网络断线重连。
  4. 校准 :虽然SHT45出厂精度很高,但如果追求极致,可以用一个经过校准的高精度温度计作为参考,在代码中加入一个偏移量 calibrationOffset 进行软件校准: finalTemp = measuredTemp + calibrationOffset

这个项目从构思到实现,最深的体会是: 硬件项目的可靠性,一半在于电路和代码,另一半在于机械结构和环境防护 。尤其是和水打交道,任何一点防水上的疏忽都可能导致前功尽弃。另外,在传感器选型上,不要一味追求便宜,在关键参数上选择像Sensirion这样经过市场长期验证的产品,能省去后期大量的调试和维护烦恼。最后,灯光效果和交互逻辑需要反复站在用户角度去测试和调整,找到一个既直观又不打扰的平衡点,这才是智能设备应有的温度。

Logo

立足具身智能前沿赛道,致力于搭建全球化、开源化、全栈式技术交流与实践共创平台。

更多推荐