# 📡 Теория: миллиметровый радар присутствия HMMD

## 1. Принцип работы: радар, а не тепловизор

PIR-датчик (см. [PIR_sensor_AM312](../AM312)) — пассивный: он ничего не излучает, а
только пассивно ловит изменение инфракрасного (теплового) излучения в поле зрения. Из-за этого
он видит **только движение** — неподвижный, пусть даже тёплый человек, для него невидим.

HMMD — активный радар: сам излучает электромагнитную волну в диапазоне **24–24.25 ГГц**
(миллиметровый диапазон, mmWave) и анализирует отражённый от объектов сигнал. Определение цели
основано на **эффекте Доплера**: если отражающая поверхность движется относительно радара
(включая микроскопические колебания грудной клетки при дыхании), частота отражённой волны
чуть сдвигается относительно излучённой — именно этот сдвиг радар и детектирует, отличая
"живую", хоть бы и почти неподвижную цель, от статичной обстановки комнаты (мебель, стены).
Это принципиально другой физический механизм, чем у PIR, и именно поэтому радар способен
замечать сидящего неподвижно человека, а PIR — нет.

## 2. Технические характеристики

Модуль HMMD построен на чипе **S3KM1110** (по данным официального магазина Waveshare) и использует
технологию **FMCW** (Frequency Modulated Continuous Wave — непрерывная волна с частотной
модуляцией): вместо одиночных импульсов радар постоянно излучает сигнал с плавно меняющейся
частотой, что позволяет одновременно измерять и скорость (через доплеровский сдвиг), и
расстояние до цели (через сравнение фазы/частоты излучённого и принятого сигнала в момент приёма).

| Параметр | Значение | Источник |
| :--- | :--- | :--- |
| Частота | 24–24.25 ГГц (полоса 0.25 ГГц) | pishop.us/Waveshare |
| Дальность (настенный монтаж) | до 10 м — движение, до 6 м — микродвижения | pishop.us/Waveshare |
| Дальность (потолочный монтаж) | до 5 м — движение, до 4 м — микродвижения | pishop.us/Waveshare |
| Угол обзора | ±60° | pishop.us/Waveshare |
| Питание | 3.3В (типовое) | pishop.us/Waveshare |
| UART | 115200 бод (по умолчанию) | pishop.us/Waveshare |
| Разрешение по дальности | ~0.7 м, точность ~0.15 м (цель в движении, до 10 м) | pishop.us/Waveshare |
| Цикл обновления данных | ~100 мс | pishop.us/Waveshare |

Эти цифры относятся к общей линейке модулей на чипе S3KM1110 (в объявлениях Waveshare этот же
чип фигурирует и под названием HMMD, и под названием S3KM1110) — взяты из карточки товара
поставщика, не из официального PDF-даташита (тот на момент написания недоступен для скачивания
в этом окружении).

## 3. Протокол — что подтверждено, а что нет

Это важный раздел: **предыдущая версия этого компонента использовала HEX-команды настройки вида
`55 5A ...`, которые не подтверждены ни одним независимым источником** и, скорее всего, были
придуманы при первом черновом написании кода, а не взяты из документации. Официальная wiki
Waveshare (`waveshare.com/wiki/HMMD_mmWave_Sensor`) на момент проверки недоступна напрямую из
этого окружения (сервер отвечает 403 Forbidden ботам), а по независимым отзывам (обсуждение в
репозитории проекта Tasmota, где мейнтейнер прямо сравнивал протокол HMMD с семейством LD2410)
сама эта wiki признана **неполной** — например, без описания «входа в режим команд».

Независимый рабочий пример (electroniclinic.com, ESP32 + HMMD) показывает **другой** формат
кадра — бинарный, в стиле семейства радаров **Hi-Link LD2410**: заголовок `FD FC FB FA`, хвост
`04 03 02 01`. При этом тот же источник и другие примеры кода параллельно показывают, что датчик
также способен выводить простые **текстовые ASCII-строки вида `"Range [N]"`** — именно такой
формат парсит текущий драйвер.

