ESP32 отправляет данные на другой ESP32 без установления соединения Wi-Fi

c++ esp32 nrf24l01+ network

Изначально я создавал проект, состоящий из Atmega328P и NRF24L01, чтобы создать несколько Arduino, которые могли бы общаться друг с другом. В основном я создавал что-то вроде этого:

По мере роста сети мне начинает не хватать памяти при использовании atmega328P. Я должен быть осторожен с выделением памяти и многим другим. Поэтому я хотел бы заменить NRF24L01 на ESP32. Цена ESP-WROOM-32 сама по себе также дешевле, чем покупка NRF24L01 + atmega328.


Вопрос

Как я могу отправлять данные с одного ESP32 на другой ESP32 без установления соединения WiFi? Так же, как в NRF24L01, где вы указываете канал записи, куда вы хотите отправить данные, а другой NRF24L01 прослушивает на этой трубе.


Я знаю, что могу сделать это с помощью ESP-NOW. В этом видео объясняется, как это сделать. Проблема с ESP NOW заключается в том, что мне нужно заранее знать mac-адрес ESP32, на который я собираюсь отправить сообщение. Я планирую иметь возможность добавлять устройства для умного дома, не зная MAC-адреса.

Мой алгоритм работы с NRF24, который я уже создал, выглядит следующим образом:

  1. Главный узел прослушивает адрес 2.
  2. Если я добавлю в сеть новый узел A, он будет прослушивать адрес 1.
  3. Мастер обнаруживает все устройства с адресом 1 каждые несколько секунд.
  4. Итак, в конечном итоге узел A получает сообщение пакета обнаружения, которое исходит от мастера. Теперь узел A прослушивает случайный адрес и отвечает мастеру с этим случайным адресом.
  5. Итак, узел A теперь подключен к сети.

Самое замечательное в этом алгоритме то, что я могу добавлять в сеть новые узлы, не зная заранее их адреса. Я хотел бы сделать то же самое с ESP32. Как отправить простое сообщение между двумя модулями ESP32?

, 👍0

Обсуждение

Вы должны проверить режим сетки ..., @Majenko

если они имеют постоянную мощность, вы можете подключиться к Wi-Fi при загрузке, получить «телефонную книгу» с сервера, затем отключить Wi-Fi и запустить esp-now. Если они говорят только в одну сторону, как мои выключатели (кнопки), вам не нужно менять конфигурацию, чтобы добавить больше единиц., @dandavis


1 ответ


Лучший ответ:

1

Наконец-то я нашел способ, как это сделать. Если вы используете mac-адрес FF:FF:FF:FF:FF:FF, который работает как широковещательный адрес. Это рабочий код о том, как отправить сообщение от мастера на другой esp32, не зная его mac-адреса. Позже ведомое устройство может ответить своим реальным MAC-адресом:

Код для мастера (tx)

#include <Arduino.h>
#include <esp_now.h>
#include "WiFi.h"

uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success 1" : "Delivery Fail 1");
  if (status ==0){
    Serial.println("Delivery Success 2");
  }
  else{
    Serial.println("Delivery fail 2");
  }

  Serial.println();
}       

void setup()
{

  Serial.begin(115200);

  Serial.println("Starting...\n");

  // Установить устройство в качестве станции Wi-Fi
  WiFi.mode(WIFI_STA);

  Serial.println(WiFi.macAddress());

  // Инициируем ESP-СЕЙЧАС
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    for(;;) {      delay(1);  } // не инициализировать ждать вечно
  }

  Serial.println("initialized ESP-NOW");


  // После успешной инициализации ESPNow мы зарегистрируемся для отправки CB на
  // получаем статус переданного пакета
  esp_now_register_send_cb(OnDataSent);

   // Регистрация пира
  esp_now_peer_info_t peerInfo;
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;  
  peerInfo.encrypt = false;

   // Добавляем пир
  if (esp_now_add_peer(&peerInfo) != ESP_OK){
    Serial.println("Failed to add peer");
    for(;;) {      delay(1);  } // не инициализировать ждать вечно
  }            
}

int dataToSend = 1;
void loop()
{
    dataToSend++;

    // Отправляем сообщение через ESP-NOW (размер int 4 байта на ESP32)
    esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &dataToSend, 4);
   
    if (result == ESP_OK) {
      Serial.println("Sent with success");
    }
    else {
      Serial.println("Error sending the data");
    }

    //Serial.println(WiFi.macAddress());
    delay(1000);
}

Код подчиненного устройства (Rx)

#include <Arduino.h>
#include <esp_now.h>
#include "WiFi.h"


// Обратный вызов при получении данных
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) 
{
  int dataReceived;
  memcpy(&dataReceived, incomingData, sizeof(dataReceived));

  Serial.print("Data Received: ");
  Serial.println(dataReceived);

  Serial.println();    
}

void setup()
{

  Serial.begin(115200);
  delay(100);

  Serial.println("Starting...\n");

  // Установить устройство в качестве станции Wi-Fi
  WiFi.mode(WIFI_STA);

  // печатаем наш mac адрес
  Serial.println(WiFi.macAddress());

  // Инициируем ESP-СЕЙЧАС
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    for(;;) {      delay(1);  } // не инициализировать ждать вечно
  }
  
  Serial.println("initialized ESP-NOW");



  // Зарегистрируйтесь для callback-функции, которая будет вызываться при получении данных
  esp_now_register_recv_cb(OnDataRecv);

}

void loop()
{
}

Вы также можете ответить кодом получателя, если хотите. Это будет тот же код.

,

погуглите «уровень канала данных модели OSI» для получения дополнительной информации о уровне модели osi 2 ... доступно несколько протоколов связи ... я не знаю, какие из них реализованы модулем esp32., @jsotola

Вам даже не нужно устанавливать macAddress в FF:FF:FF:FF:FF:FF, функция esp_now_send() позволяет вам передать NULL в качестве macAddress для трансляции esp_now_send(NULL , *данные, длина). См. [документацию] (https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_now.html#_CPPv412esp_now_sendPK7uint8_tPK7uint8_t6size_t)., @hcheung

Для пиров вам также не нужно использовать физический macAddress, вы можете просто назначить локальный адрес пира каждому пиру. Преимущество этого заключается не только в том, что вы избавляетесь от проблем с поиском macAddress каждого узла, когда вы заменяете одноранговый узел и заменяете другим в будущем, вам даже не нужно изменять список одноранговых macAddresses в вашем мастер-коде., @hcheung