Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions config/pir_guard.json5
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
// PIR Guard / Security Mode
// Run with: python -m run --config pir_guard
//
// connector options:
// "mock" → no hardware needed (default, safe for any machine)
// "serial" → Arduino via USB, set port to your device path
// "gpio" → Raspberry Pi / Jetson direct GPIO
// "zenoh" → network-distributed PIR publisher
version: "v1.0.3",
hertz: 0.5,
name: "pir_guard",
api_key: "${OM_API_KEY:-openmind_free}",
system_prompt_base: "You are a security guard robot. Your role is to monitor the environment for unexpected motion. When motion is detected by the PIR sensor, alert clearly and calmly. When there is no motion, remain on standby and stay quiet.",
system_governance: "Here are the laws that govern your actions. Do not violate these laws.\nFirst Law: A robot cannot harm a human or allow a human to come to harm.\nSecond Law: A robot must obey orders from humans, unless those orders conflict with the First Law.\nThird Law: A robot must protect itself, as long as that protection does not conflict with the First or Second Law.",
system_prompt_examples: "Here are some examples of interactions you might encounter:\n\n1. PIR sensor detects motion:\n Speak: 'Motion detected. Identifying presence.'\n\n2. No motion for a long time:\n Speak: 'All clear. Continuing to monitor.'",
agent_inputs: [
{
type: "PIRMotionInput",
config: {
// Change to "serial", "gpio", or "zenoh" for real hardware
connector: "mock",

// serial connector settings (connector="serial")
// port: "/dev/ttyUSB0", // Linux
// port: "COM3", // Windows
// port: "/dev/cu.usbmodem1101", // macOS
// baudrate: 9600,

// gpio connector settings (connector="gpio")
// gpio_pin: 17, // BCM GPIO17 = physical pin 11 on RPi

// zenoh connector settings (connector="zenoh")
// zenoh_topic: "om/sensors/pir",

// minimum seconds between motion alerts sent to LLM
// increase if robot speaks too frequently when sensor stays HIGH
cooldown: 5.0,
},
},
],
cortex_llm: {
type: "OpenAILLM",
config: {
agent_name: "Guard",
history_length: 5,
},
},
agent_actions: [
{
name: "speak",
llm_label: "speak",
connector: "elevenlabs_tts",
},
],
}
1 change: 1 addition & 0 deletions docs/developing/4_inputs.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ Here are a few examples for you to reuse and build on:
- [VLM_COCO_Local](https://github.com/openmind/OM1/blob/main/src/inputs/plugins/vlm_coco_local.py)
- [VLM_Vila](https://github.com/openmind/OM1/blob/main/src/inputs/plugins/vlm_vila.py)
- [Arduino GPS](https://github.com/openmind/OM1/blob/main/src/inputs/plugins/gps.py)
- [PIR Motion Sensor (HC-SR501)](https://github.com/openmind/OM1/blob/main/src/inputs/plugins/pir_motion.py)

Learn how to build a new input plugin [here](../developer_cookbook/input.md)
146 changes: 146 additions & 0 deletions docs/robotics/pir_hc_sr501.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
---
title: PIR Motion Sensor (HC-SR501)
description: "HC-SR501 Passive Infrared Motion Sensor"
icon: sensor
---

## Overview

The HC-SR501 is a Passive Infrared (PIR) sensor that detects motion by measuring changes in infrared radiation emitted by people and animals. It outputs a simple digital HIGH/LOW signal, making it an efficient and low-power trigger for robot guard and security modes.

Because the sensor consumes only ~1 mA in standby, it is ideal as a **wake-up trigger**: keep the PIR active continuously, then activate heavier subsystems (camera, VLM, LLM) only when motion is detected.

## Hardware

| Parameter | Value |
|-----------|-------|
| Supply voltage | 4.5 V – 20 V (typically 5 V) |
| Output voltage | 3.3 V HIGH / 0 V LOW |
| Detection range | Up to 7 m |
| Detection angle | ~120° cone |
| Trigger hold time | 0.3 s – ~200 s (adjustable via onboard potentiometer) |
| Current draw | ~1 mA standby |

The board has two potentiometers:
- **Sensitivity** — adjusts detection range (turn clockwise to increase)
- **Time delay** — adjusts how long OUT stays HIGH after detection

And a jumper for trigger mode:
- **H (repeatable)** — OUT stays HIGH as long as motion continues (recommended)
- **L (single)** — OUT pulses once per trigger event

## Connector Options

The `PIRMotionInput` plugin supports four hardware backends:

| Connector | Hardware | Use case |
|-----------|----------|----------|
| `serial` | Arduino / any USB microcontroller | Cross-platform, multi-sensor |
| `gpio` | Raspberry Pi / Jetson | Direct wiring, minimal hardware |
| `zenoh` | Any Zenoh-capable device | Distributed / multi-robot setups |
| `mock` | No hardware | Development and testing (default) |

## Wiring

### Arduino (serial connector)
```
HC-SR501 VCC → Arduino 5V
HC-SR501 GND → Arduino GND
HC-SR501 OUT → Arduino D2
```

Upload this sketch to the Arduino:
```cpp
const int PIR_PIN = 2;

void setup() {
Serial.begin(9600);
pinMode(PIR_PIN, INPUT);
}

void loop() {
Serial.println(digitalRead(PIR_PIN) ? "MOTION:1" : "MOTION:0");
delay(500);
}
```

### Raspberry Pi (gpio connector)
```
HC-SR501 VCC → RPi Pin 2 (5V)
HC-SR501 GND → RPi Pin 6 (GND)
HC-SR501 OUT → RPi Pin 11 (GPIO17, BCM)
```

> **Note:** HC-SR501 OUT is typically 3.3 V-safe, but verify your specific sensor's datasheet before connecting directly to a 3.3 V GPIO pin.

### Finding the Arduino on Linux
```bash
sudo dmesg | grep ttyUSB*
# or
sudo dmesg | grep ttyACM*
```

Read the data to verify the sensor is streaming:
```bash
screen /dev/ttyUSB0 9600
```

### Finding the Arduino on macOS
```bash
ls /dev/cu.*
```

It should appear as something like `/dev/cu.usbmodem1101`.

## Configuration

Add `PIRMotionInput` to your config's `agent_inputs`:
```json5
{
agent_inputs: [
{
type: "PIRMotionInput",
config: {
connector: "serial", // serial | gpio | zenoh | mock
port: "/dev/ttyUSB0", // serial only
baudrate: 9600, // serial only
gpio_pin: 17, // gpio only (BCM numbering)
zenoh_topic: "om/sensors/pir", // zenoh only
cooldown: 5.0, // seconds between LLM alerts
},
},
],
}
```

The `cooldown` parameter is important: HC-SR501 can hold its output HIGH for up to ~200 seconds depending on the time delay potentiometer setting. Without cooldown the LLM would receive hundreds of identical motion alerts. The default of 5.0 seconds is a safe starting point — increase it if your robot speaks too frequently.

## Running

A ready-to-use config is provided:
```bash
python -m run --config pir_guard
```

This runs the robot in security/guard mode using the mock connector by default. Change `connector` to `"serial"` or `"gpio"` for real hardware.

## Zenoh Distributed Setup

If the sensor is on a remote device (e.g. a Raspberry Pi on the robot body, while OM1 runs on a separate computer):
```python
import zenoh
import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.IN)

session = zenoh.open()
pub = session.declare_publisher("om/sensors/pir")

while True:
pub.put("1" if GPIO.input(17) else "0")
time.sleep(0.5)
```

Then set `connector: "zenoh"` in your OM1 config.
Loading
Loading