从零打造一个会“看天色”的智能窗帘:基于ESP32的实战项目全解析
你有没有过这样的经历?大清早阳光刺眼,却被窗帘挡得严严实实,起床第一件事就是手动拉开;或者傍晚回家,屋里已经黑成一片,还得摸黑去开灯、拉窗帘。更别提夏天烈日当空时,明明没人在家,窗帘却敞开着,室内温度飙升——这不仅是舒适性问题,更是实实在在的能源浪费。
如果窗帘能像人一样“感知光线”,在合适的时间自动开合呢?
今天,我们就来动手实现这样一个会“看天色”的智能窗帘系统。整个项目以ESP32为核心控制器,搭配步进电机与光照传感器 BH1750,通过 Wi-Fi 接入手机 App 实现远程控制和自动化运行。成本不到百元,代码开源可复用,特别适合嵌入式初学者练手或家庭 DIY 升级。
为什么选 ESP32?它不只是个 Wi-Fi 模块
说到物联网主控芯片,很多人第一反应是 ESP8266。但在这个项目里,我们选择功能更强的ESP32——它不只是多了一个蓝牙模块那么简单。
ESP32 是乐鑫推出的双核处理器(Tensilica LX6),主频高达 240MHz,拥有 34 个 GPIO 引脚,支持 PWM、I²C、SPI、ADC 等丰富外设接口。最关键的是,它能在运行电机控制逻辑的同时,稳定维持 Wi-Fi 连接并处理网络请求,这对实时性要求较高的智能家居设备至关重要。
更重要的是,它的低功耗表现非常出色:进入深度睡眠模式后电流仅5μA,意味着未来完全可以做成电池供电版本,比如安装在没有电源插座的飘窗上。
开发方面也极其友好,支持 Arduino IDE、ESP-IDF 和 MicroPython,社区资源丰富。哪怕你是第一次接触嵌入式开发,也能快速上手。
下面这段代码展示了 ESP32 如何连接家庭 Wi-Fi,为后续与云端通信打下基础:
#include <WiFi.h> const char* ssid = "Your_WiFi_SSID"; const char* password = "Your_WiFi_Password"; void setup() { Serial.begin(115200); pinMode(LED_BUILTIN, OUTPUT); WiFi.begin(ssid, password); Serial.print("Connecting to WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nConnected!"); Serial.print("IP Address: "); Serial.println(WiFi.localIP()); } void loop() { // 后续可在此处添加 MQTT 订阅或 HTTP 服务 delay(1000); }✅ 提示:实际部署中建议使用MQTT 协议进行轻量级通信,比轮询 HTTP 更省电、响应更快。
电机怎么选?步进电机让位置控制变得简单
窗帘需要的是精确的位置控制:不能只“转”或“停”,而要能知道当前是“全开”、“半开”还是“关闭”。这就排除了普通的直流电机(除非加编码器和限位开关)。
我们选用的是常见的28BYJ-48 减速步进电机 + ULN2003 驱动板组合。这套方案成本极低(合计不到20元),且无需额外反馈装置即可实现开环定位。
它是怎么工作的?
步进电机的本质是“走一步,动一度”。每接收一个脉冲信号,转子就转动一个固定角度——这个角度叫“步距角”。
28BYJ-48 的原始步距角是 5.625°,内部减速比为 1:64,最终输出轴每步旋转约0.0879°。也就是说,转一圈需要:
360° / 0.0879° ≈ 4096 步但由于常用驱动库默认按 2048 步计算(半步模式),我们在代码中通常设置为stepsPerRevolution = 2048。
ULN2003 则是一个达林顿阵列芯片,负责把 ESP32 输出的微弱 GPIO 信号放大成足以驱动电机线圈的电流。
下面是控制电机正反转的核心代码:
#include <Stepper.h> const int stepsPerRevolution = 2048; Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11); // IN1~IN4 对应 D8/D10/D9/D11 void setup() { myStepper.setSpeed(10); // 转速:10 RPM } void loop() { // 关闭窗帘(顺时针) myStepper.step(stepsPerRevolution); delay(2000); // 打开窗帘(逆时针) myStepper.step(-stepsPerRevolution); delay(2000); }⚠️ 注意:长时间堵转会导致电机发热甚至损坏。务必加入软件限位或超时保护机制。
光线说了算:用 BH1750 实现真正的“自适应”
光敏电阻便宜好用,但精度差、一致性不好,容易受温漂影响。想要长期稳定运行,必须上数字传感器。
我们选择了BH1750 数字光照传感器,它采用 I²C 接口,直接输出 Lux 值,测量范围从 1 到 65536 Lux,分辨率可达 1 Lux,在高精度模式下响应时间仅 180ms。
它的感光曲线接近人眼视觉响应,这意味着它的读数更符合我们对“亮”或“暗”的主观感受,非常适合用于自动窗帘、屏幕调光等场景。
接线也非常简单:
- VCC → 5V 或 3.3V
- GND → GND
- SCL → ESP32 的 SCL 引脚(如 GPIO22)
- SDA → ESP32 的 SDA 引脚(如 GPIO21)
代码实现如下:
#include <Wire.h> #include <BH1750.h> BH1750 lightMeter; void setup() { Wire.begin(); lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE); Serial.begin(115200); } void loop() { float lux = lightMeter.readLightLevel(); Serial.printf("Light: %.2f lx\n", lux); if (lux < 100) { closeCurtain(); // 天黑了,关窗帘 } else if (lux > 300) { openCurtain(); // 天亮了,开窗帘 } delay(1000); }你可以根据自家窗户朝向调整阈值。例如北向房间可能永远达不到 300 Lux,那就设成 150 Lux 触发开启。
整体架构:软硬协同,构建闭环控制系统
整个系统的结构其实很清晰:
[ BH1750 ] ---(I²C)--→ [ ESP32 ] │ (Wi-Fi) ↓ ┌─────┴─────┐ │ 路由器 │ └─────┬─────┘ ↓ [ 手机App / 云平台 ] ↑ (GPIO 控制) ↓ [ ULN2003 驱动板 ] ↓ [ 28BYJ-48 步进电机 ] ↓ [ 窗帘传动机构 ]ESP32 扮演“大脑”角色:
- 定期采集光照数据;
- 判断是否满足自动化条件;
- 接收来自 App 的远程指令;
- 驱动电机执行动作;
- 回传当前状态(如“已打开”、“正在关闭”)。
所有模块建议统一使用5V/2A 开关电源供电。尤其注意:电机启动瞬间电流较大,若与 ESP32 共用线性稳压源,可能导致 MCU 复位。最好将电机电源与逻辑电源隔离,并在 VCC-GND 间并联一个100μF 电解电容滤波。
不只是遥控:这些设计细节决定了成败
很多教程做到“手机能控制”就结束了,但我们追求的是真正可用的产品级体验。以下几点是你必须考虑的工程细节:
✅ 本地化策略:断网也能工作
依赖云平台的风险在于——一旦断网,系统瘫痪。解决方案是在 ESP32 中固化一套本地逻辑,例如:
- 每天早上 7:00 自动开启;
- 当光照低于 100 Lux 持续 5 分钟,则关闭窗帘;
- 支持手动暂停自动化。
这样即使路由器重启,也不影响基本功能。
✅ 位置记忆:支持“半开”模式
记录电机累计步数,就能实现多档位控制。比如:
- 全开:+2048 步
- 半开:+1024 步
- 关闭:0 步
下次启动时可根据上次状态决定初始方向,避免每次都跑全程。
✅ OTA 升级:免拆机更新固件
启用 ESP32 的 OTA 功能,未来修复 bug 或增加新特性时,只需在 App 里点一下“升级”,无需再拆壳插 USB。
✅ 安全防护:防止电机堵转
加入超时检测机制。例如“关闭窗帘”操作最长允许运行 15 秒,超时则强制停止并报警,避免因机械卡死烧毁电机。
从“能用”到“好用”:那些值得拓展的方向
完成基础功能后,还有很多玩法可以尝试:
| 升级方向 | 实现方式 |
|---|---|
| 语音控制 | 接入 Alexa / Google Assistant / 小爱同学 |
| 多传感器联动 | 加入温湿度传感器,高温+强光时自动关闭遮阳 |
| 本地交互 | 增加 OLED 屏幕 + 按键,支持现场查看状态 |
| 行为预测 | 记录用户操作习惯,AI 预测最佳开关时机 |
| 能耗统计 | 结合光照数据估算每日节省的空调负荷 |
甚至可以接入 Home Assistant,与其他设备联动:
- “晚上 9 点 + 光照 < 50 Lux” → 关闭窗帘 + 打开卧室灯;
- “离家模式启动” → 所有窗帘关闭,增强安全性。
写在最后:小设备,大智慧
这个项目看似只是一个“自动拉窗帘”的小玩意,但它涵盖了现代 IoT 设备的核心要素:
- 传感(BH1750)
- 控制(ESP32)
- 执行(步进电机)
- 通信(Wi-Fi/MQTT)
- 用户交互(App)
更重要的是,它体现了智能化的本质:不是让人学会操作机器,而是让机器理解人的需求。
当你清晨醒来,窗帘缓缓拉开,阳光温柔洒进房间;傍晚归家,屋内灯光渐亮,窗帘悄然合拢——那一刻你会明白,科技真正的价值,不在于炫技,而在于无声的体贴。
如果你也在尝试类似的项目,欢迎在评论区分享你的设计思路或遇到的坑。一起把生活变得更聪明一点。