1. 项目概述
这个基于Arduino的智能家居环境监测系统,是我去年为一个朋友的新家设计的实际项目。当时他刚装修完房子,想要一套能自动调节室内环境的智能系统,但又不想花大价钱购买商业解决方案。经过两周的开发和调试,最终完成了这套成本不到300元,但功能相当完善的DIY系统。
核心功能是通过各类传感器实时监测室内环境参数(光照、温湿度等),然后自动控制窗帘、灯光等设备。比如当室内光线太强时自动拉上窗帘,温度过高时开启风扇,检测到异常情况(如火焰)时触发报警。整个系统以Arduino Nano为主控,配合常见的传感器模块,非常适合想要入门智能家居开发的爱好者。
2. 系统架构设计
2.1 硬件选型与配置
选择Arduino Nano作为主控有几个重要考虑:
- 体积小巧(18×45mm),适合嵌入家居环境
- 价格便宜(正版约50元,兼容版20元左右)
- 具有足够的I/O接口(14个数字I/O,8个模拟输入)
- 低功耗(工作电流约20mA)
传感器配置方案:
- 光照传感器:BH1750(I2C接口,量程1-65535lux)
- 温湿度传感器:DHT11(单总线接口,温度0-50℃±2℃,湿度20-90%RH±5%)
- 火焰传感器:红外接收管+比较器电路(检测波长760nm-1100nm)
- 雨滴传感器:基于PCB板的电阻式检测
执行设备选型:
- 窗帘控制:SG90微型舵机(扭矩1.6kg·cm)
- 灯光调节:5mm LED+MOS管驱动电路
- 报警装置:有源蜂鸣器(工作电压3-5V)
2.2 系统工作原理
系统运行流程分为三个主要阶段:
- 数据采集:各传感器周期性(默认1秒)采集环境参数
- 数据处理:Arduino对原始数据进行滤波和校准
- 设备控制:根据预设规则驱动执行机构
特别要注意的是各传感器的采样时序安排。DHT11每次读取需要约20ms,BH1750约120ms,如果同时读取可能导致系统响应延迟。我的解决方案是采用分时采样策略:
- 奇数秒:读取光照和温湿度
- 偶数秒:检测火焰和雨滴
这样既保证了数据实时性,又避免了资源冲突。
3. 硬件连接详解
3.1 核心电路连接
所有传感器和执行器的连接都需要遵循两个原则:
- 电源匹配:确保供电电压与模块要求一致
- 信号隔离:数字信号要加适当上拉/下拉电阻
具体接线方案(使用Nano引脚):
code复制BH1750:SCL→A5, SDA→A4, VCC→3.3V, GND→GND
DHT11:DATA→D2, VCC→5V, GND→GND
火焰传感器:OUT→D3, VCC→5V, GND→GND
舵机:PWM→D6, VCC→5V, GND→GND
LCD1602:RS→D7, EN→D8, D4→D9, D5→D10, D6→D11, D7→D12
重要提示:舵机工作时电流较大(峰值可达500mA),建议单独供电或增加大容量电容(1000μF)滤波,否则可能导致Arduino复位。
3.2 电源设计
系统采用两种供电方案:
- 开发调试阶段:USB供电(5V/500mA)
- 实际部署时:5V/2A电源适配器+降压模块
实测各模块电流消耗:
- Arduino Nano:20mA
- 传感器组:约15mA
- LCD屏:5mA
- 舵机(工作状态):300-500mA
因此电源适配器至少要提供1A的持续电流,建议留50%余量选择2A电源。
4. 软件实现
4.1 核心算法设计
光照数据处理采用移动平均滤波算法:
cpp复制#define FILTER_LEN 5
int filterBuffer[FILTER_LEN];
int filterIndex = 0;
int movingAverage(int newValue) {
filterBuffer[filterIndex] = newValue;
filterIndex = (filterIndex + 1) % FILTER_LEN;
long sum = 0;
for(int i=0; i<FILTER_LEN; i++) {
sum += filterBuffer[i];
}
return sum / FILTER_LEN;
}
温湿度控制采用滞后比较算法,避免设备频繁启停:
cpp复制void tempControl(float currentTemp) {
static bool fanState = false;
if(!fanState && currentTemp > 28.0) { // 高于28度启动
digitalWrite(FAN_PIN, HIGH);
fanState = true;
}
else if(fanState && currentTemp < 26.0) { // 低于26度停止
digitalWrite(FAN_PIN, LOW);
fanState = false;
}
}
4.2 主要功能实现
光照自适应调节逻辑:
- 当光照<100lux:开启LED并随光照降低线性增加亮度
- 100-300lux:保持LED最低亮度
- 300-1000lux:关闭LED
-
1000lux:控制舵机关闭窗帘(分步执行,每次转动10°)
火焰报警处理流程:
cpp复制void checkFire() {
if(digitalRead(FIRE_PIN) == LOW) { // 检测到火焰
digitalWrite(BUZZER_PIN, HIGH);
lcd.setCursor(0, 1);
lcd.print("FIRE ALERT!");
delay(1000); // 持续报警
} else {
digitalWrite(BUZZER_PIN, LOW);
}
}
5. 系统调试与优化
5.1 校准技巧
光照传感器校准方法:
- 在完全黑暗环境下读取传感器值(应为0-10lux)
- 在标准500lux光源下读取
- 计算校准系数:实际值/测量值
实测发现BH1750在低照度时线性度较差,解决方法:
cpp复制float adjustLux(int raw) {
if(raw < 100) return raw * 0.8; // 低照度补偿
else if(raw > 10000) return raw * 1.1; // 高照度补偿
else return raw;
}
5.2 常见问题解决
问题1:DHT11偶尔读取失败
解决方案:
- 增加读取超时判断
- 失败后延迟至少2秒再重试
- 硬件上在DATA线加4.7K上拉电阻
问题2:舵机出现抖动
解决方法:
- 确保电源充足(电压不低于4.8V)
- 在程序中增加20ms延时between信号变化
- 在舵机电源端并联100μF电容
问题3:LCD显示乱码
排查步骤:
- 检查对比度调节电位器(通常10KΩ)
- 确认初始化时序正确(需至少40ms延时after power on)
- 重新插拔排线,确保接触良好
6. 实际应用效果
经过两周的连续运行测试,系统表现如下:
- 光照检测误差:±5%(与专业照度计对比)
- 温度检测误差:±0.5℃
- 响应延迟:<1秒(从环境变化到执行动作)
- 误报率:火焰检测<0.1%
功耗情况:
- 待机状态:35mA
- 工作状态:平均80mA(峰值600mA)
几个实用的功能扩展建议:
- 增加蓝牙模块,实现手机参数设置
- 添加RTC模块,实现时段控制策略
- 接入物联网平台,实现远程监控
- 使用太阳能电池板供电,实现完全无线
这个项目最让我满意的不是技术实现,而是看到朋友家人实际使用时的便利性。特别是自动窗帘功能,早上会根据室内光线缓缓打开,既保证了自然醒的舒适感,又节省了手动操作的麻烦。整个系统的硬件成本不到300元,但实现了商业系统上千元的功能,这就是DIY的乐趣所在。