这次我们来看一个非常实用的 Arduino 创客项目:下雨自动关窗系统。这个项目的核心不是复杂的算法,而是如何用最基础的硬件和代码,解决一个生活中的实际问题——下雨天忘记关窗。对于大中小学的创客作业、青少年科创比赛或者 DIY 爱好者来说,这是一个既能学习电子知识,又能做出实用作品的绝佳选择。
项目基于 Arduino 开发板,通过一个雨滴传感器来检测是否下雨,一旦检测到雨水,就会自动控制舵机或电机来关闭窗户。整个过程完全自动化,无需人工干预。它的硬件门槛极低,成本可控,代码逻辑清晰,非常适合作为入门到进阶的实践案例。本文将带你从零开始,完成整个系统的硬件搭建、代码编写、调试到最终部署,让你亲手打造一个属于自己的“智能雨控门窗卫士”。
1. 核心能力速览
在动手之前,我们先快速了解这个项目的核心规格和所需资源,让你对整体工作量有个把握。
| 能力项 | 说明 |
|---|---|
| 核心功能 | 检测雨水并自动触发关窗动作 |
| 核心控制器 | Arduino Uno / Nano / ESP32 等主流开发板 |
| 关键传感器 | 雨滴传感器 / 雨水检测模块 |
| 执行机构 | SG90 / MG996R 舵机,或直流电机+继电器 |
| 编程环境 | Arduino IDE 或 PlatformIO |
| 代码复杂度 | 初级到中级,涉及数字信号读取与舵机控制 |
| 硬件成本 | 约 50 - 150 元人民币(视具体配件而定) |
| 供电方式 | USB 供电或外部 5V/7-12V 适配器 |
| 适合场景 | 家庭窗户、阳台、创客教育、科创作品、DIY 智能家居入门 |
| 扩展潜力 | 可增加蓝牙/Wi-Fi 远程状态查看、手动开关模式、湿度阈值调节等 |
2. 适用场景与使用边界
这个智能关窗系统最适合哪些人、哪些场景,又有哪些需要注意的边界呢?
适用人群与场景:
- 学生与教育者:非常适合作为大中小学的 STEM 教育、创客社团活动或青少年科技创新大赛的作品。它涵盖了传感器应用、自动控制和嵌入式编程等多个知识点。
- DIY 爱好者与智能家居新手:如果你想入门智能硬件,这是一个目标明确、成果可见的练手项目。完成后可以直接用于家庭环境。
- 解决实际痛点:适用于经常忘记关窗的家庭、办公室,或者需要保护室内设备(如靠窗的书桌、电器)免受雨淋的场合。
使用边界与注意事项:
- 机械结构限制:本项目的核心是电子控制和逻辑,窗户的机械改造(如安装导轨、连接舵机与窗扇)需要根据自家窗户的实际情况(推拉窗、平开窗)自行设计。确保机械部分牢固、安全,避免窗户意外跌落。
- 传感器精度:常见的雨滴传感器模块是通过板载导电图形的电阻变化来检测,可能对雾气、溅水产生误报。对于要求极高的场景,可能需要更专业的传感器或增加滤波算法。
- 供电安全:如果使用大扭矩舵机或电机,瞬间电流较大,务必确保电源(如适配器或电池)能提供足够电流,并注意接线牢固,防止发热。
- 环境适应性:雨滴传感器需要暴露在室外,需考虑其防水性和耐久性。可以为传感器制作简单的防水外壳,但不要完全密封影响检测。
- 法律责任与安全:这是一个自动化装置,务必确保其在任何情况下都不会对人员(特别是儿童)造成夹伤等风险。建议增加手动优先开关,或在系统异常时能自动断电/进入安全模式。
3. 环境准备与前置条件
开始制作前,请准备好以下软硬件环境。
硬件清单:这是完成本项目所需的最低配置,你也可以根据需求升级。
| 组件 | 型号/规格 | 数量 | 备注 |
|---|---|---|---|
| 主控板 | Arduino Uno R3 | 1 | 最通用,入门首选。也可用 Nano、ESP32等。 |
| 雨滴传感器 | 雨滴/雨水检测模块 | 1 | 通常带有模拟和数字输出。 |
| 舵机 | SG90 9g 舵机 | 1 | 用于驱动小窗户。若窗户重,需 MG996R 等大扭矩舵机。 |
| 连接线 | 杜邦线(公对公、公对母) | 若干 | 用于连接各模块。 |
| 电源 | USB 数据线 或 5V/2A 适配器 | 1 | 为整个系统供电。舵机耗电大时建议用外部电源。 |
| 面包板 | 400孔或830孔 | 1 | 方便搭建测试电路。 |
| 窗户机械结构 | 连杆、支架、胶带等 | 1套 | 需根据窗户类型DIY,将舵机旋转运动转化为关窗动作。 |
软件环境准备:
- 安装 Arduino IDE:访问 Arduino 官网下载并安装最新版 IDE。安装过程中会自动安装 USB 驱动(如 CH340)。
- 驱动检查:将 Arduino 通过 USB 线连接电脑。打开设备管理器,查看端口是否出现新的 COM 口(如 COM3, COM4)。如果显示黄色叹号,需要手动安装 CH340 或 CP2102 等 USB 转串口芯片驱动。
- IDE 配置:打开 Arduino IDE,在
工具->开发板中选择你使用的板子(如 Arduino Uno)。在工具->端口中选择对应的 COM 口。
4. 硬件连接与电路搭建
正确的硬件连接是成功的第一步。我们按照信号流来连接:传感器 -> Arduino -> 舵机。
连接示意图(文字描述):
- 雨滴传感器连接:
- 传感器
VCC引脚 -> Arduino5V引脚。 - 传感器
GND引脚 -> ArduinoGND引脚。 - 传感器
DO(数字输出)引脚 -> Arduino数字引脚 2(或其他任意数字引脚)。我们使用数字信号,简化判断逻辑。 - (可选)传感器
AO(模拟输出)引脚 -> ArduinoA0引脚。可用于检测雨量大小,本项目暂不使用。
- 传感器
- 舵机连接:
- 舵机
红色线(电源+) -> Arduino5V引脚。注意:如果舵机扭矩大,强烈建议将此外接到独立的 5V 电源上,并与 Arduino 共地,避免 Arduino 板载稳压器过载。 - 舵机
棕色线(地线-) -> ArduinoGND引脚。 - 舵机
橙色线(信号线) -> Arduino数字引脚 9(支持 PWM,用于控制角度)。
- 舵机
电路搭建步骤:
- 将 Arduino 板、面包板固定好。
- 使用杜邦线,按照上述描述,将雨滴传感器和舵机连接到 Arduino 和面包板上。
- 检查所有连接是否牢固,避免虚接。
- 最后连接 USB 线或外部电源。
安全提示:在通电前,再次确认电源正负极没有接反,特别是舵机的接线。接反可能瞬间损坏舵机或 Arduino。
5. 代码编写与上传
硬件连接好后,我们来编写控制逻辑。代码的核心是:循环读取雨滴传感器的数字信号,当检测到雨水(信号由高变低)时,控制舵机转动到“关窗”角度;当传感器变干后,可以控制舵机回到“开窗”角度。
完整示例代码:
// 定义引脚 const int rainSensorPin = 2; // 雨滴传感器数字输出接 Arduino 引脚 2 const int servoPin = 9; // 舵机信号线接 Arduino 引脚 9 // 定义舵机角度(需根据你的窗户实际安装情况调整) const int openAngle = 0; // 窗户“打开”对应的舵机角度 const int closeAngle = 90; // 窗户“关闭”对应的舵机角度 // 引入舵机库 #include <Servo.h> Servo myServo; // 创建舵机对象 // 变量声明 int sensorState = 0; // 存储传感器当前状态 int lastSensorState = HIGH; // 存储传感器上一次状态(初始为高,因为干燥时输出高电平) bool windowClosed = false; // 标记窗户当前是否已关闭 void setup() { // 初始化串口通信,用于调试 Serial.begin(9600); // 配置传感器引脚为输入模式 pinMode(rainSensorPin, INPUT_PULLUP); // 使用内部上拉电阻,确保未连接时引脚为高电平 // 将舵机连接到指定引脚 myServo.attach(servoPin); // 初始化窗户为打开状态 myServo.write(openAngle); windowClosed = false; Serial.println("系统启动,窗户初始状态:打开"); delay(1000); // 等待舵机运动到位 } void loop() { // 1. 读取雨滴传感器状态 // 注意:大多数模块,干燥时输出高电平(HIGH),检测到雨水时输出低电平(LOW) sensorState = digitalRead(rainSensorPin); // 2. 打印传感器状态到串口监视器(调试用) Serial.print("雨滴传感器状态: "); Serial.println(sensorState == LOW ? "检测到雨水!" : "天气干燥"); // 3. 判断状态是否发生变化(从干燥到下雨) if (sensorState == LOW && lastSensorState == HIGH) { // 检测到开始下雨 Serial.println(">>> 开始下雨,触发关窗动作!"); closeWindow(); } // 4. 可选:判断雨是否停了(从下雨到干燥),并自动开窗 else if (sensorState == HIGH && lastSensorState == LOW && windowClosed) { // 检测到雨停,且窗户是关着的 Serial.println(">>> 雨停了,触发开窗动作!"); openWindow(); } // 5. 更新上一次的状态 lastSensorState = sensorState; // 6. 延时一段时间再检测,避免过于频繁的检测和动作 delay(500); // 检测间隔500毫秒 } // 关窗函数 void closeWindow() { if (!windowClosed) { Serial.println("正在关闭窗户..."); myServo.write(closeAngle); // 舵机转动到关窗角度 delay(1000); // 等待舵机运动到位,时间根据舵机速度和窗户阻力调整 windowClosed = true; Serial.println("窗户已关闭。"); } } // 开窗函数 void openWindow() { if (windowClosed) { Serial.println("正在打开窗户..."); myServo.write(openAngle); // 舵机转动到开窗角度 delay(1000); // 等待舵机运动到位 windowClosed = false; Serial.println("窗户已打开。"); } }代码上传步骤:
- 打开 Arduino IDE,将以上代码复制粘贴到新窗口中。
- 再次确认
工具菜单下的开发板和端口选择正确。 - 点击
验证(对勾图标)编译代码,确保没有语法错误。 - 点击
上传(右箭头图标)将代码烧录到 Arduino 板中。 - 上传成功后,打开
工具->串口监视器,设置波特率为 9600。你应该能看到“系统启动,窗户初始状态:打开”的提示信息。
6. 功能测试与效果验证
代码上传后,我们进入关键的测试环节。测试的目的是验证整个系统能否按预期工作。
测试准备:
- 模拟雨水:准备一个小喷壶或滴管,装上清水。
- 机械联动:暂时不安装到真实窗户上。可以将舵机臂用胶带粘上一根小棍或指针,直观观察其转动。
- 串口监视器:保持打开,用于查看系统状态。
分步测试流程:
6.1 传感器基础测试
- 目的:验证雨滴传感器能否正确响应。
- 操作:向雨滴传感器的检测区域滴几滴水。
- 预期:串口监视器中打印的状态应从“天气干燥”变为“检测到雨水!”。
- 成功标准:状态变化灵敏、准确。
- 排查:如果状态不变,检查传感器接线、传感器板载电位器(可能调节了灵敏度)、代码中引脚号是否正确。
6.2 关窗动作触发测试
- 目的:验证检测到雨水后,舵机能否执行关窗动作。
- 操作:在传感器干燥状态下,向其喷水。
- 预期:串口打印“开始下雨,触发关窗动作!”和“正在关闭窗户…”,随后舵机应转动到
closeAngle定义的角度(默认为90度)。 - 成功标准:舵机准确转动到预设的“关窗”位置。
- 排查:如果舵机不转,检查舵机接线(特别是信号线)、电源是否充足。尝试在
setup函数中直接写myServo.write(90)测试舵机本身是否正常。
6.3 状态保持与防抖测试
- 目的:验证窗户不会因为传感器的微小波动而反复开合。
- 操作:持续向传感器喷水,保持其湿润状态。
- 预期:舵机只转动一次到关闭位置,之后即使传感器状态持续为“雨水”,也不会重复执行关窗动作。串口应持续打印“检测到雨水!”。
- 成功标准:系统状态稳定,无多余动作。
- 排查:这由代码中的
windowClosed状态变量和逻辑判断保证。如果反复触发,检查逻辑判断条件。
6.4 雨停开窗测试(可选功能)
- 目的:验证雨停后自动开窗功能。
- 操作:停止喷水,并用纸巾轻轻吸干传感器检测区域。
- 预期:串口打印“雨停了,触发开窗动作!”和“正在打开窗户…”,舵机应转回
openAngle定义的角度(默认为0度)。 - 成功标准:系统能正确检测到“雨停”事件并恢复开窗状态。
- 注意:自动开窗功能是否启用,取决于你的实际需求。如果希望一直保持关窗直到手动打开,可以注释掉代码中相关的
else if判断。
7. 机械安装与系统集成
电子部分测试成功后,最挑战的部分来了——将电子装置与真实的窗户结合。
设计原则:
- 力量传递:舵机的旋转运动需要通过连杆、摇臂等机构转化为窗户的直线推拉或旋转。可以使用3D打印件、激光切割亚克力板,或者用现成的材料(如角铁、连杆套件)制作。
- 牢固固定:舵机和支架必须牢固地固定在窗框或墙壁上,防止动作时脱落。
- 避免卡死:确保机械运动路径顺畅,没有死点。舵机在到达极限位置时如果被堵转,电流会急剧增大导致损坏。可以在代码中避免让舵机转到物理极限角度,留有余量。
- 手动优先:务必确保在自动系统失灵或需要紧急开关窗时,可以轻松地手动操作窗户。不要设计成纯自动锁死结构。
安装步骤建议:
- 确定关窗逻辑:测量你的窗户从全开到全关需要的行程距离或旋转角度。
- 制作连接机构:设计一个将舵机臂与窗户把手或窗扇连接的机构。例如,对于推拉窗,可以用一根杆子,一头连接舵机臂,另一头连接窗扇。
- 固定舵机:将舵机用螺丝或强力胶(如热熔胶、AB胶)固定在窗框附近稳固的位置。
- 连接与调试:将连接机构安装好,但先不要完全锁死。上传一个简单的舵机摆动测试程序,手动调整连接点和舵机初始角度,确保窗户能平滑地从“全开”移动到“全关”。
- 调整代码角度:根据上一步调试出的实际有效角度,修改代码中的
openAngle和closeAngle值。 - 整体测试:安装好雨滴传感器(注意其位置应能有效收集雨水,又不会被轻易误触发),进行最终的通电淋水测试。
8. 优化与扩展功能
基础功能实现后,你可以考虑以下优化和扩展,让项目更完善、更智能。
8.1 增加灵敏度调节与状态指示灯
- 硬件:增加一个电位器连接到模拟引脚 A1,用于调节触发雨量阈值。增加一个 LED 灯(如接引脚 13)作为状态指示(常亮=开窗,闪烁=关窗中,熄灭=异常)。
- 代码:在
loop中读取电位器值,映射为判断雨水信号的阈值。根据windowClosed状态控制 LED。
8.2 增加手动/自动切换开关
- 硬件:增加一个拨动开关或按钮,接数字引脚并启用上拉电阻。
- 代码:读取开关状态。当处于“手动”模式时,屏蔽雨滴传感器的触发,可以通过另一个按钮控制开关窗。这增加了系统的安全性和可控性。
8.3 升级为物联网版本(使用 ESP32)
- 硬件:将主控更换为 ESP32(如 ESP32 DevKitC),它内置 Wi-Fi 和蓝牙。
- 功能:
- 远程状态监控:通过 Wi-Fi 连接家庭路由器,将窗户状态(开/关)、传感器数据上传到物联网平台(如 Blynk、ThingsBoard)或自建服务器,在手机 App 上查看。
- 远程控制:即使不在家,也可以通过手机 App 手动触发关窗或开窗。
- 天气预报联动:通过网络 API 获取实时天气预报,在降雨概率高时提前关窗,而不仅仅是响应实际雨水。
8.4 增加多种传感器融合判断
- 硬件:增加温湿度传感器(如 DHT11)、风速传感器。
- 逻辑:实现更复杂的判断逻辑。例如,只有同时满足“检测到雨水”和“风速低于某值”时才关窗,防止大风大雨天气强行关窗导致机械损坏。
9. 常见问题与排查方法
在制作过程中,你可能会遇到以下问题,这里提供排查思路。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| Arduino IDE 无法上传程序 | 1. 端口选择错误 2. 驱动未安装 3. 开发板类型选错 | 1. 检查设备管理器中的 COM 口 2. 检查开发板类型是否与实物一致 3. 尝试按一下板子上的复位键再上传 | 1. 安装正确的 CH340/CP2102 驱动 2. 在 工具->端口和开发板中正确选择 |
| 串口监视器无输出或乱码 | 1. 波特率设置错误 2. 代码中 Serial.begin()波特率不匹配3. 串口被其他软件占用 | 1. 检查 IDE 波特率是否与代码中一致(如9600) 2. 关闭可能占用串口的其他软件 | 1. 统一波特率为 9600 或 115200 2. 重启 Arduino IDE |
| 雨滴传感器始终显示“干燥” | 1. 接线错误(VCC/GND) 2. 传感器灵敏度电位器未调节 3. 传感器损坏 | 1. 用万用表测量传感器供电电压 2. 调节板载蓝色电位器 3. 将 DO 引脚直接短接到 GND,看状态是否变化 | 1. 重新检查接线 2. 顺时针/逆时针调节电位器,用螺丝刀滴水上板测试 3. 更换传感器 |
| 舵机不转动或抖动 | 1. 电源功率不足 2. 信号线接触不良 3. 机械负载过重卡死 | 1. 观察 Arduino 板载电源指示灯是否变暗 2. 单独测试舵机(用示例代码 Sweep)3. 断开机械负载测试 | 1. 为舵机提供独立的外部 5V/2A 以上电源 2. 检查并固定信号线连接 3. 减轻机械负载或更换更大扭矩舵机 |
| 窗户关不严或关过头 | 1. 舵机角度 (closeAngle) 设置不准确2. 机械连接存在虚位或弹性变形 | 1. 在机械安装完成后,通过串口发送指令单独测试舵机角度 2. 观察机械传动是否牢固 | 1. 精细调整代码中的角度值,找到刚好关严的位置 2. 加固机械连接件 |
| 系统误触发(无雨关窗) | 1. 传感器灵敏度太高 2. 传感器表面有灰尘、冷凝水 3. 电气干扰 | 1. 清洁传感器表面 2. 逆时针调节灵敏度电位器 3. 在代码中增加“延时确认”逻辑 | 1. 调整灵敏度 2. 修改代码:连续检测到多次雨水信号后再触发动作(软件防抖) |
10. 最佳实践与项目总结
最佳实践建议:
- 分阶段测试:永远遵循“先软件,后硬件;先模块,后集成”的原则。先在桌面上测试所有电子模块功能正常,再安装到窗户上。
- 电源隔离:驱动电机/舵机的电源最好与逻辑控制部分(Arduino)的电源隔离或使用独立电源模块,避免干扰导致单片机复位。
- 做好防水:为室外部分的传感器制作一个小的防水罩(如用塑料瓶裁剪),确保电路板不被淋湿,同时让感应面朝下暴露。
- 保留调试接口:在最终版本中,也保留串口打印功能,并将调试信息输出级别调低。这样在出现问题时,可以快速定位。
- 安全第一:确保自动关窗不会夹伤人或宠物。可以在窗边安装红外或超声波避障传感器,在检测到障碍物时停止关窗动作。
项目总结:这个 Arduino 下雨自动关窗项目,成功地将一个简单的物理传感器(雨滴传感器)和一个执行器(舵机),通过一块开源硬件(Arduino)和几十行代码,组合成了一个解决实际生活问题的智能装置。它的价值不仅在于最终的成果,更在于完整的实践过程:从需求分析、硬件选型、电路搭建、编程逻辑、机械设计到系统调试。
对于初学者,你掌握了数字信号读取、舵机控制、状态机编程等核心技能。对于进阶者,你可以在此基础上扩展出网络功能、多传感器融合、更复杂的决策逻辑。这个项目就像一个“乐高底座”,为你打开了智能家居和物联网世界的大门。建议你将所有代码、电路图、机械设计图妥善保存,并记录下遇到的问题和解决方案,这本身就是一份宝贵的创客学习笔记。现在,你可以自信地将它展示给你的同学、老师,或者真正地安装在家里的窗户上了。