Гайд по сборке простого Wi-Fi-радара. DIY или Сделай сам.. DIY или Сделай сам. python.. DIY или Сделай сам. python. raspberry pi.. DIY или Сделай сам. python. raspberry pi. ruvds_перевод.. DIY или Сделай сам. python. raspberry pi. ruvds_перевод. wifi-радар.. DIY или Сделай сам. python. raspberry pi. ruvds_перевод. wifi-радар. Блог компании RUVDS.com.. DIY или Сделай сам. python. raspberry pi. ruvds_перевод. wifi-радар. Блог компании RUVDS.com. Любительская радиосвязь.. DIY или Сделай сам. python. raspberry pi. ruvds_перевод. wifi-радар. Блог компании RUVDS.com. Любительская радиосвязь. Программирование.. DIY или Сделай сам. python. raspberry pi. ruvds_перевод. wifi-радар. Блог компании RUVDS.com. Любительская радиосвязь. Программирование. Программирование микроконтроллеров.. DIY или Сделай сам. python. raspberry pi. ruvds_перевод. wifi-радар. Блог компании RUVDS.com. Любительская радиосвязь. Программирование. Программирование микроконтроллеров. радиолокация.. DIY или Сделай сам. python. raspberry pi. ruvds_перевод. wifi-радар. Блог компании RUVDS.com. Любительская радиосвязь. Программирование. Программирование микроконтроллеров. радиолокация. радиосвязь.
Гайд по сборке простого Wi-Fi-радара - 1

Подробное руководство по сборке радара для мониторинга присутствия в помещении человека и даже просто его дыхания.

Общий механизм выглядит так: ESP32-S3 измеряет параметры канала Wi-Fi 100 раз/сек, а Raspberry Pi их анализирует, в реальном времени выводя результат в браузере. Эта система обнаруживает абсолютно неподвижно сидящего человека по одному только движению его грудной клетки во время дыхания — без каких-либо камер, датчиков PIR или носимых устройств.

Содержание

1. Что умеет система

Движение

Регистрирует ходьбу, жестикулирование, приседание. При движении всплеск сигнала на ~28 дБ выше фонового шума — такое пропустить невозможно.

Присутствие

Отличает пустую комнату от той, где неподвижно сидит человек. Это уже сложный процесс, на котором ИК-датчики движения (PIR) постоянно ошибаются.

Частота дыхания

От 8 до 36 вдохов/мин. Точность проверена по эталону и составляет погрешность в рамках 0,1 вдоха/мин.

Сканирование сквозь стены

Сигнал с частотой 2,4 ГГц  проходит сквозь гипсокартон, дерево и стекло. Кирпич и бетон его сильно ослабляют, а фольгированная изоляция полностью блокирует.

Классы активности

Пусто / неподвижно / едва заметно / активно / интенсивно.

Данные окружающей среды

Измерение температуры, влажности, давления и качества воздуха (при подключении дополнительных датчиков).

Отчёт о сне

Регистрирует время в постели, неподвижность или беспокойность во сне, его нарушения, частоту дыхания в течение ночи.

2. Чего она не умеет

Этот раздел важнее списка возможностей, так как в большинстве тех заявлений о технологии Wi-Fi-sensing, которые можно встретить в сети, описываются совсем другие приборы.

Распространённые заявления

Что имеем в данном случае

Увидеть силуэт или скелет человека

С помощью Wi-Fi это нереально. Ширина полосы 20 МГц даёт разрешение по дальности c / 2B = 7,5 метров, что превышает размер большинства комнат. То есть информации о таких деталях объекта в сигнале просто нет. В известных демо-роликах MIT (RF-Pose, RF-Capture, WiTrack) используются специально созданные FMCW-радары с полосой частот в несколько ГГц и антенной решеткой, а не Wi-Fi.

Определить местоположение человека в комнате

Один передатчик и один приёмник измеряют только один путь сигнала. То есть вы узнаёте о том, что что-то изменилось, а не где оно изменилось. Для определения местоположения требуется как минимум 3 отдельных узла.

Подсчитать людей

Два человека вызывают больше возмущений в канале, чем один, но не настолько, чтобы можно было надёжно их посчитать.

Определить неподвижного человека, который задерживает дыхание

Измерять нечего. Простая физика, а не отсутствие фичи.

Идентифицировать человека

Невозможно

Фиксировать фазы сна (REM / глубокий / поверхностный)

Фазы сна определяются по активности мозга и глаз, а этой информации в сигнале нет. Этот прибор детектирует неподвижность, оставляя её интерпретацию вам.

К тому же, это не медицинский прибор. Это инструмент для спальни на базе микроконтроллера за $5.

3. Принцип работы

Общее описание:

