ESP32智能家居实战:用PIR传感器DIY人体感应灯(附完整代码)
·
ESP32智能家居实战:用PIR传感器DIY人体感应灯(附完整代码)
深夜起床摸黑找开关的经历相信很多人都有过。传统感应灯要么价格昂贵,要么功能单一,而今天我们要用成本不到50元的ESP32开发板和PIR传感器,打造一个能智能判断环境光线、自动调节亮度的可编程人体感应灯。这个项目不仅能解决夜间照明痛点,还能通过简单的代码修改实现更多扩展功能。
1. 硬件选型与核心原理
1.1 为什么选择ESP32+PIR方案
ESP32-WROOM-32D开发板具备以下优势:
- 双核240MHz处理器,轻松处理传感器数据
- 内置Wi-Fi/蓝牙,便于后续智能联动
- 超低功耗模式(仅10μA)适合常电设备
- 丰富的GPIO接口(34个)支持多传感器扩展
HC-SR501 PIR传感器的特性参数:
| 参数 | 数值范围 | 说明 |
|---|---|---|
| 检测距离 | 3-7米可调 | 通过电位器调节 |
| 触发输出 | 高电平3.3V | 直接兼容ESP32电平 |
| 延时时间 | 5-300秒可调 | 控制灯亮持续时间 |
| 工作温度 | -15℃~+70℃ | 适合室内环境 |
| 静态功耗 | <60μA | 几乎可忽略的待机耗电 |
1.2 光线检测的巧妙实现
传统方案需要单独的光敏电阻,而我们利用ESP32的ADC特性,通过LED反向作为光传感器:
// 利用LED光电效应检测环境光
int readLightLevel(int pin) {
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW); // 放电
delayMicroseconds(10);
pinMode(pin, INPUT);
unsigned long start = micros();
while(digitalRead(pin)==LOW && micros()-start<10000);
return micros()-start; // 值越大表示环境越暗
}
提示:使用白光LED效果最佳,普通LED需实测校准阈值
2. 硬件搭建与电路设计
2.1 物料清单(总成本<50元)
- ESP32开发板 ×1(约25元)
- HC-SR501 PIR传感器 ×1(约8元)
- 5mm白光LED ×3(共约2元)
- 220Ω电阻 ×3(共约0.3元)
- 微型面包板 ×1(约5元)
- 杜邦线若干(约2元)
2.2 电路连接示意图
PIR传感器 ESP32
VCC → 3.3V
OUT → GPIO13
GND → GND
LED组(并联) ESP32
正极 → GPIO12 → 220Ω电阻
负极 → GND
光线检测LED ESP32
正极 → GPIO14
负极 → GND(不接电阻)
注意:PIR传感器的灵敏度调节旋钮建议先设为中间值,安装后再微调
3. 核心代码实现与优化
3.1 基础功能实现
#include <Arduino.h>
// 引脚定义
const int pirPin = 13;
const int ledPin = 12;
const int lightSensePin = 14;
// 光线阈值(需根据实测调整)
const int DARK_THRESHOLD = 5000;
void setup() {
Serial.begin(115200);
pinMode(pirPin, INPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
}
void loop() {
int lightLevel = readLightLevel(lightSensePin);
bool isDark = lightLevel > DARK_THRESHOLD;
if(digitalRead(pirPin) == HIGH && isDark) {
digitalWrite(ledPin, HIGH);
Serial.println("Motion detected - Light ON");
delay(5000); // 基础延时5秒
} else {
digitalWrite(ledPin, LOW);
}
delay(100); // 降低CPU占用
}
3.2 高级功能扩展
渐亮渐灭效果
void smoothLightControl(bool turnOn) {
int brightness = 0;
int step = turnOn ? 5 : -5;
while(turnOn ? brightness<=255 : brightness>=0) {
analogWrite(ledPin, brightness);
brightness += step;
delay(20);
}
}
环境自适应亮度
int adaptiveBrightness(int lightLevel) {
// 将光强映射到PWM值(0-255)
int raw = map(lightLevel, 2000, 8000, 50, 255);
return constrain(raw, 50, 255); // 限制最低亮度
}
4. 安装调试与性能优化
4.1 最佳安装位置选择
- 高度建议:1.8-2.2米(略高于门框)
- 角度调整:
- 走廊:传感器轴线与走廊方向呈30°夹角
- 门口:朝向活动区域中心
- 卫生间:避免直对淋浴水汽
4.2 常见问题排查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 灯常亮不灭 | PIR延时调节过长 | 逆时针旋转"Time"电位器 |
| 反应迟钝 | 检测距离设置过远 | 顺时针旋转"Sens"电位器 |
| 频繁误触发 | 安装在空调/暖气附近 | 改变位置或加装遮光罩 |
| 白天也亮灯 | 光线阈值设置不当 | 重新校准DARK_THRESHOLD值 |
| LED闪烁不稳定 | 电源功率不足 | 改用独立5V电源供电 |
4.3 功耗优化技巧
- 启用ESP32深度睡眠:
#define uS_TO_S_FACTOR 1000000
esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 1); // PIR触发唤醒
esp_deep_sleep_start();
- PWM频率提升至10kHz减少可闻噪声:
ledcSetup(0, 10000, 8); // 通道0, 10kHz, 8位分辨率
ledcAttachPin(ledPin, 0);
5. 进阶扩展方案
5.1 智能家居联动
通过MQTT接入HomeAssistant:
#include <WiFi.h>
#include <PubSubClient.h>
WiFiClient espClient;
PubSubClient client(espClient);
void callback(char* topic, byte* payload, unsigned int length) {
// 处理云端指令
}
void reconnect() {
while (!client.connected()) {
if (client.connect("ESP32Light")) {
client.subscribe("home/bedroom/light/cmd");
}
}
}
void setup() {
// ...原有代码...
client.setServer("mqtt_server", 1883);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) reconnect();
client.loop();
if(motionDetected) {
client.publish("home/bedroom/light/status", "ON");
}
}
5.2 多传感器融合方案
结合毫米波雷达(LD2410)实现静态存在检测:
# MicroPython示例
from machine import UART
uart = UART(1, baudrate=256000, tx=17, rx=16)
def check_presence():
uart.write(b'\xFD\xFC\xFB\xFA\x04\x03\x02\x01')
if uart.any():
data = uart.read()
if data[7] == 0x01: # 静态目标标志
return True
return False
5.3 3D打印外壳设计
推荐使用以下参数设计壁挂外壳:
- 壁厚:2mm
- 传感器开孔:20×15mm矩形
- 散热孔:直径1.5mm阵列
- 安装方式:磁吸或3M胶贴
difference() {
cube([80,60,30], center=true);
translate([0,0,5]) cube([76,56,28], center=true);
translate([30,0,0]) cube([20,15,10], center=true); // PIR开口
}
实际测试中,将PIR的延时设置为15秒,光线阈值根据卧室环境校准为4200,配合5V/2A电源适配器,系统已稳定运行6个月。最惊喜的是通过HomeAssistant联动,实现了"起夜自动亮灯→到达卫生间→卫生间灯已亮"的无缝体验。
更多推荐



所有评论(0)