ESP-NOW — альтернативный протокол обмена данными для ESP8266 и ESP32. Основные понятия



    Технология ESP-NOW — это упрощенный протокол связи WiFi с передачей коротких пакетов между парами сопряженных устройств, разработанный и выпущенный Espressif в 2016.07 для микроконтроллеров ESP8266 и ESP32. При этом дополнительные процедуры, связанные с поддержкой протокола WiFi не используются, что ускоряет процесс обмена пакетами.

    ESP-NOW может применяться в Интернете Вещей для управления интеллектуальными источниками света, реле, розетками, другими устройствами дистанционного управления, получения информации от датчиков и других приложений.

    ESP-NOW поддерживает следующие функции


    • Зашифрованная и незашифрованная связь между сопряженными парами устройств.
    • Смешанные зашифрованная и незашифрованная связь между сопряженными устройствами.
    • Передача до 250 байт полезной информации.
    • Настройка функции обратного вызова для информирования прикладного уровня, в частности, об успешности или сбое передачи.


    ESP-NOW также имеет следующие особенности и ограничения


    • Скорость передачи — не более 1 мбит/с на частоте 2,4гГц, т.е. ESP-NOW работает на той же частоте и каналах, что и ваш роутер WiFi.
    • Протокол WiFi не используется
    • Аналогичен протоколу с низким энергопотреблением, используемому в беспроводной мыши 2,4 ГГц.
    • Требуется только начальное сопряжение.
    • После сопряжения соединение не разрывается.
    • Широковещательная передача не поддерживается — только множественная раздача сопряженным парам устройств.
    • Максимум 20 пар, включая зашифрованные, поддерживаются на одном устройстве, включая зашифрованные пары.
    • Максимум 10 зашифрованных пар поддерживаются в режиме Station.
    • Максимум 6 в режиме SoftAP или SoftAP + Station.
    • Шифрование многоадресной рассылки не поддерживается.

    Безопасность


    ESP-NOW применяет технологию фреймов IEEE802.11 Action Vendor вместе с функцией IE, разработанной Espressif, и технологией шифрования CCMP, реализуя безопасное коммуникационное решение без установления соединения. Устройство с Wi-Fi поддерживает основной мастер-ключ (PMK) и несколько локальных мастер-ключей (LMK)

    • PMK используется для шифрования LMK с помощью алгоритма AES-128.
    • LMK сопряженного устройства используется для шифрования пользовательской информации методом CCMP. Максимальное количество разных LMK — 6. Если LMK для сопряженного устройства не задан, пользовательские данные шифроваться не будут.

    Базовый уровень


    На нижнем уровне протокола ESP_NOW поддерживается связанный список, содержащий информацию о локальном устройстве и о сопряженном устройстве, в том числе MAC-адреса и ключи. ESP-NOW также хранит часто используемые данные для прикладного уровня, чтобы избежать накладных расходов на повторную обработку связанного списка. Информация об устройствах используется для отправки и получения данных и включает в себя

    Информацию о локальном устройстве:

    • PMK: 16 байт — основной мастер-ключ, который используется для шифрования ключа на присоединенном устройстве (KOK в API) ESP_NOW поддерживает PMK по умолчанию, поэтому настройка не требуется. Если необходимо, можно убедиться, что значение PMK совпадает с локальным устройством.
    • Режим: 1 байт — режим локального устройства определяющий передающий WiFi интерфейс (SoftAP или STA) ESP-NOW. Режим сопряженного устройства не влияет на какую-либо функцию, а только сохраняет информацию о режиме для прикладного уровня. В режиме STA WiFi применим только Station и SoftAP WiFi — только SoftAP.
      Режимы ESP_NOW работы локального устройства
      Режим Состояние Приоритет WiFi
      IDLE не определено передача данных не разрешена
      CONTROLLER главный STA
      SLAVE подчиненный SoftAP

      COMBO главный&подчиненный SoftAP


    Информацию о сопряженном устройстве в паре (включая часто используемую информацию и другую пользовательскую информацию):

    • LMK: 16 байт — локальный мастер-ключ, который используется для шифрования ключа полезной информации во время связи в данной паре.
    • MAC-адрес: 6 байт — адрес сопряженного устройства, совпадает с адресом отправителя. Например, если пакет отправляется со Station, MAC-адрес должен совпадать с адресом Station.
    • Режим: 1 байт — режим локального устройства определяющий передающий интерфейс (SoftAP или STA) ESP-NOW.
    • Канал: 1 байт — канал, через который обмениваются данными устройства, соединенные в пару.Может иметь значение 0..255. Канал не влияет ни на какую функцию, а только сохраняет информацию о канале для прикладного уровня. Значение определяется прикладным уровнем. Например, 0 означает, что канал не определен; 1 ~ 14 означает действительные каналы; всем остальным значениям могут быть назначены функции, которые определены прикладным уровнем.

    Espressif не рекомендует использовать продолжительные операции в функциях обратного вызова при посылке/отправке пакетов, что связано, предположительно, с реализацией алгоритмов, использующих механизм прерываний. В пользу этого предположения так же говорят и проблемы, связанные с динамическим выделением памяти в функциях обратного вызова, что решается предпочтительным использованием статических переменных, а так же неоднозначность применения механизма исключений MicroPython.

    Реализация асинхронности процессов запуска/завершения, установки связи в паре, получении/передачи пакетов Espressif не описывается, что так же не облегчает применение идеологии asyncio MicroPython.

    Формат пакета ESP-NOW


    • Заголовок MAC: 24 байта.
    • Категория: 1 байт, указывающий на категорию создателя пакета. Установлено значение (127).
    • ID организации: 3 байта, содержит уникальный идентификатор, который является первыми тремя байтами MAC-адреса, примененного Espressif. Установлено значение (0x18fe34)
    • Случайное значение: 4 байта, используется для защиты данных.
    • Данные создателя пакета: 7-255байт

    Данные создателя пакета содержат следующие поля:

    • ID: 1 байт, Установлено значение (221).
    • Длина: 1 байт, общая длина ID организации, типа, версии и пользовательских данных.
    • ID организации: 3 байта, содержит уникальный идентификатор, который является первыми тремя байтами MAC-адреса, примененного Espressif. Установлено значение (0x18fe34)
    • Тип: 1 байт, протокол ESP-NOW. Установлено значение (4)
    • Версия: 1 байт, текущая версия ESP-NOW. Установлено (1)
    • Содержимое: 0-250 байт пользовательские данные.
    • FCS: 4 байта, контрольная сумма

    Так как ESP-NOW не использует протокол WiFi, заголовок MAC немного отличается от заголовка стандартных пакетов. Биты FromDS и ToDS поля FrameControl равны 0. В первом поле адреса задан адрес назначения. Во втором поле адреса указан адрес источника. Третье поле адреса установлено как широковещательный адрес (0xff: 0xff: 0xff: 0xff: 0xff: 0xff).

    Основной алгоритм применения


    Начало и завершение


    Перед началом использования ESP-NOW рекомендуется установить интерфейс Wi-Fi в нужном режиме. Обычно интерфейс Station устанавливается для CONTROLLER, интерфейс SoftAP для SLAVE и COMBO. Так же целесообразно остановить Wi-Fi после завершения использования ESP-NOW.

    Для начала работы ESP-NOW вызвать esp_now_init() и esp_now_deinit() для завершения. Когда вызывается esp_now_deinit(), вся информация о сопряженных устройствах удаляется.

    Привязка функций обратных вызовов


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

    При использовании esp_now_register_send_cb() следует учитывать:

    В связанной паре:

    • Если прикладной уровень не получил пакет, но функция обратного вызова вернула «success», причиной может быть:
      — атаки от мошеннического устройства
      — ошибки установки зашифрованного ключа
      — потери пакетов на прикладном уровне Espressif
    • Если прикладной уровень получил пакет, но функция обратного вызова возвращает ошибку, причиной может быть:
      — Канал занят, и ACK не получен.

    При множественной связи со всеми парами локального устройства:

    • Если функция обратного вызова возвращает «success», это означает, что пакет был отправлен успешно.
    • Если функция обратного вызова возвращает ошибку, это означает, что пакет не был успешно отправлен.

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

    Добавление пары сопряженных устройств


    Прежде чем отправлять данные необходимо добавить устройство в список пар сопряженных устройств вызовом esp_now_add_peer(). Перед отправкой данных группе установленных пар необходимо добавить устройство с групповым MAC-адресом. Диапазон канала сопряженных устройств составляет от 0 до 14. Если канал установлен на 0, данные будут отправляться по текущему каналу. В противном случае канал должен быть установлен как канал, на котором находится локальное устройство.

    Безопасность


    Если ключ необходимо зашифровать, для настройки можно вызвать esp_now_set_pmk(), чтобы установить PMK. Если PMK не установлен, будет использоваться PMK по умолчанию и выбрать один и тот же ключ для всех устройств. Так же для выбранных пар установить LMK.

    Отправка данных пакетами ESP-NOW


    Для отправки данных ESP-NOW используется esp_now_send (). При этом функция, установленная ранее в esp_now_register_send_cb() вернет ESP_NOW_SEND_SUCCESS при отправке функции обратного вызова, если данные были успешно приняты на уровне MAC. В противном случае вернется ESP_NOW_SEND_FAIL. Несколько причин могут привести к тому, что ESP-NOW не сможет отправить данные. В частности,

    • целевое устройство не существует;
    • каналы устройств не совпадают;
    • данные теряются при передаче.

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

    При отправке данных ESP-NOW через esp_now_send() следует учитывать, что за один раз можно отправлять не более 250 байтов информации.

    ВНИМАНИЕ! Слишком короткий интервал между отправкой двух пакетов ESP-NOW может привести к ошибкам исполнения функции обратного вызова, в связи с чем рекомендуется отправлять следующий пакет данных ESP-NOW после того, как функция обратного вызова при обработке предыдущей отправки успешно завершилась. Функция обратного вызова отправляется из высокоприоритетной задачи Wi-Fi. Поэтому не рекомендуется выполнять продолжительные операции в функции обратного вызова. Вместо этого можно разместить необходимые данные в статическую очередь и обработать их из процессом с более низким приоритетом.

    Если функция отправки возвращает MAC-адрес, то он будет отправлен на устройство с этим MAC-адресом. Если функция отправки возвращает NULL, то пакет будет отправлен ​​всем устройствам, присоединенным к отправляющему, что может привести к сбою передачи или задержке из-за перегрузки сети.

    Получение данных пакетами ESP-NOW


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

    В заключение изложенного


    Мой опыт сборки Espressif IDE и MicroPython с ESP-NOW, описывающий ошибки, с которыми столкнулся при сборке и варианты их исправления собираюсь выложить после достижения устойчивого результата. Тогда же сделаю и описание библиотеки ESP-NOW на MicroPython с обнаруженными ошибками, способами их устранения. К сожалению, в связи с тем, что исходный код ESP-NOW закрыт и распространяется только в бинарном виде, понимание алгоритмов протокола ESP-NOW эмпирическое и существует ряд уже выявленных проблем, по которым не всегда находятся варианты их логичного преодоления, но в целом ESP-NOW успешно применяется в сообществе как C-пользователей, так и Питонистов исходя из более 300 применений, представленных на GitHub.

    Описание библиотеки ESP-NOW на С от Espressif

    Описание и открытые источники ESP-NOW на MicroPython
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 12

      0
      Аналогичен протоколу с низким энергопотреблением, используемому в беспроводной мыши 2,4 ГГц.

      Пожалуйста, уточните насколько низко в % (или с цифрами по току) в сравнении с общим потреблением и с режимом wifi.
      Можно ли уменьшить? Например уменьшением скорости обмена или периодичности посылок (или это несущественно с общим потреблением). Спасибо.

        0
        Интересное сравнение протоколов WiFi, ESP-NOW и LoRa www.youtube.com/watch?v=6NsBN42B80Q, там же приводят вариант решений для WiFi/Esp-NOW для Arduino
          0
          Японцы из M5Stack провели такое тестирование lang-ship.com/blog/work/m5stickc-esp-now-2

          Резюме
          Если вы используете ESP-NOW, потребление тока составляет около 3 мА для передачи с интервалом до 100 мс. Потребление тока увеличится примерно на 3 мА с интервалами в 10 мс
        0
        насколько низко в % (или с цифрами по току) в сравнении с общим потреблением и с режимом wifi.

        По току кушает столько же сколько и при работе wifi. Выгода во времени — в более шустром соединении и передаче пакетов.

          0
          Видимо протокол предназначен для автоматики, где нужно быстрое время реакции, для этого предусмотрено постоянное соединение. Но все равно, не понятно ограничение протокола 1 Мбит/с, если не предполагается экономия энергии.
            0

            Да там как бы и постоянного соединения нет как такового, просто шлется "The Vendor Specific Action frame", с определенным макадресом (список макадресов я так понимаю формируется на этапе привязки), принял его адресат или нет — его проблемы.
            Вобще esp now больше напоминает BLE adversing, только ездит на wifi.

              0
              А как выводить наружу информацию из сети ESP устройств, если все они будут использовать ESP-now. Например, можно ли поставить на обычный компьютер драйвера вайфай адаптера, чтобы он смог общаться с ESP-now сетью?
                0

                Самое простое — воткнуть в комп espиху и сварганить на ней мост esp-now<->ПК.
                Для линуха где то натыкался на реализацию esp-now на raw_sock, правда wifi адаптер при этом должен работать в режиме монитора.

              0

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


              Можно запрограммировать ESP-8266 так, что по включении он передаёт пакет по ESP-NOW (быстро, гораздо быстрее чем WiFi) и сразу выключается. Такая схема делает обоснованным схему запитывания от батареек, которые при этом будут жить долго.


              В сочетании с повышенной по сравнению с WiFi дальностью (умельцы показывали до 700м) применение ESP-NOW привлекательно для автономных сенсоров, до которых непрактично тянуть провода.

            0
            Можно пояснить про максимальное количество пар. Вот я хочу сделать сеть сенсоров, ставлю одну ESP в качестве центральной ноды. Сколько сенсоров на эту ноду можно подвесить? И что делать по достижении этого лимита — ставить несколько ESPшек на центральной ноде?
              0
              Сколько сенсоров на эту ноду можно подвесить?

              The maximum number of paired devices is twenty.


              И что делать по достижении этого лимита — ставить несколько ESPшек на центральной ноде?

              Как вариант — на центральной ноде перевести esp в promiscuous и разбирать все приходящие пакеты (хз правда насколько это работоспособно — надо проверять).

                0
                github.com/HarringayMakerSpace/ESP-Now — репозиторий одного из экспериментаторов ESP-NOW, возможно, подтолкнет к каким-либо решениям в Вашем случае. Вообще, нет ограничений на организацию иерархии, к примеру, я группирую информацию по территориальному признаку — котельная и находящийся рядом курятник или пасеку, собираю в более плотный пакет и переправляю тому, кто по смыслу может разумно распорядиться полученной информацией. В этом отношении интересны алгоритмы реализации mesh-сетей, которые должны позволить донести информацию от сенсоров и обратно к управляющим элементам по оптимальным маршрутам — если какой-либо узел перестал работать. Причем мне хочется это исполнить на MicroPython а не на C. Одна из вдохновляющих идей — здесь github.com/AnyMesh/anyMesh-Python

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

              Самое читаемое