Wi-Fi-сигнал приходит на приёмник сразу несколькими путями — как напрямую, так и в виде отражений от стен, мебели и людей. Все эти копии сигнала накладываются друг на друга с разными задержками, в результате чего некоторые частоты усиливаются, а некоторые друг друга гасят. Такая картина взаимодействия частот называется информацией о состоянии канала (Channel State Information, CSI), и её могут сообщать большинство микросхем Wi-Fi. Поместите что-либо в комнату, и длина пути сигнала изменится. Тело человека состоит преимущественно из воды и хорошо отражает волны на частоте 2,4 ГГц, что и делает людей видимыми. Длина волны на 2,4 ГГц составляет 12,5 см, так что смещение грудной клетки в диапазоне 6 мм при дыхании изменяет путь сигнала достаточно, чтобы это можно было измерить.

Путь данных

Гайд по сборке простого Wi-Fi-радара - 2

Поскольку мы сканируем пространство между роутером и ESP32, эти устройства нужно расположить в противоположных частях комнаты так, чтобы человек находился между ними.

Необходимость генерировать трафик

CSI существует только в момент получения пакетов. Сам по себе пустой канал не генерирует никаких данных, какое бы качественное оборудование вы ни использовали.

Подход

Частота получения CSI

Пассивное прослушивание фоновых сигналов Wi-Fi

~1 Гц, нерегулярно

ESP32 отправляет данные и фиксирует CSI из ответов роутера (ACK-пакетов)

~1 Гц (не работает)

Pi отправляет UDP-пакеты на ESP32

1:1, вплоть до 200 Гц

В данном проекте использован конкретно третий вариант, в связи с чем плату ESP32 необходимо полноценно подключать к Wi-Fi-сети. Благодаря этому, частота опроса задаётся программно, а не определяется случайно, и замеры происходят через равные промежутки времени, что нам и нужно для точного анализа дыхания.

Роль Pi

Гайд по сборке простого Wi-Fi-радара - 3

Две важные детали, от которых зависит, будет ли вообще работать эта схема:

  • Оба частотных диапазона представляют доплеровские частоты, а не демонстрируют скорость движения человека. Отражатель, движущийся со скоростью v, сдвигает сигнал на величину v / длина волны. Таким образом, ходьба со скоростью 1 м/с ведёт к появлению всплеска в районе 8 Гц — но никак не на частоте шагов. Дыхание же остаётся в пределах всего 0,13—0,7 Гц, и это единственная причина, почему его удаётся разделить с движением.

  • Все показания измеряются в дБ относительно собственного шума приёмника, поэтому для пустой комнаты они всегда будут равны 0 дБ — в любом помещении, на любом расстоянии и при любой мощности передатчика. Здесь нет этапа калибровки или заранее измеренного эталона, который мог бы со временем сбиваться. Собственный шум прибора определяется путём разложения ковариационной матрицы поднесущих частот. Суть в том, что внутри радиомодуля шум на каждой из этих частот является независимым в то время, как происходящие в комнате действия вызывают синхронное изменение всех поднесущих сразу.

4. Что нужно купить

Минимальная конфигурация (регистрация движения, присутствия, дыхания).

#

Компонент

Примечание

1

ESP32-S3-WROOM-1, N16R8

Датчик. По возможности берите именно такой. Главное, ознакомьтесь с предупреждением по распиновке в разделе «Подключение». Проще всего использовать отладочную плату с мостом USB-UART (CP2102) (CP2102).

1

Raspberry Pi 4

Вполне хватит версии с 2 ГБ памяти, плюс задействуется всего ~20% мощности одного ядра. Если же вы будете подключаться только через USB, то вполне подойдёт любой ПК под управлением Linux.

1

USB-кабель для передачи данных

Micro-USB или USB-C — в зависимости от разъёма на плате. Кабели только для зарядки здесь не подойдут — с ними плата просто не появится в списке подключенных устройств.

1

Любой Wi-Fi-роутер с частотой 2,4 ГГц

У вас наверняка такой есть. Версии на 5 ГГц не подойдут, так как ESP32-S3 эту частоту не видит.

Вот и весь список покупок. Если малинка у вас уже есть, то общая стоимость практически сводится к цене ESP32.

По желанию: беспроводное подключение (установка узла в любом месте)

#

Компонент

Примечание

2

nRF24L01+ PA/LNA

Один для Raspberry Pi, один для ESP32. Один модуль — это лишь половина канала связи. Необходимы развязывающие конденсаторы — см. раздел «Питание».

2

Адаптер для nRF24 с регулятором AMS1117

Однозначно лучше голого модуля. Этот адаптер исключит большинство проблем с питанием.

2

