FPV CLUB
Лаборатория FPV Club · ESP-NOW

Радиоуправление на ESP32: учебный стенд с ESP‑NOW

Сначала проведите три опыта в живой модели, затем соберите безопасный стенд на двух ESP32. В конце вы сможете объяснить, когда теряются отдельные пакеты, когда срабатывает failsafe и почему для FPV-дрона обычно выбирают ExpressLRS.

15 минут · модель2 × ESP32 · стендESP‑NOW без роутераБез пропеллеров
⚖️

Сразу определим границу. ESP‑NOW подходит для обучения, робота и низкорискового стенда. Для летательного аппарата, где отказ связи может привести к падению, используйте штатную RC-систему — например, ExpressLRS — и отдельно проверяйте её failsafe.
Шаг 1 · увидеть принцип

Проведите три опыта

Нажимайте кнопки по порядку. У каждого опыта есть одно действие, один наблюдаемый результат и короткое объяснение.

ESP‑NOW LINK LAB

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

LINK

Маршрут ученика0 из 3 опытов


Начните с опыта 1. Смотрите на команду на выходе, затем на LQ, возраст пакета и состояние.

ПередатчикESP32 + стики

ESP32 TX

seq 0

ПриёмникESP32 + выход

ESP32 RX

rx 0

Команда на выходе

−1000безопасный минимум
Таймер failsafe

0 / 250 мс

LQ · 100 пакетов100%
Возраст пакета0 мс
Пакетная частота100 Гц
Потеряно всего0
СостояниеLINK

Что означают эти показатели?
LQ — доля принятых пакетов из последних 100 попыток; возраст — время после последнего валидного пакета; потеряно — пропуски, замеченные по номеру seq. Failsafe зависит от возраста пакета, а не от одного значения LQ.
После трёх опытов необязательные настройки
Изменить условия вручную
−1000
8/100
5/100

Показать график LQ

График показывает LQ во времени. После смены условия подождите 1–2 секунды: окно из 100 пакетов обновляется постепенно.

Что сейчас происходит объяснение без формул
Связь стабильнаПакеты приходят чаще тайм-аута. Приёмник обновляет выход и считает пропуски по номеру последовательности.

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

Команда следует за стиком → при помехах появляются пропуски → после выключения TX возраст пакета доходит до тайм-аута и выход становится −1000. В модели связь восстанавливается автоматически; на реальном аппарате возврат управления должен требовать осознанного повторного разрешения.

Шаг 2 · собрать схему

Что именно мы строим

ESP32 — микроконтроллер с радиочастью. ESP‑NOW — способ передавать короткие кадры между ESP без точки доступа. Формат команд, подтверждение, телеметрию и безопасность вы проектируете сами.

ПультСтики → ADC → нормализация → пакет с seq
ESP‑NOWUnicast, одинаковый Wi‑Fi-канал, известный MAC
ПриёмникПроверка длины/версии/seq → таймер → безопасный выход

2 × ESP32Для первого стенда лучше одинаковые DevKit-платы.
2 оси стикаПотенциометры джойстика или отдельные ручки.
ПитаниеСтабильные 5 В для DevKit; общая земля для сигналов.
Безопасная нагрузкаСветодиод, логический анализатор или серво от отдельного BEC.

Если выбираете между семействами микроконтроллеров, сначала откройте сравнение модулей ESP и STM. Для этого проекта важнее не максимальная частота ядра, а наличие подходящего радио, стабильного питания, нужных ADC/таймеров и понятной среды разработки.
Перед подключением подготовьте только безопасный минимум.

Две платы ESP32 DevKit, два USB-кабеля, джойстик или потенциометр, светодиод с резистором и стабильное питание. Мотор, ESC и пропеллеры на этом этапе не нужны.

Шаг 3 · подключить

Минимальная разводка стенда

Номера выводов ниже подходят как понятный пример для классического ESP32 DevKit. На ESP32‑C3/S3 и других платах сначала сверяйте pinout своей конкретной платы.

Передатчик

  • Ось X джойстика → GPIO34 (ADC1)
  • Ось Y → GPIO35 (ADC1)
  • Кнопка ARM/режим → GPIO32 с INPUT_PULLUP
  • VCC джойстика → 3,3 В, GND → GND

ADC2 на классическом ESP32 конфликтует с активным Wi‑Fi-драйвером. Для стиков проще выбирать ADC1.

Приёмник

  • Тестовый LED → безопасный GPIO через резистор
  • Сигнал сервопривода → GPIO18
  • Питание сервопривода → отдельный 5 В BEC
  • Земля BEC и ESP32 → общая

Не питайте сервопривод от вывода 3,3 В ESP32. Просадка питания даст перезагрузку, которая выглядит как «плохая радиосвязь».

Как узнать MAC-адрес приёмника

