# 👁️ PIR-датчик движения AM312

AM312 — пассивный инфракрасный датчик (PIR): в отличие от радаров вроде
[HMMD-mmWave](../HMMD-mmWave), которые сами излучают сигнал и отражением обнаруживают даже
неподвижную цель (дыхание), AM312 ничего не излучает и видит только **движение** — изменение
теплового ИК-излучения в поле зрения. Неподвижный, пусть даже тёплый человек для него невидим.
Физика — в [THEORY.md](THEORY.md).

## 📋 Навигация

| Файл | Что внутри |
| :--- | :--- |
| [WIRING.md](WIRING.md) | Подключение, таблица пинов |
| [THEORY.md](THEORY.md) | Принцип PIR, отличие от радаров, ограничения |
| [Lesson.md](Lesson.md) | Методический план урока для учителя |
| [PREZ.md](PREZ.md) | Презентация модуля — тезисы для урока |

## 🛠 Состав компонента

- [`include/PirSensor.h`](include/PirSensor.h) — интерфейс класса драйвера.
- [`src/PirSensor.cpp`](src/PirSensor.cpp) — обработка прерывания, hold time, дребезг.
- [`src/main.cpp`](src/main.cpp) — тестовый стенд: серийная диагностика, LED/реле-индикация.
- [`tools/timeline_view.py`](tools/timeline_view.py) — визуализация таймлайна событий движения в реальном времени (см. ниже).

## 🚀 Сборка и прошивка (PlatformIO)

```bash
cd Components/PIR_sensor_AM312
pio run -t upload && pio device monitor
```

По умолчанию сигнальный пин — GPIO13, см. [WIRING.md](WIRING.md).

### Ожидаемый вывод

```
=== [PIR_sensor_AM312] Motion Detection Test ===
Hold time 2000 мс, debounce 50 мс
Прогрев датчика ~5000 мс — возможны ложные срабатывания, см. THEORY.md.
Не блокирует loop() — статус печатается сразу, прогрев только помечен в логе.
------------------------------------
[IDLE]   покой  предыдущее=0 мс прогрев
[MOTION] движение обнаружено
[IDLE]   покой  предыдущее=2150 мс
```

`прогрев` в конце строки означает, что с момента `begin()` прошло меньше `kWarmupMs` — в этот
период возможны ложные срабатывания, пока пироэлектрический элемент датчика стабилизируется
(см. [THEORY.md](THEORY.md)). Это не блокирует работу — просто предупреждение в логе.

## ⚙️ Настройки в коде

Заданы в конструкторе ([`main.cpp`](src/main.cpp): `PirSensor pir(kPirPin, kHoldTimeMs, kDebounceMs)`):
- `kHoldTimeMs` (по умолчанию 2000 мс) — сколько ждать без нового фронта на пине, прежде чем
  считать движение закончившимся (защита от дребезга сигнала на границе обнаружения).
- `kDebounceMs` (по умолчанию 50 мс) — минимальный интервал между засчитываемыми фронтами
  прерывания.
- `kWarmupMs` (по умолчанию 5000 мс) — информационный порог для метки "прогрев" в логе, не
  задерживает и не блокирует работу драйвера.

AM312 не имеет программной калибровки/настройки чувствительности — это простой аналоговый
датчик с фиксированным порогом, у него нет интерфейса для этого (см. THEORY.md).

## 🖥️ Наглядная визуализация (для демонстрации детям)

[`tools/timeline_view.py`](tools/timeline_view.py) рисует ленту времени: горизонтальная шкала,
закрашенные участки — периоды, когда датчик считал, что перед ним есть движение. Хорошо
показывает hold time (почему полоса не гаснет сразу после остановки) и общий ритм срабатываний.

```bash
cd Components/PIR_sensor_AM312/tools
pip install -r requirements.txt
python3 timeline_view.py /dev/ttyUSB0   # порт как в pio device monitor
```

Подробнее про виртуальное окружение (venv/uv) — [`../../PYTHON_TOOLS.md`](../../../PYTHON_TOOLS.md).

## 🔧 Устранение неисправностей

- **Постоянно `[IDLE]`, даже при явном движении** — проверьте, что OUT датчика идёт на GPIO13 (или
  ваш выбранный пин), питание 3.3В (не 5В) — см. [WIRING.md](WIRING.md).
- **Статус мигает туда-сюда очень часто** — увеличьте `kHoldTimeMs`, датчик реагирует на
  посторонние источники движения (сквозняк, работающий вентилятор) — см. THEORY.md, раздел про
  ограничения.
- **Ложные срабатывания в первые секунды после включения** — ожидаемо, см. `прогрев` в логе выше
  и раздел про warmup в THEORY.md.