CC1101 433 MHz (альтернатива)

Работает вне диапазона Wi-Fi, поэтому не может создавать помехи измерениям на 2,4 ГГц. На этом программная часть полностью готова, но сборка упирается в согласование антенн. Здесь потребуются согласованные антенны на 433 МГц.

По желанию: мониторинг окружающей среды

#

Компонент

Примечание

1

BMP280 (или BME280)

Определение давления и температуры по данным SPI. Лучший термометр из трех.

1

DHT22 / AM2302

Влажность и температура. Берите 3-пиновый модуль сопряжения, на котором уже есть подтягивающий резистор.

1

Датчик газа MQ135 

Качество воздуха. Датчик аналоговый, поэтому обязательно ознакомьтесь с предупреждением о делителе напряжения в разделе «Подключение» ниже.

2

Резисторы на 10 kΩ

Делитель напряжения для MQ135, если вы питаете его от 5 В.

Также пригодятся: макетная плата, соединительные провода Dupont и отдельный от Pi источник питания на 5 В, если вы планируете добавить MQ135 (его нагревательный элемент непрерывно потребляет ток ~150 мА).

5. Необходимое ПО

Для Pi

Зачем

Raspberry Pi OS / любой дистрибутив Linux на базе Debian

Проект разработан на Debian 13 (Trixie) с помощью Python 3.13.

python3, python3-venv, python3-pip

Debian блокирует прямую установку пакетов в системный Python (PEP 668) через pip, поэтому нужно виртуальное окружение (virtualenv).

numpy, scipy

Нужны для цифровой обработки сигналов (DSP). Можете установить через apt, чтобы использовать в дальнейшем, либо поручить pip скачать их самому.

git

Для клонирования этого репозитория.

Веб-браузер

Для запуска дашборда не нужны ни сборка, ни какие-либо зависимости.

PlatformIO (только для самостоятельной сборки прошивки)

Устанавливается командой pip install platformio. Можете полностью это пропустить, скачав готовый бинарник.

Активный SPI (только для радиомодулей)

sudo raspi-config → Interface Options → SPI

Установка пакетов ОС:

sudo apt update
sudo apt install -y git python3-venv python3-pip python3-numpy python3-scipy

6. Подключение

Простейший вариант сборки с одним кабелем

Raspberry Pi 4  ──── USB-кабель ────  макетка ESP32-S3 

Собственно, и всё. По кабелю передаётся питание и поток данных CSI. Ниже перечислены возможные дополнительные радиомодули и датчики.

Прочтите, прежде чем подключать что-либо к ESP32

Модуль N16R8 оснащён 16 МБ флэш-памяти Quad SPI и 8 МБ Octal PSRAM. При этом Octal PSRAM занимает выводы (GPIO) с 33 по 37. Если подключить периферию к неправильному выводу, плата просто не будет загружаться без какой-либо информативной ошибки. Именно так чаще всего этот модуль превращают в кирпич.

Выводы

Назначение

Комментарий

GPIO 26—32

Внутренняя флэш-память для SPI

НЕ ИСПОЛЬЗОВАТЬ

GPIO 33—37

Octal PSRAM (на N16R8)

НЕ ИСПОЛЬЗОВАТЬ

GPIO 0, 3, 45, 46

Выбор режима загрузки

Лучше избегать

GPIO 19, 20

Аппаратный USB, линии D-/D+

Лучше избегать

GPIO 43, 44

Консоль UART0, уже используется

Лучше избегать

1, 2, 4—18, 21, 38—42, 47, 48

Безопасны

Что происходит на каждой шине

Гайд по сборке простого Wi-Fi-радара - 4

На одной шине SPI висит три устройства, каждое из которых имеет свою линию для выбора микросхемы. Датчик DHT22 работает по собственному однопроводному протоколу, а MQ135 является аналоговым.

Общая распиновка ESP32-S3

GPIO

Подключается к

4

MQ135 AO — через делитель, подробнее ниже

9

nRF24 IRQ

10

nRF24 CSN

11

SPI MOSI — общий: nRF24 + CC1101 + BMP280

12

SPI SCK — общий

13

SPI MISO — общий

14

nRF24 CE (выбор режима работы, а не микросхемы)

15

BMP280 CSB / CS

16

DHT22 DATA

17

CC1101 GDO2

18

CC1101 GDO0

21

CC1101 CSN

Сторона Raspberry Pi 4 (только при добавлении радиомодулей)

Общая шина SPI0 — подключается к обоим модулям:

Сигнал

BCM

Физический контакт

SCLK

11

23

MOSI

10

19

MISO

9

21

nRF24L01+ → /dev/spidev0.0:

Контакт модуля

BCM

Физический контакт

Примечание