Сначала прошейте плату-приёмник этим коротким скетчем, откройте Serial Monitor на 115200 бод и перепишите адрес интерфейса STA. Именно его затем добавляют как peer на передатчике.

#include <WiFi.h>

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  delay(100);
  Serial.println(WiFi.macAddress());
}

void loop() {}

Не перепутайте адреса: у STA и SoftAP одной платы разные MAC. В этой лаборатории обе платы работают в режиме STA и на одном выбранном Wi‑Fi-канале.

Если у вас ESP32-C3, S3 или другая DevKit-плата

Не переносите номера GPIO вслепую. Сверьте pinout именно своей платы: наличие ADC1, загрузочные выводы, допустимый ток и встроенный LED различаются. Радиологика урока остаётся той же, меняется разводка.

Разводка готова, если обе платы запускаются отдельно.

В Serial виден MAC приёмника, движение стика меняет показания ADC, а тестовый LED приёмника включается локальной командой. Только после этого добавляйте радиообмен.

Шаг 4 · сделать пакет

Команда должна быть проверяемой

Не отправляйте «просто четыре числа». Версия формата, последовательный номер и флаги помогают отличить новый пакет от старого, увидеть пропуски и безопасно обновлять прошивку.

Минимальная структура пакета

Фиксированный размер упрощает проверку. Значения каналов удобно нормировать в диапазон −1000…1000, а throttle отдельно переводить в безопасный минимум при failsafe.

struct __attribute__((packed)) ControlPacket {
  uint16_t magic;       // например 0xE532
  uint8_t  version;     // версия формата
  uint8_t  flags;       // arm, mode, кнопки
  uint32_t seq;         // растёт на каждый пакет
  int16_t  ch[8];       // -1000 ... 1000
};

static_assert(sizeof(ControlPacket) == 24, "Packet size changed");
Что делать в callback приёмника

Callback ESP‑NOW выполняется в задаче Wi‑Fi. В нём быстро проверьте адрес источника, длину, magic/version и скопируйте данные в очередь или защищённый буфер. Управление PWM, журналирование и тяжёлые вычисления перенесите в обычный loop/task.

onReceive(info, data, len):
  if source MAC is not allowed: return
  if len != sizeof(ControlPacket): return
  copy data to local packet
  if magic/version invalid: return
  if seq is old or duplicate: return
  queue packet for control task
Failsafe выполняется отдельно от приёма

Главное правило: отсутствие callback тоже является событием. Поэтому таймер проверяет возраст последнего валидного пакета независимо от радиообработчика.

if (millis() - lastValidPacketMs > FAILSAFE_MS) {
  output.throttle = -1000;
  output.roll = output.pitch = output.yaw = 0;
  output.armed = false;
  linkState = FAILSAFE;
}
Статус отправки ESP‑NOW означает успех или ошибку на MAC‑уровне. Если нужно знать, что приложение приёмника действительно приняло и применило пакет, добавьте обратный пакет ACK/telemetry с последним обработанным seq.
Как превратить официальный пример в этот стенд
  1. Откройте актуальный пример ESP‑NOW из установленного пакета Arduino‑ESP32 и сначала добейтесь обмена тестовой строкой.
  2. Перейдите с broadcast на unicast и добавьте MAC приёмника как peer.
  3. Замените строку структурой ControlPacket; одинаковое объявление должно быть на обеих платах.
  4. На приёмнике принимайте пакет в callback, но применяйте его и проверяйте failsafe в обычном loop() или отдельной задаче.
  5. Сначала выводите seq, возраст пакета и состояние в Serial. LED подключайте после того, как проверка длины, версии и источника уже работает.

Так меньше риск одновременно отлаживать Wi‑Fi-канал, структуру данных, ADC и выход. Актуальные сигнатуры API берите из официального примера Arduino‑ESP32: они меняются между поколениями пакета плат.

Программа готова к наземным тестам, когда неверный пакет ничего не меняет.

Верный новый seq обновляет выход; дубликат, неверная длина, другая версия и чужой MAC игнорируются; независимый таймер всё равно переводит выход в безопасное состояние.

Главное отличие

ESP32/ESP‑NOW против ExpressLRS

Сравнивать «ESP32 и ELRS» напрямую не совсем корректно: первое — платформа, второе — законченная радиосистема. Но для выбора канала управления такое сравнение полезно.

