第1章:系统总体架构设计

做天窗漏水检测这个项目,说实话,我一开始也走了不少弯路。记得第一次做样机时,传感器选型没考虑周全,一下雨就误报,搞得自己很狼狈。所以这一章,我想把系统架构设计的思路掰开揉碎了讲清楚。

1.1 硬件架构:传感器 + 主控 + 执行器

硬件架构说白了就三个部分:感知、决策、执行。我习惯用「三明治」结构来理解它。

1.1.1 传感器层

传感器是系统的「眼睛」。我建议至少部署两种传感器:

  • 漏水检测传感器:比如电容式或电阻式水位传感器。我个人偏爱电容式,因为它不怕腐蚀,寿命长。我在项目中遇到过电阻式传感器用半年就氧化失效的情况,后来全换成了电容式。
  • 雨量传感器:用来判断是否下雨。可以选红外光学式,或者简单的导电式。嗯,这里要注意:导电式容易误触发,最好加个软件滤波。
我的经验:传感器安装位置很关键。漏水传感器要放在天窗排水槽的最低点,雨量传感器则要避开遮挡物。我曾经因为装偏了,导致漏水检测延迟了整整30秒。

1.1.2 主控层

主控芯片我推荐用ESP32或STM32。为什么?

  • ESP32:自带Wi-Fi和蓝牙,适合做物联网方案。功耗控制也不错,待机时能到10μA左右。
  • STM32:实时性更好,适合对响应速度要求高的场景。我有个项目要求漏水后0.5秒内关窗,用的就是STM32。

你想想看,如果只是做本地控制,STM32就够了。但如果想远程报警、手机控制,那ESP32更省事。

1.1.3 执行器层

执行器就是「动手」的部分。常见方案有:

  • 步进电机:控制精度高,适合电动天窗。我习惯用28BYJ-48,便宜又够用。
  • 舵机:适合小型天窗或翻盖式结构。注意扭矩要留余量,我吃过亏,选了个小舵机,结果天窗卡住关不上。
  • 继电器:如果天窗是原厂电机驱动,用继电器控制电源通断就行。简单粗暴,但要注意防浪涌。
组件 推荐型号 关键参数 我的评价
漏水传感器 电容式水位传感器 检测范围0-10mm 耐腐蚀,寿命长
主控芯片 ESP32-WROOM-32 双核240MHz,Wi-Fi+BLE 物联网首选
执行器 28BYJ-48步进电机 5V,扭矩0.3kg·cm 性价比高

1.2 软件架构:数据采集层 + 逻辑层 + 控制层

软件架构我习惯分三层。这样好维护,也好扩展。你想想看,如果所有代码都写在一个文件里,后期改个逻辑都得翻半天。

1.2.1 数据采集层

这一层负责跟传感器打交道。核心任务:

  • 定时读取传感器数据(我一般设100ms采样一次)
  • 做简单的滤波处理(比如中值滤波,去掉毛刺)
  • 把原始数据转换成物理值(比如电压转水位高度)
// 数据采集层示例代码
void collect_sensor_data() {
    int raw_value = analogRead(WATER_SENSOR_PIN);
    // 中值滤波,去掉异常值
    if (abs(raw_value - last_value) < 50) {
        filtered_value = raw_value;
    }
    // 转换成水位高度(mm)
    water_level = map(filtered_value, 0, 4095, 0, 10);
    last_value = raw_value;
}
避坑指南:我曾经在数据采集层忘了做去抖处理,结果传感器一有波动就触发关窗,大晴天窗户自己关上了。后来加了50ms的去抖延时,问题才解决。

1.2.2 逻辑层

逻辑层是系统的「大脑」。它负责判断:

  • 当前是否漏水(水位超过阈值且持续1秒以上)
  • 是否正在下雨(雨量传感器输出高电平)
  • 是否需要关窗(漏水 + 下雨,或者单独漏水超过3秒)

我习惯用状态机来实现。状态机的好处是逻辑清晰,不容易出bug。

// 逻辑层状态机示例
enum SystemState {
    IDLE,       // 正常状态
    LEAK_DETECTED, // 检测到漏水
    RAINING,    // 正在下雨
    CLOSING     // 正在关窗
};

SystemState current_state = IDLE;

void logic_loop() {
    switch(current_state) {
        case IDLE:
            if (water_level > THRESHOLD) {
                current_state = LEAK_DETECTED;
            }
            break;
        case LEAK_DETECTED:
            if (is_raining || leak_duration > 3000) {
                current_state = CLOSING;
            }
            break;
        // ... 其他状态处理
    }
}

1.2.3 控制层

控制层负责执行具体动作。比如:

  • 驱动步进电机正转(关窗)或反转(开窗)
  • 控制继电器通断
  • 发送报警通知到手机

这一层要特别注意安全。我建议加个限位开关,防止电机堵转烧坏。

重要提醒:控制层一定要做超时保护。我曾经遇到过电机卡住,程序一直发脉冲,结果电机烧了。后来加了5秒超时自动停止的逻辑,再没出过问题。

1.3 通信协议选择

通信协议这块,我根据实际场景推荐三种方案:

1.3.1 传感器与主控之间:I2C 或 模拟量

传感器离主控一般很近(几十厘米以内),用I2C最方便。两根线就能搞定。如果传感器是模拟输出,直接用ADC读取也行。

  • I2C:适合数字传感器,比如BME280温湿度传感器。速率100kHz就够了。
  • 模拟量:适合水位传感器、雨量传感器。注意加个上拉电阻,信号更稳定。

1.3.2 主控与执行器之间:PWM 或 步进电机驱动协议

控制电机时,我习惯用PWM控制舵机,用步进电机驱动库控制步进电机。

  • PWM:频率50Hz,占空比5%-10%控制舵机角度。
  • 步进电机驱动:用ULN2003驱动板,通过GPIO控制步进顺序。

1.3.3 主控与云端之间:MQTT 或 HTTP

如果需要远程监控,我强烈推荐MQTT。它比HTTP轻量,而且支持实时推送。

协议 适用场景 优点 缺点
MQTT 实时监控、远程控制 低带宽、双向通信 需要Broker服务器
HTTP 数据上报、日志记录 简单、通用 实时性差、开销大
我的建议:如果只是本地控制,用串口通信就够了。但如果你想做手机App远程查看,那MQTT是首选。我现在的项目都是「本地用串口,远程用MQTT」双通道设计。

好了,系统总体架构就讲到这里。下一章我会详细讲传感器选型和电路设计。记住一句话:架构设计时多花点心思,后面调试能省一半时间。