GND

20

VCC

17

Строго 3,3 В; 5 В модуль не выдержит.

CE

25

22

Контакт выбора режима, а не микросхемы.

CSN

8

24

CE0

IRQ

24

18

Подключение не обязательно, но желательно.

CC1101 → /dev/spidev0.1:

Контакт модуля

BCM

Физический контакт

GND

9

VCC

1 (строго 3,3 В; 5 В модуль не выдержит).

CSN / SS

7

26 (CE1)

GDO0

23

16

GDO2

27

13

Расположение контактов на модулях CC1101 зависит от конкретной платы. Существует как минимум три популярных варианта разводки, и позиции пинов на них отличаются. Ориентируйтесь только по маркировкам на самой плате, а не по очерёдности выводов.

Датчики состояния окружающей среды (на ESP32)

BMP280 (SPI — использует общую шину и требует только собственной линии выбора микросхемы):

Контакт модуля

ESP32-S3

VCC

3V3

GND

GND

SCL / SCK

GPIO12

SDA / SDI / MOSI

GPIO11

SDO / MISO

GPIO13

CSB / CS

GPIO15

В режиме SPI линия SDA работает как вход, а SDO — как выход. То есть здесь не тот механизм, который предполагают маркировки для интерфейса I2C. Так что, если считать ID чипа не удаётся, первым делом поменяйте эти два провода местами.

Подключение DHT22 — VCC→3V3, DATA→GPIO16, GND→GND. Если у вас голый 4-контактный датчик, то потребуется добавить подтягивающий резистор на 10 kΩ между линиями DATA и 3V3; на 3-контактных модулях он уже присутствует.

Подключение MQ135 — VCC→5V, GND→GND, AO→GPIO4 через делитель напряжения:

   MQ135 AO ────[ 10k ]────┬────[ 10k ]──── GND
                           │
                           └──────► ESP32 GPIO4   (2.5 V max)

Нагреватель рассчитан на 5 В, а питаемый от 5 В контакт AO может выдавать напряжение до 5 В, что сожжёт АЦП ESP32, рассчитанный на 3,3 В. Здесь сгодится любая пара одинаковых резисторов — важно только соотношение их сопротивлений.

Альтернатива без резисторов: запитайте модуль от 3,3 В и подключите контакт AO напрямую (напряжение на нём физически не сможет превысить уровень питания датчика), а затем один раз укажите плате следующую настройку:

python tools/node.py mq135 supply 3v3

Выбор GPIO 4 не случаен: это должен быть один из выводов между GPIO 1 и 10, которые относятся к первому блоку АЦП (ADC1). Второй блок — ADC2 (выводы GPIO 11—20) — физически невозможно использовать во время работы Wi-Fi, так как радиомодуль полностью забирает этот преобразователь под свои нужды. Поскольку работа Wi-Fi — это главная цель данного проекта, использование блоков ADC2 исключено в принципе.

Питание — слабые места этой конфигурации

  • Самый проблемный элемент — это модуль nRF24L01+ PA/LNA. В моменты всплесков на мощности +20 дБм скачки тока здесь достигают 115 мА, и шина питания 3,3 В малинки просто с ними не справляется. Симптом этой проблемы очень характерный: прибор успевает передать несколько пакетов, а затем замолкает. Чтобы решить проблему, припаяйте электролитический конденсатор на 10—100 мкФ вместе с керамическим на 100 нФ прямо к контактам VCC и GND радиомодуля — именно на плате модуля, а не на шине макетной платы. А ещё лучше — запитайте его от отдельного стабилизатора AMS1117-3.3, подключённого к 5 В.

  • Подключайте антенны до включения питания. Передача сигнала в открытый порт может привести к повреждению усилителя.

  • Подбирайте антенну для CC1101 строго под его частотный диапазон. Антенны на 433 и 868 МГц не взаимозаменяемы, и со стороны это их различие выглядит так, будто сгорел радиомодуль.

  • Нагреватель MQ135 непрерывно потребляет ток около 150 мА. Если после его добавления ESP32 начинает уходить в перезагрузку из-за просадки питания, либо частота опроса CSI становится нестабильной — организуйте для датчика отдельное питание 5 В с общей землёй.

Вся логика процесса, вместе с пятью багами nRF24, которые пришлось исправлять для обеспечения надёжной связи, описана в разделе 4 файла PROJECT.txt.

7. Поэтапная сборка

Шаг 1 — скачайте код

git clone https://github.com/The-Masked-Bear/wifisense-pi.git
cd wifisense-pi

Шаг 2 — настройте окружение Python

Флаг --system-site-packages позволяет повторно использовать установленные через apt пакеты numpy и scipy, исключая необходимость их долгой компиляции на Pi.

