Skip to main content

Motion-Activated Security System

PIR sensor triggers camera capture and sends email alerts with snapshot attachments.

Overview

Build a motion-activated security system that detects movement with a PIR sensor, captures a snapshot from an IP camera, and emails the image to you as an alert. An LED indicator provides local visual feedback when motion is detected. A 10-second debounce delay prevents repeated alerts from a single event.

Beginner
Difficulty
4
Nodes Used
~10 min
Setup Time
2 GPIOs
Pins Required

What You'll Need

Hardware

  • * Raspberry Pi (any model with GPIO)
  • * HC-SR501 PIR motion sensor
  • * LED + 220Ω resistor (indicator)
  • * IP camera with HTTP snapshot URL (e.g., ESP32-CAM, Wyze, Tapo)
  • * Jumper wires

Software / Accounts

  • * EdgeFlow installed on your Pi
  • * SMTP email credentials (Gmail, Outlook, etc.)
  • * IP camera accessible on your local network

Wiring Diagram

PIR Sensor (HC-SR501)

VCC → 5V (Pin 2)

OUT → GPIO17 (Pin 11)

GND → GND (Pin 6)

Set jumper to "H" mode (repeatable trigger). Adjust sensitivity potentiometer to taste.

LED Indicator

Anode (+) → 220Ω resistor → GPIO27 (Pin 13)

Cathode (-) → GND (Pin 14)

LED lights up when motion is detected. Use any standard LED color.

Importable Flow JSON

Copy this JSON and import it via Menu → Import in the EdgeFlow editor.

{
  "name": "Motion-Activated Security System",
  "nodes": [
    {
      "id": "pir_1",
      "type": "pir",
      "name": "PIR Motion Sensor",
      "pin": 17,
      "edge": "rising",
      "debounce": 200,
      "x": 120,
      "y": 200
    },
    {
      "id": "delay_debounce",
      "type": "delay",
      "name": "10s Debounce",
      "timeout": 10,
      "timeoutUnits": "seconds",
      "rateAction": "drop",
      "x": 320,
      "y": 200
    },
    {
      "id": "led_on",
      "type": "change",
      "name": "LED ON",
      "rules": [
        { "t": "set", "p": "payload", "to": 1 }
      ],
      "x": 320,
      "y": 100
    },
    {
      "id": "led_off_delay",
      "type": "delay",
      "name": "LED 3s Timer",
      "timeout": 3,
      "timeoutUnits": "seconds",
      "x": 500,
      "y": 100
    },
    {
      "id": "led_off",
      "type": "change",
      "name": "LED OFF",
      "rules": [
        { "t": "set", "p": "payload", "to": 0 }
      ],
      "x": 660,
      "y": 100
    },
    {
      "id": "gpio_led",
      "type": "gpio-out",
      "name": "LED Indicator",
      "pin": 27,
      "mode": "digital",
      "x": 840,
      "y": 100
    },
    {
      "id": "snapshot",
      "type": "http-request",
      "name": "Camera Snapshot",
      "method": "GET",
      "url": "http://192.168.1.100/capture",
      "returnType": "bin",
      "x": 520,
      "y": 200
    },
    {
      "id": "format_email",
      "type": "function",
      "name": "Format Email",
      "func": "msg.to = 'your-email@example.com';\nmsg.subject = 'Motion Detected - ' + new Date().toLocaleString();\nmsg.body = 'Motion was detected by the PIR sensor.\\nTimestamp: ' + new Date().toISOString();\nif (msg.payload) {\n  msg.attachments = [{ filename: 'snapshot.jpg', content: msg.payload }];\n}\nreturn msg;",
      "x": 720,
      "y": 200
    },
    {
      "id": "email_send",
      "type": "email",
      "name": "Send Email Alert",
      "smtp": "smtp.gmail.com",
      "port": 587,
      "secure": true,
      "user": "your-email@gmail.com",
      "password": "YOUR_APP_PASSWORD",
      "x": 920,
      "y": 200
    },
    {
      "id": "debug_1",
      "type": "debug",
      "name": "Motion Log",
      "x": 520,
      "y": 320
    }
  ],
  "connections": [
    { "from": "pir_1", "to": "delay_debounce" },
    { "from": "pir_1", "to": "led_on" },
    { "from": "led_on", "to": "gpio_led" },
    { "from": "led_on", "to": "led_off_delay" },
    { "from": "led_off_delay", "to": "led_off" },
    { "from": "led_off", "to": "gpio_led" },
    { "from": "delay_debounce", "to": "snapshot" },
    { "from": "delay_debounce", "to": "debug_1" },
    { "from": "snapshot", "to": "format_email" },
    { "from": "format_email", "to": "email_send" }
  ]
}

