Приходило ли вам в голову, что ваша любимая esp32, может использоваться в роли самого натурального радиолокационного радара?

Если не приходило, то добро пожаловать под кат, так как кое-кому это пришло:-))

Далее в статье рассматривается специфическая версия радара, когда передатчик и приёмник конструктивно не выполнены в едином корпусе, а разнесены в пространстве. Тем не менее, всё работает и никто не мешает в дальнейшем (при желании) — сделать более классическую версию, где приёмник и передатчик расположены в корпусе одного устройства.

Ориентировочная, приблизительная цена одной из полноразмерных версий esp32, на данный момент, на всем известном китайском сайте, — находится в пределах 400 рублей, что и упомянуто в заголовке статьи.

Какая была основная задумка (хотя возможности технологии намного шире, и об этом ещё будет в конце статьи): сделать просто-напросто датчик движения!

При этом, не используя каких-либо внешних датчиков, а всего лишь воспользовавшись уже имеющимися возможностями (а как мы знаем, — чем проще система, тем она надёжней). «А ещё это интересно».©

Если кто не сталкивался ранее, то, в качестве краткого вступления, поясню, что далее речь пойдёт о несколько нестандартном использовании микроконтроллеров семейства esp32 (а конкретно в этом эксперименте ниже, была использована версия esp32 wroom 32), которые обычно применяются для самоделок в области любительской и не очень робототехники, а также устройств «умного дома» и интернета вещей (IoT).

Микроконтроллеры семейства esp32 очень удобны для этого применения, так как содержат на борту достаточно мощный процессор, довольно дёшевы и имеют как минимум два беспроводных интерфейса — Wi-fi и Bluetooth BLE.

Итак, это было небольшое отступление, а теперь — немного теории…

Сначала — «бочка мёда».
Дело в том, что технология беспроводной передачи данных wi-fi содержит ряд возможностей, которые обычно не используют создатели типовых самоделок на базе микроконтроллеров esp32, и одной из таких возможностей является Channel State Information (CSI) — метаданные радиоканала, которые позволяют оценить изменения окружающей среды.

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

Какие параметры этих метаданных могут быть использованы:
  • амплитуда сигнала (то есть, как изменяется мощность принятого сигнала);
  • сдвиг по фазе сигнала (то есть время прохождения сигнала);
  • данные о поднесущих.

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

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

А теперь — «ложка дёгтя».
Несмотря на множество попыток, у меня эта технология «не завелась», поэтому, в решении ниже, была использована несколько более простая технология, но, тем не менее, вполне рабочая — Received Signal Strength Indicator (RSSI) — как можно понять по названию, измерения силы принятого сигнала, в децибел-милливаттах(дБм).

Давайте сразу «зайдём с конца» — так как я сам тоже обычно довольно-таки нетерпелив, и мне бывает любопытно узнать, что в итоге мы таки получим в результате всех этих мытарств?

А получим мы следующее: весьма чувствительную систему детекции движений — во время моих тестов, в любой точке комнаты (примерно 3,5 х5,5 метров) стоило не только сделать шаг, но даже изменить положение руки — как сразу это детектировалось! О_о

Кроме того: после того как произошла детекция движения в комнате — сразу отсылается e-mail хозяину, что «в комнате какое-то движение!».


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

Радиолокация ещё хороша тем, что она совершенно равнодушна к освещённости и температуре в комнате, — что могло бы быть проблемой в случае оптических датчиков (плавали, знаем), или, например, к шумовому фону (если бы мы использовали какой-нибудь звуковой датчик, как вариант).

Какие были опасения: так как я живу в многоквартирном доме (как, наверное, и большинство из вас), то, как нетрудно догадаться, эфирная ситуация весьма сложная — беглый обзор доступных wi-fi сетей сразу находит порядка 30 штук!

Кроме того, были опасения и по поводу прохождения wi-fi сигнала сквозь стены – и что вместо полезной работы, по наблюдению за этой комнатой, он, условно говоря, будет отслеживать, когда сосед в квартире сверху/сбоку/и.т.д. «пошёл в туалет»:-))).

Были опасения и по поводу «внедомовых» объектов: так как живу я на втором этаже, а прямо под окнами у меня проходит улица, с довольно-таки активным автомобильным движением, где ездят «большие железные колесницы» (машины), наверняка влияющие на электромагнитное поле, то я опасался, что датчик будет отслеживать и их тоже!