python3 -m venv --system-site-packages .venv
./.venv/bin/pip install -r requirements.txt

Шаг 3 — протестируйте без подключения устройств

Синтетический канал связи — это не просто рандомная имитация, а полноценный симулятор, основанный на законах физики. Он запускает реальную цепочку детекторов, поэтому веб-панель ведёт себя точно так же, как и при подключении настоящего железа. Выполните этот тест в первую очередь. Так вы проверите корректность установки ПО до того, как начнёте разбираться, что и куда подключать.

cd pi
../.venv/bin/python -m wifisense --link synthetic

Откройте http://localhost:8080. Вы должны увидеть бегущий график “водопад” и изменение статусов. Остановить визуализацию можно комбинацией Ctrl-C.

Шаг 4 — прошейте ESP32

Скачайте готовый бинарник, или скомпилируйте его сами:

pip install platformio
cd firmware
pio run -t upload --upload-port /dev/ttyUSB0

Не обнаруживается подключение через USB? Выполните ls /dev/ttyUSB* и lsusb | grep -i "silicon labs". Если ничего не появится, сначала попробуйте использовать другой USB-кабель.

Шаг 5 — укажите узлу, к какому WiFi подключаться

Нужна сеть строго на 2,4 ГГц. Учётные данные сохраняются во флэш-памяти ESP32 и при отключении питания не стираются. Так что это разовый шаг, который не требует повторной компиляции.

cd pi
../.venv/bin/python tools/node.py wifi "YourSSID" "YourPassword"
../.venv/bin/python tools/node.py info      # Ищите assoc=yes и IP.

При открытии последовательного порта плата перезагружается, поэтому в течение нескольких первых секунд она будет недоступна. Скрипт tools/node.py дожидается её готовности, но при прямом подключении через терминал такого автоматического ожидания не будет.

Шаг 6 — полноценный запуск

cd pi
cp config.example.json config.json        # Не обязательно; вполне сгодятся и базовые установки.
../.venv/bin/python -m wifisense --link serial

Шаг 7 — правильное расположение устройств

Это самый важный этап:

Роутер ────────────  Человек ────────────  Узел ESP32

Расстояние между ними от 2 до 8 метров. Узел и роутер должны находиться в противоположных концах области, которую вы планируете сканировать.          

Проверьте показания RSSI в дашборде: пригодный диапазон от -40 до -60 dBm.

Шаг 8 — Автозапуск при загрузке

./install.sh              # Только сервер.
./install.sh --kiosk      # Плюс полноэкранный браузер на дисплее Pi.
./install.sh --uninstall  # Удаление.

8. Запуск

systemctl status wifisense       # Проверка работоспособности системы.
journalctl -u wifisense -f       # Логи в реальном времени.
sudo systemctl restart wifisense

URL-адрес

Что отображает

http://<pi-address>:8080

Дашборд в реальном времени

http://<pi-address>:8080/history

Историю + отчёт о сне

Запуск вручную (сначала остановите службу):

cd pi
../.venv/bin/python -m wifisense --link serial      # USB-кабель.
../.venv/bin/python -m wifisense --link synthetic   # Без подключения оборудования.
../.venv/bin/python -m wifisense --link nrf24       # Радиомодуль на 2,4 ГГц.

9. Показания дашборда

Панель

О чём говорит

Big word

CLEAR / PRESENT / MOVEMENT / ACTIVE / VIGOROUS. PRESENT означает, что человек присутствует, но не движется. Это обнаруживается по дыханию.

MOTION (dB)

Общее движение. 0 дБ — пустая комната, значения выше ~6 дБ означают реальное движение, при ходьбе показания колеблются в районе 20—30 дБ.

VITALS (dB)

Энергия в диапазоне регистрации дыхания. По этим показаниям фиксируется неподвижный человек.

CHANNEL RESPONSE

Водопадный график. Горизонтальные полосы отражают постоянную картину многолучевого распространения сигнала в комнате, а вертикальные штрихи означают, что что-то в ней движется.

ACTIVITY

Оба графика показаний в дБ за последнюю минуту. Пунктирные линии отмечают пороговые значения, на основе которых система принимает решения в данный момент.

RESPIRATION

Количество вдохов в минуту, отфильтрованная форма волны и спектр с отмеченным выбранным пиком. Пустой экран с ровной линией — это нормально. Системе требуется неподвижный объект и около 30 секунд для расчёта.

ENVIRONMENT

Появляется только после прибытия пакета данных, поэтому сборка без дополнительных датчиков выглядит завершённой, а не сломанной.

PACKETS

