红外传感器 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用于灵敏度调节
LED5mm¥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

  2. $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 模块¥101¥10
Arduino Nano¥181¥18
光敏电阻模块¥51¥5
LED 灯珠¥13¥3
电阻电容若干¥51¥5
PCB 洞洞板¥31¥3
外壳(3D 打印)¥101¥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

  2. $1

  3. $1

  4. $1

  5. $1

  6. $1

  7. $1

从简单的 LED 指示,到智能家居自动化,再到远程监控系统,PIR 传感器都能胜任。关键是理解它的特性,用合适的方法规避局限。

希望这篇博客文章对您有所帮助!