Критерий ESP32 + ESP‑NOW ExpressLRS
Что это Собственный проект поверх протокола Espressif Специализированная RC-система TX/RX с готовой прошивкой
Радиоканал Обычно 2,4 ГГц, один заданный Wi‑Fi-канал 2,4 ГГц, 868/915 МГц и совместимые диапазоны; частотные перестройки по протоколу
Пакетная частота Задаёте сами; реальный джиттер зависит от кода и радиоэфира Стандартизованные режимы с известной частотой пакетов
Метрики Нужно самим считать seq, LQ, ACK, возраст пакета LQ, RSSI dBm, RF mode и телеметрия уже встроены в рабочий процесс
Failsafe Полностью ваша логика и ваша ответственность Предусмотрен радиосистемой и интеграцией с FC; всё равно требует проверки
Интеграция с FC Нужно реализовать PWM/UART/CRSF-подобный мост и тщательно испытать Готовые CRSF/MAVLink/PWM-сценарии в зависимости от оборудования
Где уместно Учебный стенд, робот, наземная платформа, кастомная телеметрия FPV-дрон, самолёт, дальний и ответственный радиоканал
Главный риск Ложное ощущение готовности после теста «на столе» Ошибка target, антенны, настройки или монтажа — систему тоже надо проверять
Практическое правило. Если отказ канала способен уронить аппарат или травмировать человека — берите штатную RC-систему и проверенную интеграцию. ESP‑NOW оставляйте для обучения, низкорисковых платформ и функций, отказ которых переводит устройство в безопасное состояние.

Если выбираете уже реальный ELRS-приёмник, не ориентируйтесь только на надпись ESP на плате. Начните с матрицы выбора target ELRS: target определяется всей аппаратной схемой, RF-чипом и разводкой, а не названием микроконтроллера.

Шаг 5 · доказать безопасность

Шесть наземных проверок

«Пакеты идут» — только начало. Хороший стенд должен предсказуемо ломаться и восстанавливаться.

1. Выключение передатчика

Через заданный тайм-аут выход обязан перейти в заранее определённое безопасное состояние.

2. Перезагрузка приёмника

До первого валидного пакета никаких старых или случайных команд на выходе.

3. Чужой передатчик

Неверный MAC, magic или ключ не должны обновлять каналы.

4. Пропуски и дубликаты

Счётчик seq выявляет потерянные кадры; старые пакеты не откатывают положение.

5. Просадка питания

Сервопривод двигается под нагрузкой, а ESP32 не перезагружается и не теряет peer.

6. Возврат связи

Решите заранее: выход оживает сразу или ждёт отдельной команды разблокировки.

Диагностика

Если не работает или работает нестабильно

Идите от наблюдаемого симптома. Не меняйте одновременно канал, частоту отправки, питание и структуру пакета.

Передатчик пишет SEND_FAIL
  • Проверьте, что обе платы работают в совместимом Wi‑Fi-режиме и на одном канале.
  • Сверьте MAC именно нужного интерфейса: STA и SoftAP имеют разные адреса.
  • Убедитесь, что peer добавлен после запуска Wi‑Fi и инициализации ESP‑NOW.
  • Не отправляйте новый пакет, пока callback предыдущей отправки не вернулся.
SEND_SUCCESS есть, но выход не меняется

MAC-уровень мог подтвердить кадр, но приложение могло отвергнуть его из-за длины, версии, старого seq или другого источника. Добавьте счётчики: received, valid, applied и ACK с последним применённым seq.

Связь резко хуже рядом с роутером или VTX

ESP‑NOW остаётся на выбранном Wi‑Fi-канале. Роутер или VTX 2,4 ГГц могут занимать тот же диапазон напрямую. VTX 5,8 ГГц диапазон не перекрывает, но близкое мощное радио, гармоники, плохая фильтрация или общее шумное питание всё равно способны ухудшить работу сборки. Разнесите антенны и питание, а результат оценивайте по LQ и пропускам, не только по «силе».

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

ESP32 перезагружается при движении серво

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

LQ хороший, а управление «дёргается»

Проверьте ADC стиков, фильтрацию, калибровку центра, deadband, частоту обновления PWM и гонки между callback и loop. Высокий LQ говорит только о доле принятых пакетов, а не о качестве всей цепочки управления.

Выбор решения

Как продолжить проект

Выберите следующий шаг по задаче, а не по тому, какой чип уже лежит на столе.

Стенд или робот

Оставляйте ESP‑NOW. Добавьте unicast, ключи PMK/LMK, ACK, журнал seq/LQ, watchdog и безопасный выход.

FPV-дрон

Переходите на ELRS и CRSF. Сравните диапазоны 433/900/2400 МГц по задаче, антеннам и разрешённым частотам.

Автопилот и данные

Не смешивайте RC и высокообъёмную телеметрию без расчёта полосы. Для ArduPilot откройте ELRS с QGroundControl и Mission Planner.

Маршрут дальше

Три связанных материала

Официальные источники и важные оговорки

Дальность намеренно не указана одной цифрой: она зависит от платы, антенны, ориентации, высоты, помех, питания, корпуса и выбранного режима. Любой тест на столе нужно повторять в реальных условиях, не создавая риска людям и имуществу.

Прокрутить вверх
Напишите нам