Сгруппированные счётчики всех типов кадров данных. Потери вычисляются по порядковым номерам пакетов, которые присваивает сам узел, поэтому пропуск — это кадр, который гарантированно ушёл с платы, но до Pi так и не долетел.

DIAGNOSTICS

Частота опроса должна быть около 100 Гц. При этом ошибки, отброшенные и отклонённые пакеты должны быть на 0.

На калибровку детекции движения уходит 6 секунд, а на детекцию дыхания 30.

О показателе качества воздуха. При его вычислении используются стандартная шкала AQI (индекс качества воздуха) от 0 до 500, стандартные категории и та же кусочно-линейная интерполяция, что и в настоящем AQI. Отличие в том, что вычисляются эти данные исключительно на основе показаний эквивалента CO2 от датчика MQ135. При расчёте нормативного AQI преобладают твёрдые микрочастицы PM2.5, которые этот датчик вообще не умеет измерять, поэтому даже в задымлённом помещении прибор может сообщать статус «Good». Так что ориентируйтесь на динамику изменения этого значения, а не на саму абсолютную цифру. Подробно этот принцип и работа самокорректирующегося базового уровня объясняются в разделе 6d файла PROJECT.TXT.

10. Как получить качественные результаты

  • Плата и роутер должны находиться на противоположных сторонах сканируемого пространства. Вы фиксируете то, что происходит между ними, а не вокруг самой платы.

  • Разнесите их на расстояние от 2 до 8 метров.

  • Если сигнал сильнее, это не значит, что он лучше. При очень близком расположении начинает преобладать сигнал по прямому пути, и отражения просто теряются в нём. Уровень RSSI должен быть в диапазоне от -40 до -60 дБм.

  • Усядьтесь где-нибудь посередине, в идеале строго по центру — но не рядом с платой.

  • Для регистрации дыхания требуется неподвижность. Ориентируйтесь по показаниям MOTION, а не собственному ощущению неподвижности: система фиксирует как движение рук при использовании клавиатуры, так и шевеления на стуле. Дыхание начинает обнаруживаться чуть ниже +5 дБ. Если вы двигаетесь, дашборд просто покажет «subject moving» и никаких показаний не выведет, что вполне корректно.

  • Хороший захват сигнала выглядит так: движение (Motion) ниже +5 дБ, жизненные показатели (Vitals) выше +20 дБ, частота плавно меняется на десятые доли, а уровень достоверности (confidence) выше 0,4.

  • Система регистрирует движение вентиляторов, занавесок и животных. Всё это не относится к ложным положительным, так как здесь действительно происходит движение.

11. Все команды в одном месте

Выполните эти команды из каталога pi/.

Сервер

Команда

Действие

../.venv/bin/python -m wifisense --link serial

Запуск через USB-кабель

../.venv/bin/python -m wifisense --link synthetic

Запуск без оборудования

../.venv/bin/python -m wifisense --link nrf24

Запуск по радиоканалу 2,4 ГГц

../.venv/bin/python -m wifisense --link replay

Воспроизведение записанного сеанса

Взаимодействие с платой

Команда

Действие

tools/node.py info

Статус: подключение к сети (ассоциирование), IP-адрес, состояние CSI, частота опроса.

tools/node.py monitor 30

Измерение реальной частоты поступления кадров CSI.

tools/node.py wifi "SSID" "PASSWORD"

Конфигурирование параметров WiFi (сохраняются во флэш-памяти).

tools/node.py mode sta / mode sniffer

Режим ассоциирования (association) или режим прослушивания (promiscuous).

tools/node.py link usb / nrf24 / cc1101

Переключение режима передачи данных (настройка сохраняется во флэш-памяти).

tools/node.py reboot

Перезапуск узла.

tools/node.py radioscan

Сканирование задокументированных контактов подключения радиомодулей.

tools/node.py radiosweep

Поиск радиомодулей на всех доступных GPIO (~20 с).

Датчики окружающей среды

Команда

Действие

tools/node.py env

Считывание показаний со всех трёх датчиков.

tools/node.py mq135 cal

Установка базового уровня качества воздуха (выполняйте возле открытого окна).

tools/node.py mq135 supply 3v3

Указание плате, что аналоговый выход (AO) подключен напрямую.

tools/node.py mq135 supply 5v

Указание плате, что AO подключен через делитель напряжения.

Проверка корректности

Команда

Действие

tools/validate_dsp.py

Тестирование всей цепочки детекторов с помощью синтетических данных CSI при заданной частоте дыхания — 81 проверка. Это единственное место, где пайплайн обработки данных можно проверить на ошибочность. Именно этот скрипт запускается системой непрерывной интеграции при каждом обновлении (push) кода.

REST API

Конечная точка

Возвращает

/api/state

Полный снимок данных в реальном времени.

