人体感应灯
重要提示:关于开发板的兼容性
本教程的核心逻辑适用于所有 ESP32 开发板,但所有操作步骤均以 微雪 ESP32-S3-Zero 迷你开发板 为例进行讲解。如果您使用其他型号的开发板,请根据实际情况修改相应设置。
项目介绍
本项目通过 PIR(被动红外)传感器检测人体存在,自动控制 WS2812 LED 灯带的开关,实现智能感应照明功能。当传感器检测到人体活动时,灯带自动点亮;当持续一段时间未检测到活动后,灯带自动熄灭。
硬件连接
需要使用的器件有:
- PIR 运动传感器 * 1
- WS2812 灯条 * 1
- 面包板 * 1
- 导线
- ESP32 开发板
按照下面接线图连接电路:
ESP32-S3-Zero 引脚图


硬件连接注意事项
- 电源连接:PIR 传感器和 WS2812 灯带都需要连接到 5V 电源。
- 跳线帽设置:PIR 模块的跳线帽需要设置为 H 模式(高电平触发模式)。
- 调试建议:为方便初次调试,建议先将 PIR 模块的检测距离调节到最低,避免误触发,待功能验证正常后再根据实际需求调整。
代码实现
提示
此代码示例依赖 “FastLED” 库。请在 Arduino IDE 的库管理器中搜索并安装 “FastLED” 库。
安装方法请参考:Arduino 库管理教程。
/*
人体感应灯
当 PIR 传感器检测到人体运动时,点亮 WS2812 LED 灯带。
如果在设定时间内没有再次检测到运动,灯光将自动熄灭。
电路连接:
* PIR 传感器信号脚 -> 引脚 7
* WS2812 LED 数据脚 -> 引脚 8
Wulu (Waveshare Team)
*/
#include <FastLED.h>
// --- 配置参数 ---
const int pirPin = 7; // PIR 传感器连接的引脚
const int ledPin = 8; // LED 灯带连接的引脚
const int numLeds = 8; // 灯珠的数量
const unsigned long lightDuration = 5000; // 亮灯持续时间 (毫秒)
// 定义 LED 数组
CRGB leds[numLeds];
// --- 状态变量 ---
boolean isLightOn = false; // 记录当前灯是否亮着
unsigned long lastMotionTime = 0; // 记录最后一次检测到运动的时间
void setup() {
Serial.begin(115200);
// 设置 PIR 引脚为下拉输入模式 (未触发时保持低电平)
pinMode(pirPin, INPUT_PULLDOWN);
// 初始化 LED 灯带
FastLED.addLeds<WS2812, ledPin, GRB>(leds, numLeds);
FastLED.setBrightness(50);
FastLED.clear();
FastLED.show();
Serial.println("系统已启动...");
turnLightOff(); // 确保启动时灯是灭的
}
void loop() {
unsigned long currentTime = millis();
int motionState = digitalRead(pirPin);
// 1. 如果检测到运动,重置计时器
if (motionState == HIGH) {
lastMotionTime = currentTime;
// 如果灯没亮,把它打开
if (!isLightOn) {
Serial.println("检测到运动 -> 开灯");
turnLightOn();
isLightOn = true;
}
}
// 2. 如果没有运动,检查是否超时
else {
if (isLightOn) {
unsigned long duration = currentTime - lastMotionTime;
// 如果当前时间减去最后运动时间超过了设定时长
if (duration > lightDuration) {
Serial.println("超时无人 -> 关灯");
turnLightOff();
isLightOn = false;
delay(1000); //稍微延时,防止临界状态闪烁
}
}
}
delay(100); // 简单的循环延时
}
// 开灯函数
void turnLightOn() {
fill_solid(leds, numLeds, CRGB::Purple);
FastLED.show();
}
// 关灯函数
void turnLightOff() {
fill_solid(leds, numLeds, CRGB::Black);
FastLED.show();
}
代码解释
-
引入库:引入
FastLED.h库,这是一个功能强大且易于使用的 LED 控制库。提示此代码示例依赖 “FastLED” 库。请在 Arduino IDE 的库管理器中搜索并安装 “FastLED” 库。
安装方法请参考:Arduino 库管理教程。
-
配置参数与全局变量:
- 使用
const关键字定义常量,包括引脚号、LED 数量和持续时间。 - 创建
CRGB数组leds,用于存储每个 LED 的颜色数据。 - 定义全局变量
isLightOn和lastMotionTime用于状态管理。
const int pirPin = 7;
const int ledPin = 8;
const int numLeds = 8;
const unsigned long lightDuration = 5000;
CRGB leds[numLeds]; - 使用
-
初始化 (
setup):- 初始化串口和 PIR 引脚。
- 使用
FastLED.addLeds初始化灯带配置。这里指定了 LED 类型 (WS2812)、引脚 (ledPin) 和色彩顺序 (GRB)。 FastLED.setBrightness(50)设置全局亮度,避免太刺眼或电流过大。
void setup() {
// ...
FastLED.addLeds<WS2812, ledPin, GRB>(leds, numLeds);
FastLED.setBrightness(50);
// ...
} -
功能函数 (
turnLightOn/turnLightOff):- 将开灯和关灯的逻辑拆分为两个独立的函数,避免使用布尔参数,使代码意图更清晰。
- 使用
fill_solid函数快速填充整个灯带的颜色。 CRGB::Purple是库中预定义的紫色,也可以使用CRGB(128, 0, 128)自定义。FastLED.show()发送数据更新灯带显示。
void turnLightOn() {
fill_solid(leds, numLeds, CRGB::Purple);
FastLED.show();
} -
主循环 (
loop):- 逻辑与之前相同:检测 PIR 状态,有人则开灯并刷新时间,无人且超时则关灯。
- 使用
millis()进行非阻塞的时间计算。