**Прямого подтверждения, какой из двух форматов (ASCII или бинарный) выдаёт именно ваш
экземпляр модуля "из коробки", без сторонних команд настройки, на момент написания этого
компонента нет.** Поэтому:

- [`HmmdRadar::begin()`](src/HmmdRadar.cpp#L14-L20) **не отправляет никаких HEX-команд
  настройки** — они не подтверждены, могли не делать ничего полезного на реальном железе, и их
  удаление не может ничего сломать (датчик по спецификации должен сам начинать выдавать данные
  после подачи питания).
- [`HmmdRadar::update()`](src/HmmdRadar.cpp#L22-L55) параллельно пытается разобрать оба формата:
  [`tryParseAsciiLine()`](src/HmmdRadar.cpp#L57-L77) ищет строку `"Range"`,
  [`tryParseBinaryFrame()`](src/HmmdRadar.cpp#L79-L105) ищет байтовые границы `FD FC FB FA ... 04
  03 02 01`. Для бинарного формата драйвер **честно фиксирует только сам факт валидного кадра**
  (`FrameFormat::Binary`), не пытаясь декодировать точное смещение поля дистанции внутри —
  чтобы узнать реальное смещение, нужен доступ к официальному протоколу или ручной разбор дампа.
- В [`main.cpp`](src/main.cpp) есть режим сырого HEX-дампа (команда `r` в Serial Monitor) — он
  печатает каждый байт, пришедший от радара, как есть, без парсинга. Это единственный надёжный
  способ на практике увидеть, что реально шлёт конкретный физический экземпляр датчика.

### Как проверить протокол на реальном железе

1. Подключить датчик по [WIRING.md](WIRING.md), прошить, открыть Serial Monitor.
2. Отправить `r` — включить сырой дамп.
3. Посмотреть на вывод:
   - Если видно читаемый текст ASCII (буквы, "Range", цифры) — подтверждён текстовый протокол,
     всё уже работает, `[TARGET]`/`[EMPTY]` в обычном режиме будут показывать `формат=ASCII`.
   - Если видно повторяющиеся байты `FD FC FB FA` в начале "пачек" — подтверждён бинарный
     LD2410-подобный протокол; в обычном режиме будет `формат=BINARY`, но дистанция при этом
     **не будет заполняться** (только факт присутствия), пока кто-то не разберёт точное смещение
     байта дистанции внутри payload вручную по дампу и не допишет декодирование в
     `tryParseBinaryFrame()`.

## 4. Логика удержания статуса (hold time)

Реальный сигнал радара немного "дрожит" на границе зоны обнаружения — цель может на долю
секунды пропасть из отчёта и снова появиться, хотя физически человек никуда не уходил. Наивная
логика "нет данных в этом кадре → сразу гасим статус" даёт заметное мерцание индикации. Поэтому
драйвер использует **hold time** ([`HmmdRadar::update()`](src/HmmdRadar.cpp#L51-L54),
по умолчанию 2000 мс, задаётся в конструкторе) — статус "цель обнаружена" гаснет только после
`holdTimeMs` миллисекунд *подряд* без единого валидного показания, а не при первом же пропуске.

## 5. Ограничения технологии

- mmWave-радар не проникает через металл — металлические стены/двери полностью экранируют сигнал.
- Движение постороннего объекта в зоне обзора (например, работающий вентилятор, штора на
  сквозняке) может давать ложные срабатывания — это плата за высокую чувствительность к любому
  движению, включая микроскопическое.
- Возможны взаимные помехи при работе нескольких radar-модулей близко друг к другу на той же
  полосе частот.

## 6. Почему нет расчёта дБ/точной дальности "из коробки"

В отличие от [INMP441](../../Sound/INMP441)/[ICS43434](../../Sound/ICS43434), где сырой
АЦП-сигнал напрямую доступен коду ESP32, у HMMD вся физика (доплеровский сдвиг, FMCW-обработка,
вычисление дальности) происходит **внутри самого чипа радара** — ESP32 получает уже готовый
результат по UART, а не сырые данные для собственной обработки. Это упрощает код на
микроконтроллере, но и ограничивает то, что можно "увидеть" программно — на этом уровне нет
доступа к самому отражённому сигналу, только к финальному выводу датчика.