/api/health

200, если по каналу передаются данные; 503, если нет.

/api/history?hours=24&points=900

Архивированные временные ряды.

/api/sleep?night=YYYY-MM-DD

Отчёт по сну за одну ночь (по умолчанию прошлую).

/api/sleep/nights

По каким ночам есть данные.

/api/history/stats

Количество сохранённых строк, временной охват и ошибки записи.

12. Решение типичных проблем

Симптом

Причина и исправление

Нет устройства /dev/ttyUSB*

Почти всегда дело в USB-кабеле, который предназначен только для зарядки. Если не он, то выполните команду lsusb | grep -i "silicon labs".

Частота опроса ~1Гц вместо ~100 Гц

Плата не подключена к роутеру, поэтому UDP-запрос от Pi не может до неё дойти. Выполните tools/node.py info и найдите assoc=yes. Ваш WiFi точно работает на 2,4ГГц?

Частота опроса равна 0

Проверьте статус csi=ok в выводе tools/node.py info. FAILED означает, что API-интерфейс CSI был отклонён — обычно это вызвано несоответствием прошивки и IDF. Перепрошейте ESP.

Все показатели молчат (CLEAR), хотя в комнате кто-то есть.

Человек находится не между платой и роутером. Проверьте уровень RSSI: он должен быть в диапазоне от -40 до -60 дБм.

Все показатели активны (ACTIVE) в пустой комнате.

Значит, движение всё же есть: вентилятор, открытое окно, какое-то животное. Также убедитесь, что плата лежит неподвижно — если она будет висеть на кабеле, будет регистрироваться движение.

Дыхание не распознаётся

Объект наблюдения должен быть неподвижен в течение 30+ секунд, а частота опроса составлять более ~20 Гц. Сообщение «subject moving» указывает на то, что детектор движения блокирует распознавание дыхания, что абсолютно правильно.

Растёт число ошибок подключения

Помехи в последовательном порту. Используйте более короткий или более качественный USB-кабель. Имейте в виду, что механизм CRC перехватывает каждый повреждённый кадр, поэтому рост ошибок снижает лишь частоту опроса, но на корректность не влияет.

Панель мониторинга окружающей среды не отображается

Кадр с данными об окружающей среде не поступал. Обратитесь к плате напрямую: tools/node.py env.

BMP280 = ABSENT

Провода SDO/SDA перепутаны местами (самое вероятное), контакт CSB не подключён к GPIO15, или используется плата с поддержкой только I2C, где CSB жёстко подтянут к питанию.

DHT22 = NO-REPLY

Отсутствует подтягивающий резистор на 10 кОм для отдельного 4-контактного датчика; либо линия DATA не подключена к GPIO16.

MQ135 = OUT-OF-RANGE

Напряжение около 0 мВ: AO не подключен. Напряжение близко к напряжению питания: элемент перенасыщён, либо AO подключен напрямую к 5 В без делителя — сначала проверьте этот момент, так как он может привести к повреждению АЦП.

Показания качества воздуха застыли на “WARMING UP”

Для автоматической калибровки прибор должен быть включен как минимум три минуты и выдавать корректные показания.

Служба не запускается

journalctl -u wifisense -n 40

Более подробные объяснения даны в разделе 9 файла PROJECT.txt.

13. Готовая прошивка и образы контейнеров

Прошивка без установки PlatformIO

Каждый релиз сопровождается готовыми для прошивки бинарниками — ищите их на странице Releases. Едины комбинированный образ заливается с нулевого адреса (0x0):

pip install esptool
esptool.py --chip esp32s3 --port /dev/ttyUSB0 --baud 921600 
    write_flash 0x0 wifisense-firmware-v1.0.0.bin

Сначала проверьте, что именно скачали:

sha256sum -c SHA256SUMS

В бинарном файле содержится временный радиоключ, состоящий из одних нулей. Это абсолютно нормально для работы через USB-кабель, так как данные по нему всё равно передаются без шифрования. Но если вы используете радиоканал, вам потребуется задать собственный ключ и пересобрать проект вручную — готовый бинарный файл не может содержать в себе приватный ключ. См. раздел «Безопасность радиоканала».

Запуск сервера в контейнере

Готовые образы публикуются в GitHub Container Registry для архитектур linux/amd64 и linux/arm64:

# Только дашборд, без оборудования, по адресу http://localhost:8080
docker run --rm -p 8080:8080 ghcr.io/the-masked-bear/wifisense-pi:latest

# С платой, подключенной по USB.
docker run --rm -p 8080:8080 --device /dev/ttyUSB0 
    ghcr.io/the-masked-bear/wifisense-pi:latest python -m wifisense --link serial

Безопасность радиоканала

