mirror of
https://github.com/ImplFerris/esp32-book.git
synced 2025-09-24 14:31:13 +00:00
Burglar-alarm with PIR sensor and ESP32 with Rust
This commit is contained in:
parent
766bde78ad
commit
b7df78d947
@ -18,7 +18,7 @@
|
||||
- [Fading LED](./led/index.md)
|
||||
- [Code](./led/code.md)
|
||||
- [External LED](./led/external-led.md)
|
||||
- [Buzzinga](./buzzer/index.md)
|
||||
- [Buzzer](./buzzer/index.md)
|
||||
- [Circuit](./buzzer/circuit.md)
|
||||
- [Active Beep](./buzzer/active-beep.md)
|
||||
- [Play Songs](./buzzer/play-songs/index.md)
|
||||
@ -31,6 +31,11 @@
|
||||
- [Circuit](./ultrasonic/circuit.md)
|
||||
- [Code](./ultrasonic/code.md)
|
||||
- [Using Buzzer](./ultrasonic/using-buzzer.md)
|
||||
- [PIR Sensor](./pir-sensor/index.md)
|
||||
- [Adjustments](./pir-sensor/settings.md)
|
||||
- [Circuit](./pir-sensor/circuit.md)
|
||||
- [Motion Detection](./pir-sensor/code.md)
|
||||
- [Burglar Alarm](./pir-sensor/burglar-alarm.md)
|
||||
- [Servo Motor](./servo/index.md)
|
||||
- [PWM and Servo Position](./servo/pwm.md)
|
||||
- [Circuit](./servo/circuit.md)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Buzzinga
|
||||
# Buzzer
|
||||
|
||||
In this section, we will explore some fun activities using the `buzzer`. I chose the title "Buzzinga" just for fun (a nod to Sheldon's "Bazinga" in *The Big Bang Theory*); it's not a technical term.
|
||||
In this section, we will explore some fun activities using the `buzzer`.
|
||||
|
||||
- **Active or Passive Buzzer**
|
||||
- **Jumper Wires**:
|
||||
|
126
src/pir-sensor/burglar-alarm.md
Normal file
126
src/pir-sensor/burglar-alarm.md
Normal file
@ -0,0 +1,126 @@
|
||||
# Building a Simple Burglar Alarm with ESP32, PIR Sensor, and Rust
|
||||
|
||||
Let’s make a simple burglar alarm that activates the buzzer for a short time before turning it off. We also turn on the on-board LED, which is connected to GPIO2. Feel free to adjust it to suit your needs!
|
||||
|
||||
## Hardware requirements
|
||||
|
||||
- Active Buzzer
|
||||
- PIR Sensor
|
||||
- Jumper wires
|
||||
|
||||
## Circuit
|
||||
|
||||
The PIR sensor connection is the same as before (see [circuit](./circuit.md)). We connect the middle output pin of the sensor to GPIO 33.
|
||||
|
||||
### Buzzer Pin Connection:
|
||||
<table style="margin-bottom:20px">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ESP32 Pin</th>
|
||||
<th style="width: 250px; margin: 0 auto;">Wire</th>
|
||||
<th>Buzzer Pin</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>GPIO 18</td>
|
||||
<td style="text-align: center; vertical-align: middle; padding: 0;">
|
||||
<div class="wire blue" style="width: 200px; margin: 0 auto;">
|
||||
<div class="male-left"></div>
|
||||
<div class="male-right"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>Positive Pin</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GND</td>
|
||||
<td style="text-align: center; vertical-align: middle; padding: 0;">
|
||||
<div class="wire black" style="width: 200px; margin: 0 auto;">
|
||||
<div class="male-left"></div>
|
||||
<div class="male-right"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>Negative Pin</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<img style="display: block; margin: auto;" alt="HC-SR501" src="./images/esp32-pir-sensor-burglar-alarm.png"/>
|
||||
|
||||
|
||||
## Buzzer and LED Pins
|
||||
|
||||
We'll set up GPIO 18 as an Output pin with an initial Low state for the active buzzer. The onboard LED, connected to GPIO 2, will also be configured as an Output pin with an initial Low state.
|
||||
|
||||
```rust
|
||||
let mut buzzer_pin = Output::new(peripherals.GPIO18, Level::Low);
|
||||
let mut led = Output::new(peripherals.GPIO2, Level::Low);
|
||||
```
|
||||
|
||||
## The Logic
|
||||
|
||||
The logic is similar to the previous code. However, this time, instead of just printing a message when motion is detected (i.e., when the sensor pin is High), we'll turn the buzzer and LED on for a brief moment and then turn them off.
|
||||
|
||||
```rust
|
||||
loop {
|
||||
if sensor_pin.is_high() {
|
||||
buzzer_pin.set_high();
|
||||
led.set_high();
|
||||
delay.delay(100.millis());
|
||||
buzzer_pin.set_low();
|
||||
led.set_low();
|
||||
}
|
||||
delay.delay(100.millis());
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Clone the existing project
|
||||
You can clone (or refer) project I created and navigate to the `burglar-alarm` folder.
|
||||
|
||||
```sh
|
||||
git clone https://github.com/ImplFerris/esp32-projects
|
||||
cd esp32-projects/burglar-alarm
|
||||
```
|
||||
|
||||
|
||||
## The Full code
|
||||
|
||||
```rust
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::delay::Delay;
|
||||
use esp_hal::gpio::{Input, Level, Output, Pull};
|
||||
use esp_hal::prelude::*;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let peripherals = esp_hal::init({
|
||||
let mut config = esp_hal::Config::default();
|
||||
config.cpu_clock = CpuClock::max();
|
||||
config
|
||||
});
|
||||
|
||||
esp_println::logger::init_logger_from_env();
|
||||
|
||||
let sensor_pin = Input::new(peripherals.GPIO33, Pull::Down);
|
||||
|
||||
let mut buzzer_pin = Output::new(peripherals.GPIO18, Level::Low);
|
||||
let mut led = Output::new(peripherals.GPIO2, Level::Low);
|
||||
|
||||
let delay = Delay::new();
|
||||
loop {
|
||||
if sensor_pin.is_high() {
|
||||
buzzer_pin.set_high();
|
||||
led.set_high();
|
||||
delay.delay(100.millis());
|
||||
buzzer_pin.set_low();
|
||||
led.set_low();
|
||||
}
|
||||
delay.delay(100.millis());
|
||||
}
|
||||
}
|
||||
```
|
54
src/pir-sensor/circuit.md
Normal file
54
src/pir-sensor/circuit.md
Normal file
@ -0,0 +1,54 @@
|
||||
## HC-SR501 Pinout
|
||||
|
||||
The output pin is easy to spot since it's right in the middle.
|
||||
|
||||
If you're unsure which pin is Ground and which is VCC, you can remove the white dome to check. You can also identify it by looking for the pin next to the protection diode-that's the VCC pin.
|
||||
|
||||
|
||||
## Connecting PIR Sensor with ESP32
|
||||
|
||||
The sensor operates at 5V, but the ESP32 GPIO pins are 3.3V tolerant. The PIR sensor module outputs 3.3V when motion is detected, so it can be directly connected to the GPIO without any issues. Otherwise, you will need a voltage divider to reduce the voltage to 3.3V.
|
||||
|
||||
<table style="margin-bottom:20px">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ESP32 Pin</th>
|
||||
<th style="width: 250px; margin: 0 auto;">Wire</th>
|
||||
<th>PIR Sensor Pin</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>GPIO 33</td>
|
||||
<td style="text-align: center; vertical-align: middle; padding: 0;">
|
||||
<div class="wire yellow" style="width: 200px; margin: 0 auto;">
|
||||
<div class="male-left"></div>
|
||||
<div class="male-right"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>OUT (middle pin)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>5V</td>
|
||||
<td style="text-align: center; vertical-align: middle; padding: 0;">
|
||||
<div class="wire red" style="width: 200px; margin: 0 auto;">
|
||||
<div class="male-left"></div>
|
||||
<div class="male-right"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>VCC</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GND</td>
|
||||
<td style="text-align: center; vertical-align: middle; padding: 0;">
|
||||
<div class="wire black" style="width: 200px; margin: 0 auto;">
|
||||
<div class="male-left"></div>
|
||||
<div class="male-right"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>GND</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br/>
|
||||
<img style="display: block; margin: auto;" alt="HC-SR501" src="./images/esp32-pir-sensor-connection-circuit.png"/>
|
79
src/pir-sensor/code.md
Normal file
79
src/pir-sensor/code.md
Normal file
@ -0,0 +1,79 @@
|
||||
# Write Rust Code for Motion Detection Using a PIR Sensor and ESP32
|
||||
|
||||
Let's write a simple program that prints a message whenever motion is detected. This will help us fine-tune the PIR sensor settings and grasp some basic concepts. Once that's done, we'll build a complete burglar alarm simulation with a buzzer and an onboard LED (or an external LED, which you can adjust as needed) to make it more exciting.
|
||||
|
||||
|
||||
### Generate project using esp-generate
|
||||
|
||||
To create the project, use the `esp-generate` command. Run the following:
|
||||
|
||||
```sh
|
||||
esp-generate --chip esp32 pir-sensor
|
||||
```
|
||||
|
||||
This will open a screen asking you to select options. We dont need to select any options. Just save it by pressing "s" in the keyboard.
|
||||
|
||||
## Sensor Output Pin to ESP32's Input
|
||||
|
||||
We'll configure GPIO 33 as an input pin with an initial pull-down state. This pin is connected to the PIR sensor's output, which goes HIGH whenever motion is detected.
|
||||
|
||||
```rust
|
||||
let sensor_pin = Input::new(peripherals.GPIO33, Pull::Down);
|
||||
```
|
||||
|
||||
## The logic
|
||||
The idea is simple: we continuously check the sensor's output in a loop. When the sensor's output goes HIGH, we print the message "Motion detected" and add a short delay.
|
||||
|
||||
```rust
|
||||
loop {
|
||||
if sensor_pin.is_high() {
|
||||
println!("Motion detected");
|
||||
delay.delay(100.millis());
|
||||
}
|
||||
delay.delay(100.millis());
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Clone the existing project
|
||||
You can clone (or refer) project I created and navigate to the `pir-sensor` folder.
|
||||
|
||||
```sh
|
||||
git clone https://github.com/ImplFerris/esp32-projects
|
||||
cd esp32-projects/pir-sensor
|
||||
```
|
||||
|
||||
## The Full code
|
||||
|
||||
```rust
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::delay::Delay;
|
||||
use esp_hal::gpio::{Input, Pull};
|
||||
use esp_hal::prelude::*;
|
||||
use esp_println::println;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let peripherals = esp_hal::init({
|
||||
let mut config = esp_hal::Config::default();
|
||||
config.cpu_clock = CpuClock::max();
|
||||
config
|
||||
});
|
||||
|
||||
esp_println::logger::init_logger_from_env();
|
||||
|
||||
let sensor_pin = Input::new(peripherals.GPIO33, Pull::Down);
|
||||
|
||||
let delay = Delay::new();
|
||||
loop {
|
||||
if sensor_pin.is_high() {
|
||||
println!("Motion detected");
|
||||
delay.delay(100.millis());
|
||||
}
|
||||
delay.delay(100.millis());
|
||||
}
|
||||
}
|
||||
```
|
BIN
src/pir-sensor/images/esp32-pir-sensor-burglar-alarm.png
Normal file
BIN
src/pir-sensor/images/esp32-pir-sensor-burglar-alarm.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 124 KiB |
BIN
src/pir-sensor/images/esp32-pir-sensor-connection-circuit.png
Normal file
BIN
src/pir-sensor/images/esp32-pir-sensor-connection-circuit.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 102 KiB |
BIN
src/pir-sensor/images/hc-sr501-details.jpg
Normal file
BIN
src/pir-sensor/images/hc-sr501-details.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 120 KiB |
BIN
src/pir-sensor/images/hc-sr501-retrigger-setting-jumper.jpg
Normal file
BIN
src/pir-sensor/images/hc-sr501-retrigger-setting-jumper.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 127 KiB |
BIN
src/pir-sensor/images/pir-sensor-HC-SR501.jpg
Normal file
BIN
src/pir-sensor/images/pir-sensor-HC-SR501.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 69 KiB |
25
src/pir-sensor/index.md
Normal file
25
src/pir-sensor/index.md
Normal file
@ -0,0 +1,25 @@
|
||||
# PIR Sensor
|
||||
|
||||
Ever walked into a room and had the lights turn on automatically? That's probably a PIR sensor at work.
|
||||
|
||||
In earlier chapter, we used an [ultrasonic sensor](../ultrasonic/index.md) to check if a person or object was near the sensor. It works by sending ultrasonic waves and measuring the distance to an object. The PIR sensor, however, works differently; instead of measuring distance, it detects motion.
|
||||
|
||||
The PIR sensor is called "passive" Infrared because it does not emit any infrared radiation; instead, it only detects changes in infrared radiation from the environment. It senses heat emitted by people, animals, and other warm objects. When movement occurs within its detection area, the sensor picks up the change and sends a signal. This makes it useful for automatic lighting, burglar alarms, and other motion-detection systems.
|
||||
|
||||
## Meet the Hardware
|
||||
|
||||
We will use the **HC-SR501** PIR sensor module. It has an onboard pyroelectric sensor that helps to detect movement, and a dome-shaped Fresnel lens that helps to increase the range of detection. It can work with a power supply of 5V to 12V.
|
||||
|
||||
The PIR sensor module comes with three pins: one for power, one for output (middle pin), and one for ground. It's easy to use because it provides a simple output. By default, the signal stays LOW, when no motion is detected. But the moment someone moves within its range, the output jumps to HIGH, signaling motion detection.
|
||||
|
||||
<img style="display: block; margin: auto;width:400px" alt="HC-SR501" src="./images/pir-sensor-HC-SR501.jpg"/>
|
||||
|
||||
## Resources
|
||||
|
||||
The PIR sensor module is built around the BISS0001 controller. Here are some datasheets related to the BISS0001 controller.
|
||||
|
||||
- [https://cdn-learn.adafruit.com/assets/assets/000/010/133/original/BISS0001.pdf](https://cdn-learn.adafruit.com/assets/assets/000/010/133/original/BISS0001.pdf)
|
||||
- [http://www.sc-tech.cn/en/BISS0001.pdf](http://www.sc-tech.cn/en/BISS0001.pdf)
|
||||
|
||||
If you want to learn how PIR sensors work internally, you can check out this guide:
|
||||
[How PIRs Work](https://learn.adafruit.com/pir-passive-infrared-proximity-motion-sensor/how-pirs-work). We won't cover this in the book since it's beyond scope of this book. Our focus is simply on detecting motion and sending the signal to the ESP32.
|
39
src/pir-sensor/settings.md
Normal file
39
src/pir-sensor/settings.md
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
## Adjusting the PIR Sensor Settings
|
||||
|
||||
<img style="display: block; margin: auto;width:60vh;" alt="HC-SR501" src="./images/hc-sr501-details.jpg"/>
|
||||
<p>Image Credit: <a href="https://learn.adafruit.com/pir-passive-infrared-proximity-motion-sensor/overview">Adafruit</a></p>
|
||||
|
||||
|
||||
The PIR sensor module comes with two built-in potentiometers that allow you to fine-tune its behavior: Delay Time and Sensitivity. These small adjustment knobs let you control how the sensor responds to motion, making it more adaptable to different environments and applications.
|
||||
|
||||
### Delay Time (Output Duration)
|
||||
This setting determines how long the sensor’s output remains HIGH after detecting motion. A longer delay is useful for applications like automatic lighting, where you want the light to stay on for a while after movement is detected.
|
||||
|
||||
- **Turn clockwise** to increase the duration (up to ~200 seconds).
|
||||
- **Turn counterclockwise** to decrease the duration (down to ~5 seconds).
|
||||
|
||||
### Sensitivity (Detection Range)
|
||||
This setting controls how far the sensor can detect motion. Higher sensitivity allows the sensor to pick up movement from a greater distance, while lower sensitivity reduces the detection range to prevent false triggers in small areas.
|
||||
|
||||
- **Turn clockwise** to extend the range (up to ~7 meters).
|
||||
- **Turn counterclockwise** to shorten the range (down to ~3 meters).
|
||||
|
||||
**Note:**
|
||||
|
||||
To be frank, the code we're about to write is very simple. The most challenging part for me was figuring out the direction. I knew it was clockwise (and counterclockwise), but I wasn't sure if the sensor should point up or down. The key is to hold the sensor with the dome side facing up, and then follow the clockwise and counterclockwise instructions from there.
|
||||
|
||||
## Jumper Setting
|
||||
|
||||
Aside from the pot knobs, you've got jumper settings to tweak. They let you switch between two modes: Retriggering and Non-Retriggering.
|
||||
|
||||
<img style="display: block; margin: auto;width:60vh;" alt="HC-SR501" src="./images/hc-sr501-retrigger-setting-jumper.jpg"/>
|
||||
|
||||
### Retriggering Mode (H)
|
||||
In this mode, the output stays HIGH as long as motion is detected. If more motion happens before the timer ends, it resets. Perfect for situations like lights turning on when someone's in the room and staying on as long as there's movement.
|
||||
|
||||
### Non-Retriggering Mode (L)
|
||||
Here, the output stays HIGH once motion is detected but won't trigger again until the delay time is up. Perfect for things like counting people as they pass through a door, where you need each detection to be a separate event.
|
||||
|
||||
### How to Set the Jumper
|
||||
To switch modes, just move the jumper (the small black/yellow box - yes, you can remove it and place it between two pins) to the H pins for Retriggering or the L pins for Non-Retriggering
|
Loading…
x
Reference in New Issue
Block a user