Сразу скажу: все опасения оказались напрасны! Датчик чётко срабатывает на изменения только в комнате, а все окружающие более далёкие изменения среды — игнорируются (настраивается порогом срабатывания).

Теперь, об интересном: в процессе множества экспериментов было эмпирически выявлено, а потом и «нагуглено» (ну да, это наш классический способ — «сначала всё перепробовать, и, если не получается, то только потом достать мануал»), что поляризация wi-fi антенны esp32 — горизонтальная.

Это означает, что электромагнитные колебания волны распространяются параллельно полу (наверное, не совсем корректно сказал, но, по крайней мере, если что, вы меня поправите).

Следствием из этого является (это было многократно проверено мной экспериментально) что esp32 должна стоять вертикально в процессе детекции, так как, если положить её горизонтально на стол, то она практически перестаёт реагировать на любые движения в комнате.

Также, был выявлен и ещё один момент — уверенная детекция движений происходит, если находиться относительно антенны далеко не со всех сторон!

Например, если находиться таким образом, чтобы металлический кожух чипа был параллелен и смотрел прямо на нас/от нас — то esp32 практически не обнаруживает движений!

Насколько удалось выяснить, происходит это вот из-за чего: виновата, так называемая, «диаграмма направленности» антенны, которая представляет собой условную «восьмёрку», или, другими словами, антенна esp32, наиболее чувствительна в секторе, примерно +45...-45 градусов, относительно вертикальной плоскости самой платы.

Ниже, я постарался показать это на рисунке. Углы в градусах на картинке — примерны (определял на глаз):



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

Также, есть и ещё один нюанс: вы должны находиться между роутером и самой esp32, чтобы ваши движения, в той или иной степени, как бы перегораживали сигнал, что и будет детектироваться.

Но тут, сразу возникает логичный вопрос: если здесь работает принцип перегораживания в той или иной степени сигнала, то, по идее (если рассуждать по-простому), движение должно обнаруживаться только в том случае, если вы напрямую перегородили собой роутер!

Так почему же оно обнаруживается, даже если вы напрямую не перегораживаете собой роутер (например, находитесь в крайних точках: +45 и -45 градусов)?!

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

Соответственно, если бы вы будете перемещаться в границах этого «тумана» — его картина в помещении будет изменяться, суммовой сигнал на приёмнике тоже будет изменяться, что и будет обнаруживать приёмник!

Причём, повторюсь, настроив порог срабатывания, можно сделать систему настолько чувствительной, что она (в теории) будет видеть, даже если вы «шевельнули пальцем»:-). По крайней мере на данный момент – она вполне видит движения руки…

Но, это только половина задачи. Теперь же, нужно как-то уведомить хозяина, что «кто-то неведомый бродит в комнате, по его душу».

Для этого воспользуемся библиотекой ESP_Mail_Client, которая позволяет взаимодействовать с электронной почтой.

Опять же, повторюсь, что это всего лишь один из возможных способов. Если хотите, можете попробовать прикрутить к telegram боту.

Можно использовать разные почтовые службы, но, так как я частенько использую mail.ru, именно под него и сделано это решение.

Итак, что нужно, чтобы система могла отсылать почту, используя mail.ru?

Первое, и самое главное — вам нужно разрешить доступ к своей почте, используя внешние программы/клиентов, для чего вам надо получить специальный пароль для доступа таких программ.

Чтобы получить такой пароль, вам нужно найти зайти в свою почту, и в самом низу вертикального списка ваших папок слева, — найти пункт «настройки» и далее пройти по пути, которые я показал ниже:



В конце этого пути, вам надо как-то назвать этот девайс, для которого собственно вы и формируете этот пароль — как можно видеть на картинке выше, я назвал этот доступ «esp32».

Далее, этот пароль, и ряд других настроек, забиваем в код и прошиваем этим кодом esp32:



Ну вот, собственно говоря, и всё (да не всё! ;-) — об этом ниже).

Полный код можно найти ниже:

Код для прошивки
/*Создано с использованием ИИ DeepSeek. 
Код выкладывается без любых гарантий его работы.*/

#include <WiFi.h>
#include <ESP_Mail_Client.h>
#include <time.h>

// Настройки WiFi-точки доступа (роутера, к которому подключаемся)
const char* SSID = "";
const char* PASSWORD = "";