Данные CSI позволяют узнать, когда в комнате кто-то есть, когда люди двигаются и когда они спят. Если передавать их в открытом виде, любой человек в радиусе действия радиосигнала, имеющий такой же радиомодуль на том же канале, сможет их перехватить. Поэтому все данные, отправляемые по радиоканалу, шифруются алгоритмом AES-128 в режиме счётчика с генерацией нового случайного идентификатора сессии при каждой загрузке платы и защитой от повтора пакетов.

Сгенерируйте ключ и укажите одно и то же значение на обоих сторонах канала:

python3 -c "import secrets;print(secrets.token_hex(16))"

Куда прописывать

Как

firmware/src/config.h → RADIO_KEY (либо в скрытый от git firmware/src/secrets.h)

{0x.., 0x.., ...}

pi/config.json → radio_key

32 шестнадцатеричных символа

При несовпадении ключей счётчик cobs_errors начинает стремительно расти, в то время как показатель frames_ok застывает на нуле. Это обеспечивает конфиденциальность, но не аутентификацию: наличие CRC-16 внутри зашифрованной полезной нагрузки означает, что случайная подделка пакета сработает с вероятностью всего 1/65536. Для домашнего датчика такой защиты вполне достаточно, но полноценным кодом аутентификации сообщения (MAC) это не является.

14. Структура репозитория

PROJECT.txt              документация: вся в одном файле
requirements.txt         зависимости Python
Dockerfile               образ контейнера для сервера на Pi
install.sh               установщик автозапуска
systemd/                 шаблон службы

firmware/                прошивка ESP32-S3 (PlatformIO)
  platformio.ini         конфигурация платы. Для N15R8 обязателен режим qio_opi.
  src/config.h           настраиваемые параметры: режим, контакты, частоты, выключатели датчиков
  src/main.cpp           захват данных CSI, формирование кадров, обработка команд 
  src/radio_tx.*         передача данных по радиоканалу через nRF24/CC1101, арбитраж шины SPI 
  src/cc1101_driver.*    внутренний драйвер регистров CC1101
  src/bmp280.*           внутренний SPI-драйвер для BMP280/BME280
  src/sensors.*          DHT22, MQ135 и фоновая задача для опроса датчиков
  src/link_crypto.*      алгоритм AES-128-CTR для защиты радиоканала

pi/
  wifisense/
    protocol.py          формат передачи данных: формирование кадров методом COBS, проверка CRC-16, карта поднесущих частот
    stimulus.py          UDP-генератор запросов, задающий частоту опроса
    archive.py           долгосрочное хранилище в SQLite + отчёт о сне
    spectrum.py          мониторинг субгигагерцевого диапазона радиомодуля CC1101
    dsp/                 csi -> фильтры -> движение / дыхание -> пайплайн вычислений
    link/                последовательный порт, nrf24, cc1101, воспроизведение (replay), симулятор
    api/server.py        FastAPI, WebSocket, REST
  web/                   дашборб + страница истории. Никакой сборки и зависимостей
  tools/node.py          утилита для управления ESP32 через командную строку
  tools/validate_dsp.py  проверка корректности по заданному эталону

Документация

PROJECT.txt — это основной документ, написанный так, чтобы его было удобно читать прямо за рабочим столом вдали от терминала. В нём есть всё: полная схема разводки проводов, настройка, калибровка, поиск неисправностей и обоснование каждой константы в коде. Там же описаны исправленные баги и симптомы, которыми они проявлялись — включая случай, когда из-за нестандартного дыхания человека мощность седьмой гармоники сигнала оказалась на 2,4 дБ выше основной частоты, и алгоритм выбора пиков уверенно выдал частоту дыхания, завышенную в семь раз.

Показатели системы

Частота опроса CSI

100 Гц, 1:1 с частотой UDP-запросов (работает и на 200 Гц)

Пропускная способность кабеля

149 байтов/кадр, 119 кбит/с (~16% от пропускной способности канала)

Pi CPU

~20% одного ядра

Пустая комната

Движение регистрируется на уровне +1,1 дБ, а дыхание на уровне +0.0 дБ

При ходьбе

Движение регистрируется на уровне +27,8 дБ

Дыхание неподвижного человека

Дыхание регистрируется на уровне +33,6 дБ

Точность дыхания

14,1 вдохов/мин против 14.0 эталонных; 22,0 против 22,0

Зашифрованный канал nRF24

Доставлено 108,1 Гц из 113,6 Гц захваченных (95,1% эффективности)

Ошибки последовательного порта

0 CRC, 0 ошибок фрейминга за всё время длительных испытаний

Проверка DSP

Пройдено проверок: 81/81

Автор: Bright_Translate

Источник