运动传感器
当你走近一些自动开关门、自动开关灯泡或自动启动自动扶梯的地方时,你是否会产生这样的疑问:**"它是怎么做到的? **它是怎么做到的? 如果有,本教程不仅会回答,还会告诉你如何制作。 让我们开始吧!
在本教程中,我们将学习
- HC-SR501 运动传感器的工作原理
- 如何将 HC-SR501 运动传感器连接到 Arduino
- 如何对 Arduino 进行编程以读取 HC-SR501 运动传感器的状态
- 如何使用 Arduino 和 HC-SR501 运动传感器检测人的进入并据此采取行动。
关于 HC-SR501 运动传感器
HC-SR501 PIR 传感器是一种能检测到人(或动物)运动的传感器。 它在许多应用中被广泛用于探测人的存在(自动开启/关闭灯泡、开门/关门、启动/关闭自动扶梯、探测入侵者…)。
引脚
HC-SR501 运动传感器有 3 个引脚:
-
GND pin: 需要连接至 GND(0V)
-
VCC pin: 需要连接至 VCC(5V)
-
OUTPUT pin: 是一个输出引脚: 未检测到运动时为低电平,检测到运动时为高电平。 该引脚需要连接到 Arduino 的输入引脚。
HC-SR501 还有一个跳线和两个电位器,用于调整传感器的设置。 首先,保持默认设置。 详细说明请参阅 "高级用途 " 部分。
如何使用
HC-SR501 传感器根据移动物体的红外辐射变化来检测运动。 要被 HC-SR501 传感器检测到,物体必须满足两个条件:
-
移动或摇晃
-
正在发射红外线。
So:
-
如果物体在移动,但没有发射红外线(如机器人或车辆玩具),传感器就检测不到它。
-
如果物体发出红外线但没有移动(如人静止不动),传感器就检测不到它。
人类和动物会自然发出红外线。 因此,传感器可以检测到人类和动物的移动。
OUTPUT pin’s state:
-
当传感器检测范围内没有人(或动物)移动时,传感器的输出引脚为低电平。
-
当有人(或动物)进入传感器的检测范围时,传感器的输出引脚将从低电平变为高电平。 (⇒ motion detected).
-
当有人(或动物)离开传感器的检测范围时,传感器的输出引脚会从高电平变为低电平。 (⇒ motion ended).
在实际应用中,运动传感器的工作原理略有不同,具体取决于传感器的设置
检测人类的存在
传感器本身并不能检测到人的存在,传感器只是检测运动。 我们使用 Arduino(或 MCU),根据传感器的运动检测,按照以下规则推断人类的存在:
-
如果检测到运动,则说明有人类存在
-
如果未检测到运动,则表示人类不在现场
在实际情况中,这条规则是不正确的:人在传感器范围内,但没有移动。 因此检测不到运动。 Arduino (或 MCU)推断出人类不在。
例如,您的会议室使用运动传感器自动开关灯,当有人进入会议室时,灯就会自动打开。 在会议期间,如果每个人都坐着不动,就不会检测到运动 ⇒ 人不在场 ⇒ 灯会自动关闭。 要开灯,需要有人移动。
不过,这个问题并不严重,传感器也很便宜。 因此,该传感器在许多应用中被广泛用于探测人体。
Arduino - HC-SR501 运动传感器
当 Arduino 的引脚被配置为数字输入时,它可以读取所连接的任何设备的状态(低电平或高电平)。
通过将 Arduino 的引脚与 HC-SR501 传感器的 OUTPUT 引脚连接,我们可以使用 Arduino 代码来检查 OUTPUT 引脚的值,从而检测运动。
接线图
This image is created using Fritzing. Click to enlarge image
Initial Setting
延时调节器 | 逆时针方向拧到底。 |
检测范围调节器 | 顺时针方向拧到底。 |
重复触发选择器 | 如图所示放置跳线。 |
How To Program For Motion Sensor
- 使用
pinMode()
函数将Arduino
引脚配置为数字输入模式
pinMode(PIN_TO_SENSOR, INPUT);
- 使用
digitalRead()
函数读取传感器OUTPUT
引脚的状态。
pinStateCurrent = digitalRead(PIN_TO_SENSOR);
- 检测运动开始(引脚状态从低电平变为高电平)
pinStatePrevious = pinStateCurrent; // store old state
pinStateCurrent = digitalRead(PIN_TO_SENSOR); // read new state
if (pinStatePrevious == LOW && pinStateCurrent == HIGH) { // pin state change: LOW -> HIGH
Serial.println("Motion detected!");
}
- 检测运动停止(引脚状态从高电平变为低电平)
pinStatePrevious = pinStateCurrent; // store old state
pinStateCurrent = digitalRead(PIN_TO_SENSOR); // read new state
if (pinStatePrevious == HIGH && pinStateCurrent == LOW) { // pin state change: HIGH -> LOW
Serial.println("Motion stopped!");
}
Arduino Code
/*
* Created by ArduinoGetStarted.com
*
* This example code is in the public domain
*
* Tutorial page: https://arduinogetstarted.com/tutorials/arduino-motion-sensor
*/
const int PIN_TO_SENSOR = 2; // the pin that OUTPUT pin of sensor is connected to
int pinStateCurrent = LOW; // current state of pin
int pinStatePrevious = LOW; // previous state of pin
void setup() {
Serial.begin(9600); // initialize serial
pinMode(PIN_TO_SENSOR, INPUT); // set arduino pin to input mode to read value from OUTPUT pin of sensor
}
void loop() {
pinStatePrevious = pinStateCurrent; // store old state
pinStateCurrent = digitalRead(PIN_TO_SENSOR); // read new state
if (pinStatePrevious == LOW && pinStateCurrent == HIGH) { // pin state change: LOW -> HIGH
Serial.println("Motion detected!");
// TODO: turn on alarm, light or activate a device ... here
}
else
if (pinStatePrevious == HIGH && pinStateCurrent == LOW) { // pin state change: HIGH -> LOW
Serial.println("Motion stopped!");
// TODO: turn off alarm, light or deactivate a device ... here
}
}
Quick Steps
-
Copy the above code and open with Arduino IDE
-
Click Upload button on Arduino IDE to upload code to Arduino
-
Open Serial Monitor
-
Move your hand in front of sensor range
-
See the output in Serial Monitor
Video Tutorial
the videos.
高级用法
本节为深入知识。 不懂的地方不用担心。 如果本节内容过多,请忽略本节内容,改天再来学习。 继续阅读下一节。
如上所述,我们可以通过一个跳线和两个电位器来调整传感器的设置。
Detection Range Adjuster
该电位器用于调节检测范围(约 3 米至 7 米)。
-
如果完全按顺时针方向拧紧,检测范围约为 3 米。
-
如果完全按逆时针方向拧紧,探测距离约为 7 米。
我们可以调节电位器,以达到所需的范围(数值介于 3 米和 7 米之间)。
Time Delay Adjuster
该电位器用于调节时间延迟。
-
如果完全按顺时针方向拧紧,则延时约为 5 分钟。
-
如果完全按逆时针方向拧紧,则延时约为 3 秒。
下一部分将结合重复触发器解释时间延迟的含义。
重复触发选择器
跳线用于选择触发模式:单次触发或可重复触发。
我们把时间延迟设置(通过时间延迟调节器设置)称为 time_delay。 假设您在传感器范围内持续移动了很长时间(称为 motion_time)(比 time_delay 长好几倍)
- 单次触发模式: OUTPUT 引脚的状态在低电平和高电平之间切换多次。 高电平持续时间等于延时。 低电平持续时间固定为 3 秒。
- 可重复触发模式 在(运动时间 + 延迟时间)期间,OUTPUT 引脚的状态保持高电平。
Testing
为了了解触发模式的工作原理,我们来做个测试。 将时间延迟调节器逆时针调到 3 秒。
-
单次触发模式:
- 设置跳线以选择单次触发模式
- 手在传感器前移动约 10 秒钟。
- 将手移出传感器范围
- 等待 3 秒钟,您将在串行监视器中看到如下输出:
-
可重复触发模式
- 设置跳线以选择可重复触发模式
- 手在传感器前移动约 10 秒钟。
- 将手移出传感器范围
- 等待 3 秒钟,您将在串行监视器中看到如下输出:
我们可以看到,在单次触发模式下,传感器会触发两到三次。 在可重复触发模式下,传感器只触发一次。
※ 注意:
在这两种情况下,在 LOW(3 秒)时间内(固定值和不可调值),传感器无法检测到任何运动。 换言之,传感器在此期间处于闭锁状态。 实际上,这不会造成任何问题。
建议使用可重复触发模式。
在许多实际应用中:
-
人类出现后,我们立即打开或激活设备/机器
-
人不在场时,我们不会立即关闭或停用设备/机器。 我们会在超时后关闭或停用设备/机器。
如何使用延时器
当检测到不存在人类时,自动化系统将在延迟一段时间后采取行动。
时间延迟可通过运动传感器和 Arduino 代码进行设置:
-
运动传感器:最小 3 秒,最大 5 分钟。
-
关于 Arduino 代码:任何数值,通过编码完成
如果我们不在 Arduino 代码中设置超时,超时时间就等于传感器设置中的延迟时间。
如果我们在 Arduino 代码中设置超时,超时时间就是传感器设置中的时间延迟与 Arduino 代码中的时间延迟之和。
在 Arduino 代码中设置时间延迟
/*
* Created by ArduinoGetStarted.com
*
* This example code is in the public domain
*
* Tutorial page: https://arduinogetstarted.com/tutorials/arduino-motion-sensor
*/
const int PIN_TO_SENSOR = 2; // the pin that OUTPUT pin of sensor is connected to
int pinStateCurrent = LOW; // current state of pin
int pinStatePrevious = LOW; // previous state of pin
const unsigned long DELAY_TIME_MS = 30000; // 30000 miliseconds ~ 30 seconds
bool delayEnabled = false;
unsigned long delayStartTime;
void setup() {
Serial.begin(9600); // initialize serial
pinMode(PIN_TO_SENSOR, INPUT); // set arduino pin to input mode to read value from OUTPUT pin of sensor
}
void loop() {
pinStatePrevious = pinStateCurrent; // store state
pinStateCurrent = digitalRead(PIN_TO_SENSOR); // read new state
if (pinStatePrevious == LOW && pinStateCurrent == HIGH) { // pin state change: LOW -> HIGH
Serial.println("Motion detected!");
Serial.println("Turning on / activating");
delayEnabled = false; // disable delay
// TODO: turn on alarm, light or activate a device ... here
}
else
if (pinStatePrevious == HIGH && pinStateCurrent == LOW) { // pin state change: HIGH -> LOW
Serial.println("Motion stopped!");
delayEnabled = true; // enable delay
delayStartTime = millis(); // set start time
}
if (delayEnabled == true && (millis() - delayStartTime) >= DELAY_TIME_MS) {
Serial.println("Turning off / deactivating");
delayEnabled = false; // disable delay
// TODO: turn off alarm, light or deactivate a device ... here
}
}
假设设置了可重复触发模式。 该代码中的延迟时间设置为 30 秒。 这意味着延迟时间等于 30 秒加上根据传感器设置(通过时间延迟调节器)设定的 time_delay。
挑战自我
使用运动传感器完成以下项目之一:
-
进入房间时自动开灯,离开 30 秒后自动关灯。 提示: Refer to Arduino - Relay.
-
当有人接近您的贵重物品时,自动发出警报。 提示:请参考Arduino - Piezo Buzzer.
Function References
-
pinMode()
-
digitalRead()
-
Serial
The Best Arduino Starter Kit
- See the best Arduino kit for beginner
See Also
-
Arduino - Motion Sensor - LED
-
Arduino - Motion Sensor - Relay
-
Arduino - Motion Sensor - Piezo Buzzer
-
Arduino - Motion Sensor - Servo Motor
-
Arduino - Motion Sensor - MP3 Player
-
Arduino - Motion Sensor - LED Strip