Step-by-Step Walkthrough

1

Wire the PIR Sensor and LED

Connect the HC-SR501 PIR sensor to 5V, GND, and GPIO17. Set the jumper on the PIR to "H" (repeatable trigger) mode. Wire an LED with a 220Ω resistor to GPIO27 as a visual motion indicator.

The PIR sensor needs about 30-60 seconds to warm up after first being powered on. Avoid pointing it at heat sources or windows to reduce false triggers.
2

Set Up Your IP Camera

Find the snapshot URL for your IP camera. Common formats:

ESP32-CAM:  http://192.168.1.100/capture
Tapo C200:  http://192.168.1.101/stream/snapshot.jpg
Generic:    http://CAMERA_IP/snapshot.cgi?user=admin&pwd=password

Double-click the "Camera Snapshot" node and set the URL to your camera's snapshot endpoint.

3

Configure Email SMTP

Double-click the "Send Email Alert" node and enter your SMTP settings. For Gmail, you need to create an App Password (not your regular password):

Provider Server Port
Gmail smtp.gmail.com 587
Outlook smtp.office365.com 587
Yahoo smtp.mail.yahoo.com 465
4

Deploy and Test

Click Deploy and wait 60 seconds for the PIR sensor to warm up. Walk in front of the sensor to trigger a detection. The LED should light up for 3 seconds, and you should receive an email with a camera snapshot within a few seconds.

Configuration Details

Parameter Value Description
PIR Edge Rising Triggers on motion start (LOW → HIGH)
PIR Debounce 200 ms Hardware debounce to ignore electrical noise
Alert Debounce 10 seconds Prevents duplicate alerts from sustained motion
LED Duration 3 seconds How long the indicator LED stays on
Camera Format Binary (JPEG) HTTP request returns raw image data for email attachment

Expected Output

The PIR node sends this message when motion is detected:

{
  "payload": 1,
  "pin": 17,
  "edge": "rising",
  "timestamp": 1707750123456,
  "_msgid": "f5e6d7c8"
}

After the HTTP request, the formatted email message looks like:

{
  "to": "your-email@example.com",
  "subject": "Motion Detected - 2/12/2026, 3:45:12 PM",
  "body": "Motion was detected by the PIR sensor.\nTimestamp: 2026-02-12T15:45:12.456Z",
  "attachments": [
    {
      "filename": "snapshot.jpg",
      "content": "<Buffer ff d8 ff e0 ... 42,319 bytes>"
    }
  ]
}

Troubleshooting

PIR sensor triggers constantly (false positives)
  • Reduce the sensitivity potentiometer on the PIR module
  • Avoid pointing the sensor at windows, heating vents, or fans
  • Increase the debounce delay node timeout to 30s
  • Ensure the sensor has a stable 5V power supply
Camera snapshot returns an error
  • Verify the camera IP address is correct and reachable from the Pi
  • Test the snapshot URL in a browser first
  • Check if the camera requires authentication
  • Ensure the HTTP Request node is set to return "Binary" data
Email fails to send
  • For Gmail: use an App Password, not your account password
  • Verify SMTP server and port are correct
  • Check the Pi has internet access
  • Look at the Debug panel for detailed SMTP error messages

Next Steps