红外传感器 PIR 人体检测优化技巧:误触发解决方案
为什么你的 PIR 传感器总是误触发?
用过 PIR(Passive Infrared,被动红外)人体传感器的朋友大概都遇到过这样的困扰:明明没人经过,传感器却莫名其妙触发;或者人站在那儿不动,它反而检测不到了。
这真不是传感器坏了,而是 PIR 的工作原理决定的。今天我们就来聊聊如何让 PIR 传感器变得”聪明”起来,把误触发率降到最低。
PIR 传感器工作原理速览
PIR 传感器检测的不是”人”,而是红外辐射的变化。人体体温约 37°C,会辐射出特定波长的红外线。当人移动时,传感器接收到的红外辐射强度发生变化,从而触发信号。
关键点来了:PIR 检测的是变化,不是存在。这就是为什么人静止不动时,传感器会”失去目标”。
硬件清单
| 型号 | 描述 | 价格 | 备注 |
|---|---|---|---|
| HC-SR501 | 经典 PIR 模块,可调灵敏度 | ¥8-12 | 最常用,推荐新手 |
| HC-SR505 | 小型 PIR 模块 | ¥6-10 | 体积小巧 |
| AM312 | 微型 PIR 传感器 | ¥5-8 | 适合便携项目 |
| Arduino Nano | 开发板 | ¥15-20 | 或 ESP32/STM32 |
| 电位器 | 10kΩ | ¥1 | 用于灵敏度调节 |
| LED | 5mm | ¥0.5 | 状态指示 |
硬件连接(以 HC-SR501 为例)
HC-SR501 有 3 个引脚:
-
VCC: 5V 电源
-
OUT: 信号输出(高电平触发)
-
GND: 接地
# Arduino 连接
HC-SR501 VCC → Arduino 5V
HC-SR501 OUT → Arduino D2
HC-SR501 GND → Arduino GND
模块上有两个可调电位器:
-
时间调节:控制触发后输出高电平的持续时间(5-300 秒)
-
灵敏度调节:控制检测距离(3-7 米)
基础代码示例
先从最简单的开始:
const int pirPin = 2;
const int ledPin = 13;
void setup() {
pinMode(pirPin, INPUT);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.println("PIR 传感器初始化完成");
}
void loop() {
int pirState = digitalRead(pirPin);
if (pirState == HIGH) {
digitalWrite(ledPin, HIGH);
Serial.println("检测到人体移动!");
delay(1000);
} else {
digitalWrite(ledPin, LOW);
}
}
这段代码能工作,但会有两个问题:
-
$1
-
$1
优化方案一:预热处理
HC-SR501 上电后需要预热时间,让内部电路稳定。我们可以在 setup 中加入延时:
void setup() {
pinMode(pirPin, INPUT);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.println("PIR 传感器预热中...");
delay(60000); // 预热 60 秒
Serial.println("预热完成,开始检测");
}
优化方案二:软件滤波算法
硬件调节有局限,软件滤波可以更精细地控制。下面是一个实用的滤波算法:
const int pirPin = 2;
const int ledPin = 13;
// 滤波参数
const int SAMPLE_COUNT = 5; // 采样次数
const int TRIGGER_THRESHOLD = 3; // 触发阈值(5 次中 3 次检测到)
const int COOLDOWN_MS = 5000; // 冷却时间,避免重复触发
unsigned long lastTriggerTime = 0;
bool isTriggered = false;
void setup() {
pinMode(pirPin, INPUT);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.println("PIR 传感器预热中...");
delay(60000);
Serial.println("系统就绪");
}
bool readPIRWithFilter() {
int triggerCount = 0;
for (int i = 0; i = TRIGGER_THRESHOLD;
}
void loop() {
unsigned long currentTime = millis();
// 冷却时间内不处理
if (currentTime - lastTriggerTime 0 && distance 12) {
sendWechatAlert("⚠️ 父母超过 12 小时未活动,请确认安全!");
}
}
}
void handleNightMotion() {
struct tm timeinfo;
getLocalTime(&timeinfo);
// 晚上 10 点到早上 6 点
if (timeinfo.tm_hour >= 22 || timeinfo.tm_hour = TRIGGER_THRESHOLD;
}
bool isNight() {
return analogRead(lightSensorPin) COOLDOWN_MS) {
analogWrite(lightPin, 0);
isLightOn = false;
Serial.println("自动关灯");
return;
}
// 人体检测
if (readPIRWithFilter() && !isLightOn) {
analogWrite(lightPin, 200); // 80% 亮度
isLightOn = true;
lastTriggerTime = currentTime;
Serial.println("检测到人体,开灯");
}
}
成本分析
做一个完整的 PIR 人体检测系统,成本非常低:
| 组件 | 单价 | 数量 | 小计 |
|---|---|---|---|
| HC-SR501 PIR 模块 | ¥10 | 1 | ¥10 |
| Arduino Nano | ¥18 | 1 | ¥18 |
| 光敏电阻模块 | ¥5 | 1 | ¥5 |
| LED 灯珠 | ¥1 | 3 | ¥3 |
| 电阻电容若干 | ¥5 | 1 | ¥5 |
| PCB 洞洞板 | ¥3 | 1 | ¥3 |
| 外壳(3D 打印) | ¥10 | 1 | ¥10 |
| 总计 | ¥54 |
相比市面成品的智能人体传感器(¥80-200),DIY 方案成本降低 50% 以上,而且可以完全自定义功能。
功耗优化技巧
如果是电池供电项目,功耗是关键。HC-SR501 静态电流约 50μA,触发时约 2mA。以下是降低功耗的方法:
使用休眠模式
#include
const int pirPin = 2;
volatile bool pirTriggered = false;
// PIR 中断回调
void pirISR() {
pirTriggered = true;
}
void setup() {
pinMode(pirPin, INPUT);
attachInterrupt(digitalPinToInterrupt(pirPin), pirISR, RISING);
Serial.begin(9600);
}
void loop() {
if (pirTriggered) {
pirTriggered = false;
// 唤醒后处理
Serial.println("检测到人体!");
// 执行任务...
delay(1000);
}
// 进入休眠
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_mode();
// 唤醒后继续
sleep_disable();
}
使用休眠模式后,待机电流可降至 10μA 以下,两节 AA 电池可以工作 1 年以上。
降低采样频率
不需要持续检测时,可以间歇性工作:
void loop() {
// 工作 1 秒
bool detected = readPIRWithFilter();
if (detected) {
handleDetection();
}
// 休眠 10 秒
delay(10000);
}
这样平均功耗降低 90%。
ESP32 版本代码
如果你使用 ESP32,可以利用其深度睡眠特性:
#include
#include
#define PIR_PIN 4
#define uS_TO_S_FACTOR 1000000
#define TIME_TO_SLEEP 5
RTC_DATA_ATTR int bootCount = 0;
void print_wakeup_reason() {
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch(wakeup_reason) {
case ESP_SLEEP_WAKEUP_EXT0:
Serial.println("Wakeup caused by external signal using RTC_IO");
break;
case ESP_SLEEP_WAKEUP_EXT1:
Serial.println("Wakeup caused by external signal using RTC_CNTL");
break;
case ESP_SLEEP_WAKEUP_TIMER:
Serial.println("Wakeup caused by timer");
break;
default:
Serial.println("Wakeup was not caused by deep sleep");
break;
}
}
void setup() {
Serial.begin(115200);
bootCount++;
Serial.println("Boot number: " + String(bootCount));
print_wakeup_reason();
// 配置 PIR 引脚为唤醒源
gpio_hold_en((gpio_num_t)PIR_PIN);
if (digitalRead(PIR_PIN) == HIGH) {
Serial.println("人体检测!发送通知...");
// 连接 WiFi 并发送通知
WiFi.begin("your-ssid", "your-password");
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts
#include
InfluxDbClient client("http://your-influx-server:8086", "iot_db");
Point motion_point("motion_events");
void logMotionEvent() {
motion_point.clearFields();
motion_point.addField("detected", 1);
motion_point.setTime(DateTime.now());
if (client.writePoint(motion_point)) {
Serial.println("数据已记录到 InfluxDB");
}
}
void setup() {
// ... 初始化代码
client.setConnectionParamsV1();
}
然后在 Grafana 中创建仪表盘,可以看到每天的人体活动热力图。
与 Home Assistant 集成
如果你使用 Home Assistant,可以通过 MQTT 集成:
#include
#include
const char* mqtt_server = "home-assistant.local";
const char* mqtt_topic = "home/sensor/pir_livingroom";
WiFiClient espClient;
PubSubClient client(espClient);
void reconnect() {
while (!client.connected()) {
if (client.connect("ESP32-PIR-Sensor")) {
Serial.println("MQTT 已连接");
} else {
delay(5000);
}
}
}
void setup() {
client.setServer(mqtt_server, 1883);
// ... 其他初始化
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
if (readPIRWithFilter()) {
client.publish(mqtt_topic, "ON");
Serial.println("MQTT: 发送 ON");
}
}
在 Home Assistant 的 configuration.yaml 中添加:
binary_sensor:
- platform: mqtt
name: "客厅人体传感器"
state_topic: "home/sensor/pir_livingroom"
payload_on: "ON"
payload_off: "OFF"
device_class: motion
这样你就可以在 Home Assistant 中创建自动化,例如”检测到人体时开灯”。
总结
PIR 人体传感器成本低、功耗小,是 IoT 项目的常用选择。但要用好它,需要:
-
$1
-
$1
-
$1
-
$1
-
$1
-
$1
-
$1
从简单的 LED 指示,到智能家居自动化,再到远程监控系统,PIR 传感器都能胜任。关键是理解它的特性,用合适的方法规避局限。
希望这篇博客文章对您有所帮助!