// Настройки SMTP (Mail.ru)
#define SMTP_HOST "smtp.mail.ru"
#define SMTP_PORT 465
#define EMAIL_SENDER "сюда забить адрес почты откуда шлём письмо" //e-mail, на который заходим, чтобы отослать письмо 
#define EMAIL_PASSWORD "сюда забить секретный пароль для приложений" // Пароль для приложений от mail.ru
#define EMAIL_RECIPIENT "сюда забить адрес почты куда шлём письмо" //e-mail, куда шлём письмо

#define NTP_SERVER "pool.ntp.org"
#define GMT_OFFSET_SEC 3 * 3600 // +3 для Москвы


// Параметры детектора
const float BASE_THRESHOLD = 1.2f;
const int SAMPLE_INTERVAL = 200;
const unsigned long EMAIL_COOLDOWN = 30000;

// Глобальные переменные
SMTPSession mailSession;
unsigned long lastEmailTime = 0;
float baselineRSSI = -60.0f;
bool isCalibrated = false;

void setup() {
  Serial.begin(115200);
  Serial.println("\n=== Wi-Fi Motion Detector ===");
  
  connectToWiFi();
  configTime(GMT_OFFSET_SEC, 0, NTP_SERVER);
  calibrateSensor(); // Калибровка ОСТАЁТСЯ (обязательна!)
}

void loop() {
  float currentRSSI = readFilteredRSSI();
  float deviation = abs(currentRSSI - baselineRSSI);
  float threshold = max(BASE_THRESHOLD, abs(baselineRSSI * 0.03f));

  Serial.print("RSSI: ");
  Serial.print(currentRSSI, 1);
  Serial.print(" dB | Dev: ");
  Serial.print(deviation, 1);
  Serial.print("/");
  Serial.print(threshold, 1);
  Serial.println(" dB");

  if (deviation > threshold && isCalibrated) {
    handleMotionDetected(deviation, currentRSSI);
    baselineRSSI = baselineRSSI * 0.7f + currentRSSI * 0.3f;
  } else {
    baselineRSSI = baselineRSSI * 0.98f + currentRSSI * 0.02f;
  }

  if (WiFi.status() != WL_CONNECTED) connectToWiFi();
  delay(SAMPLE_INTERVAL);
}

// Подключение к Wi-Fi
void connectToWiFi() {
  if (WiFi.status() == WL_CONNECTED) return;
  
  Serial.print("Подключение к ");
  Serial.print(SSID);
  WiFi.begin(SSID, PASSWORD);
  
  byte attempts = 0;
  while (WiFi.status() != WL_CONNECTED && attempts < 20) {
    delay(500);
    Serial.print(".");
    attempts++;
  }
  
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("\nУспешно! RSSI: " + String(WiFi.RSSI()) + " dB");
  } else {
    Serial.println("\nОшибка подключения!");
  }
}

// Калибровка (ОБЯЗАТЕЛЬНА для точных показаний)
void calibrateSensor() {
  Serial.println("Калибровка... Не двигайтесь 5 сек");
  float sum = 0;
  for (byte i = 0; i < 20; i++) {
    sum += WiFi.RSSI();
    delay(250);
  }
  baselineRSSI = sum / 20.0f;
  isCalibrated = true;
  Serial.print("Базовый уровень: ");
  Serial.println(baselineRSSI, 1);
}

// Обработка движения
void handleMotionDetected(float deviation, float rssi) {
  Serial.println(">>> ДВИЖЕНИЕ ОБНАРУЖЕНО! <<<");
  
  if (millis() - lastEmailTime > EMAIL_COOLDOWN) {
    if (sendAlert(deviation, rssi)) {
      lastEmailTime = millis();
    }
  }
}

// Отправка email
bool sendAlert(float deviation, float rssi) {
  ESP_Mail_Session config;
  config.server.host_name = SMTP_HOST;
  config.server.port = SMTP_PORT;
  config.login.email = EMAIL_SENDER;
  config.login.password = EMAIL_PASSWORD;

  SMTP_Message message;
  message.sender.name = "ESP32 Motion Alert";
  message.sender.email = EMAIL_SENDER;
  message.subject = "Обнаружено движение";
  message.addRecipient("User", EMAIL_RECIPIENT);
  
  struct tm timeinfo;
  String timeStr = getLocalTime(&timeinfo) ? 
    String(timeinfo.tm_hour) + ":" + String(timeinfo.tm_min) + ":" + String(timeinfo.tm_sec) : "N/A";
  
  message.text.content = ("Детали:\n"
    "• RSSI: " + String(rssi, 1) + " dB\n" +
    "• Отклонение: " + String(deviation, 1) + " dB\n" +
    "• Время: " + timeStr).c_str();

  if (!mailSession.connect(&config) || !MailClient.sendMail(&mailSession, &message)) {
    Serial.println("Ошибка отправки!");
    return false;
  }

  Serial.println("Письмо отправлено в " + timeStr);
  return true;
}

