4. 人体运动检测实战:基于PIR的人体感应灯设计

做嵌入式这些年,PIR传感器是我用得最多的器件之一。从楼道灯到安防报警,几乎每个项目都离不开它。今天咱们就聊聊怎么用PIR做一个靠谱的人体感应灯——不光要能亮,还得灵敏可调、延时可控,最关键的是别让家里的猫猫狗狗把灯搞亮了。

本章核心目标:搭建一个完整的人体感应灯系统,掌握灵敏度调节、延时控制、抗误报三大实战技能。

4.1 硬件选型与电路基础

PIR传感器型号很多,我个人最常用的是HC-SR501。便宜、稳定、资料多。它的核心是一个热释电元件,能检测人体发出的红外辐射变化。

参数 HC-SR501 AM312 D203S
工作电压 DC 4.5-20V DC 2.7-12V DC 3-5V
检测距离 3-7米(可调) 3-5米 5-8米
延时范围 5-200秒 2-30秒 固定8秒
输出电平 高/低可选 高电平 高电平

我建议新手先从HC-SR501入手。它有两个可调电位器,一个管灵敏度,一个管延时。说白了就是拧螺丝就能调参数,特别适合做实验。

小技巧:HC-SR501背面有个跳线帽,用来选择触发模式。单次触发模式适合做感应灯,重复触发模式适合做安防报警。我一般做灯就用单次模式。

4.2 灵敏度调节——别让灯乱亮

灵敏度调节其实就是调整PIR传感器的检测距离和角度。拧电位器的时候,你会听到"咔咔"的声音,那就是在改变比较器的参考电压。

我在项目中遇到过一个问题:把灵敏度拧到最大,结果灯连窗外路过的行人都能检测到。后来我总结了一套调参方法:

  1. 先拧到最小——让人站在传感器正前方1米处
  2. 慢慢增大——直到灯能稳定触发
  3. 退半步——再往回拧一点点,留出余量

为什么会这样?因为PIR对温度变化敏感。夏天室内外温差小,灵敏度要调高一点;冬天温差大,调低一点就行。你想想看,如果冬天把灵敏度调太高,暖气片都能让灯亮起来。

注意:灵敏度不是越高越好。过高的灵敏度会导致频繁误触发,尤其在温度变化剧烈的环境中。我曾经在一个项目里把灵敏度调太高,结果灯一晚上亮了上百次——客户差点投诉。

4.3 延时控制——灯该亮多久

延时控制决定了人离开后灯还能亮多久。HC-SR501的延时范围是5-200秒,通过另一个电位器调节。

我个人的习惯是:

  • 走廊/楼梯间:15-30秒——够用就行
  • 卫生间:60-120秒——你懂的,有时候需要久一点
  • 车库/储藏室:30-60秒——搬东西的时候别突然灭灯

如果你用单片机控制,可以更灵活。比如用Arduino读取PIR输出,然后自己写延时逻辑:

// PIR人体感应灯延时控制示例
const int pirPin = 2;    // PIR输出引脚
const int ledPin = 13;   // LED控制引脚
const int delayTime = 30000; // 延时30秒

void setup() {
  pinMode(pirPin, INPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
}

void loop() {
  if (digitalRead(pirPin) == HIGH) {
    digitalWrite(ledPin, HIGH);
    delay(delayTime);
    digitalWrite(ledPin, LOW);
  }
}

这段代码很简单,但有个问题:如果在延时期间有人再次触发,灯会重新计时吗?不会。这就是单次触发模式的局限。想实现"人一直在灯就一直亮"的效果,需要用重复触发模式,或者在代码里做计时器重置。

4.4 抗误报策略——宠物免疫

这是最头疼的问题。家里养猫养狗的朋友肯定深有体会——灯被宠物搞亮,一晚上能亮几十次。

宠物免疫的核心思路是:区分人体和宠物的红外信号特征。宠物体型小、体温高、移动速度快,和人体有明显区别。

我常用的几种方法:

方法 原理 优缺点
遮挡法 在传感器下方加挡板,屏蔽地面附近区域 简单有效,但会缩小检测范围
双传感器法 用两个PIR做差分检测,比较信号强度 效果好,但成本高
信号分析法 用单片机分析PIR输出信号的脉宽和幅度 灵活,但需要算法
透镜选择法 更换菲涅尔透镜,改变检测角度 一劳永逸,但需要选型

我最推荐的是遮挡法+信号分析法的组合。先物理屏蔽掉地面30cm以下的区域,然后在代码里加一个简单的脉宽判断:

// 宠物免疫:脉宽判断法
const int minPulseWidth = 500; // 最小脉宽500ms

void loop() {
  if (digitalRead(pirPin) == HIGH) {
    unsigned long startTime = millis();
    while (digitalRead(pirPin) == HIGH) {
      // 等待信号结束
    }
    unsigned long pulseWidth = millis() - startTime;
    
    if (pulseWidth > minPulseWidth) {
      // 人体触发
      digitalWrite(ledPin, HIGH);
      delay(30000);
      digitalWrite(ledPin, LOW);
    }
    // 脉宽小于500ms,认为是宠物,忽略
  }
}

为什么宠物的脉宽会短?因为宠物移动速度快,经过传感器的时间短。人体移动慢,信号持续时间长。当然,这个方法不是100%准确——如果宠物在你面前晃悠半天,还是可能触发。但对付大多数情况足够了。

实战经验:我曾经在一个别墅项目里用双传感器法做宠物免疫。两个PIR上下排列,间距15cm。只有两个传感器同时触发才认为是人体。结果猫跳上沙发的时候,只触发了下面的传感器——完美过滤。但狗子体型大,两个都触发了,那就没办法了。所以宠物免疫没有银弹,要根据实际情况组合使用。

4.5 完整系统流程图

下面这张图展示了人体感应灯从检测到控制的完整流程:

人体感应灯系统流程图 PIR传感器检测 信号脉宽判断 宠物触发 → 忽略 人体触发 → 开灯 延时计时器启动 延时结束 → 关灯 说明:宠物免疫通过脉宽判断实现,人体信号脉宽通常大于500ms

4.6 常见问题与避坑指南

做PIR项目,我踩过的坑比走过的路还多。这里列几个最常见的:

  • 上电后灯一直亮:HC-SR501上电后有30-60秒的稳定期,期间输出不稳定。等一会儿就好了。
  • 检测距离越来越短:菲涅尔透镜脏了。用软布擦一下,别用酒精。
  • 灯忽亮忽灭:电源纹波太大。PIR对电源质量敏感,加个100μF电容滤波。
  • 宠物免疫失效:别只依赖一种方法。物理遮挡+软件滤波+透镜选型,三重保险。

重要提醒:PIR传感器不能穿透玻璃或墙壁。如果你想把传感器装在室外检测室内,那是行不通的。红外辐射会被玻璃反射和吸收。我见过有人把PIR对着窗户装,结果灯从来没亮过——嗯,物理课没学好。

好了,这一章的内容就到这里。PIR人体感应灯看起来简单,但要做好、做稳、做智能,还是有不少门道的。希望这些实战经验能帮你少走弯路。