// Фильтрация RSSI
float readFilteredRSSI() {
  static float filtered = WiFi.RSSI();
  filtered = filtered * 0.6f + WiFi.RSSI() * 0.4f;
  return filtered;
}



Выше мы говорили о том, что возможности у этой технологии гораздо шире, чем в качестве простого датчика движения!

Какая первая мысль приходит «синонимом» к слову «радар»?

Не знаю как у вас, но у меня первая мысль это — некое «наведение на цель», «отслеживание цели».

И радар, на базе esp32, в теории, вполне с этим может справиться, только нужно несколько видоизменить систему: нужно использовать две пары из двух esp32 (итого 4): в каждой паре, одна является точкой доступа, а другая — приёмником.

Чтобы они напрямую не ловили сигнал друг друга — они размещаются в относительно длинных трубах, например, как лист А4 длиной (нужно тестировать, это предположительно).

После чего, эта пара «двустволок» наводится в сторону «цели».

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

Если нужно определять полноценные координаты X, Y — то нужно использовать как раз две пары, где одна пара будет отвечать за координату X, а вторая за Y.

Предполагаемая точность определения координат может составить примерно 10-30 см.

Полноценный радиолокационный радар ближнего радиуса действия, за условные менее чем 1600 руб (приблизительная цена четырёх esp32)?

Ну, почему бы и нет...:-) Можно кота радарить, который хочет ночью запрыгнуть на кухонный стол и обрызгивать водой из автоматической брызгалки (как один из вариантов). :-D

P.S. Использование технологии CSI, потенциально может повысить точность определения координат радаром. Но, у меня это не завелось… Возможно, заведётся у вас?

Комментарии (10)


  1. kenomimi
    17.06.2025 16:58

    HiLink делает полноценные радары по той же цене, что средний esp32. На али навалом, от дешевых, до дорогих - причем те, что подороже, даже сердечный ритм издалека видят. Сразу получаем нужную информацию по RS232, плюс есть китайское приложение для тонкой настройки...

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


    1. cnet Автор
      17.06.2025 16:58

      Только штука в том, что тут, в отличие от внешнего радара - получается "всё в одном" - ничего никуда подключать не надо -всё уже встроено и работает + ещё микроконтроллер :-)


    1. Ra3wum
      17.06.2025 16:58

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


  1. nehrung
    17.06.2025 16:58

    поляризация wi-fi антенны esp32 — горизонтальная.

    Ничто (кроме отсутствия знаний) не мешает заменить штатную антенну esp32 на антенну с круговой поляризацией Это позволит решить многие проблемы с пространственной фильтрацией радиоволн (те самые ваши "мёртвые зоны"). А можно не устранять их, а наоборот, использовать (например, для отстройки от помех, приходящих с конкретных направлений).


    1. xSVPx
      17.06.2025 16:58

      Так даже менять не надо, есть вариант esp с разъемом для внешней антенны.


  1. d1024
    17.06.2025 16:58

    Вот интереcный проект на тему радара из esp32 https://youtu.be/sXwDrcd1t-E


  1. iliasam
    17.06.2025 16:58

    Radar расшифровывается как "radio detection and ranging". Ranging в данном случае отсутствует.


    1. cnet Автор
      17.06.2025 16:58

      Здесь я хотел показать в целом направление для мыслей и разработок. А в рамках "направления" - вполне себе и координаты определяются и расстояние ;-)

      В принципе, даже на 1 esp-шке можно определять расстояние (там, в конце статьи про это есть), - просто у меня задача была немного иная. Но, надеюсь, повод для размышления я дал:-)


  1. Stepious
    17.06.2025 16:58

    Наблюдал довольно близкое здесь:

    https://youtu.be/sXwDrcd1t-E?si=n8R82OS8MSFDUPWm

    Тем не менее, их я поддерживать не хочу, а вас можно поддержать вполне, мне понравилось.