цифровая электроника
вычислительная техника
встраиваемые системы

 



Связь между двумя ESP32 через интернет

Автор: Mike(admin) от 11-04-2019, 04:55

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


Связь между двумя ESP32 через интернет

Обычно подключаемые проекты имеют веб-интерфейс или мобильный интерфейс. Если вы хотите контролировать одну вещь посредством другой, особенно с низкой задержкой и через Интернет, это довольно сложно достичь. В этом деле пригодится такой проект как этот. Это шаблон инфраструктуры Arduino, показывающий, как соединить две платы на основе ESP32 через Интернет, сводя к минимуму задержку с помощью функции автоматического восстановления в случае обрыва соединения Wi-Fi или временного отключения питания одной из подключенных плат. Эта концепция работает, если платы ESP32 находятся в одной сети Wi-Fi и если они находятся в разных сетях, даже на разных континентах.


Функциональность шаблона проекта по умолчанию – двунаправленное управление светодиодами кнопками разных плат ESP32. Вы также можете рассматривать этот шаблон как интернет-коммуникатор с азбукой Морзе. Не стесняйтесь заменять код для управления кнопками и светодиодами на любые необходимые операции ввода/вывода.


В проекте мы создаем две задачи: первая для управления подключением Wi-Fi, а вторая – для обмена данными между устройствами.


Задача Wi-Fi создается для автоматического переключения на другую сеть Wi-Fi в случае разрыва текущего соединения. В разделе конфигурации (строки 7–40 исходного кода) вы можете жестко закодировать несколько учетных данных сети Wi-Fi – это удобное решение, так вам не нужно перепрограммировать свои платы, если вы включаете их в разных местах. Вот код данной задачи:



void taskWifi( void * parameter ) {
 while (1) {
   for (int i = 0; i < NUM_NETWORKS; i++) {
     Serial.print("Connecting to ");
     Serial.print(ssidTab[i]);
     WiFi.begin(ssidTab[i], passwordTab[i]);
     for (int j = 0; j < 10; j++) {
       if (WiFi.status() != WL_CONNECTED) {
         delay(500);
         Serial.print(".");
       } else {
         Serial.println("done");
         Serial.print("IP address: ");
         Serial.println(WiFi.localIP());
#if DEV_TYPE == 0
         Husarnet.join(husarnetJoinCode, hostName0);
#elif DEV_TYPE == 1
         Husarnet.join(husarnetJoinCode, hostName1);
#endif
         Husarnet.start();
         while (WiFi.status() == WL_CONNECTED) {
           delay(500);
         }
       }
     }
   }
 }

По сути, благодаря этим двум строкам создается сеть виртуальной локальной сети между устройствами ESP32:



Husarnet.join(husarnetJoinCode, hostNameX);
Husarnet.start();

Устройства идентифицируются по именам хостов, поэтому вам не нужно беспокоиться о поиске IP-адресов. Соединение также полностью зашифровано, безопасно и конфиденциально. Это работает не только в локальной сети, но и через Интернет, потому что подключение осуществляется через Husarnet (husarnet.com). Husarnet помогает только в установлении соединения через Интернет, а пользовательские данные не пересылаются его серверами. Благодаря этому задержка меньше.


Устройства ESP32 пингуют друг друга каждые 4 секунды. Если в течение более 6 секунд пинг не получен, цикл соединения разрывается и ожидает подключения второго устройства. Поскольку цель проекта состояла в том, чтобы сделать его простым, мы не создаем двоичные кадры, не используем буфер протокола и т. д. В зависимости от вашего приложения вы можете легко изменить это.



void taskConnection( void * parameter ) {
 uint8_t oldState = btn.getLastButtonState();
 while (1) {
   while (WiFi.status() != WL_CONNECTED) {
     delay(500);
   }
#if DEV_TYPE == 0
   server.begin();
   Serial.println("Waiting for client");
   do {
     delay(500);
     client = server.available();
     client.setTimeout(3);
   } while (client < 1);
#elif DEV_TYPE == 1
   Serial.printf("Connecting to %s\r\n", hostName0);
   while (client.connect(hostName0, port) == 0) {
     delay(500);
   }
#endif
   Serial.printf("Client connected: %d\r\n", (int)client.connected());
   unsigned long lastMsg = millis();
   auto lastPing = 0;
   while (client.connected()) {
     //ping RX
     if (millis() - lastMsg > 6000) {
       Serial.println("ping timeout");
       break;
     }
     //ping TX
     auto now = millis();
     if (now > lastPing + 4000) {
       client.print('p');
       lastPing = now;
     }
     if (oldState != btn.getLastButtonState()) {
       oldState = btn.getLastButtonState();
       if (oldState == 0) {
         client.print('a');
       } else {
         client.print('b');
       }
     }
     if (client.available()) {
       char c = client.read();
       if (c == 'p') {
         lastMsg = millis();
       }
       if (c == 'a') {
         digitalWrite(LED_PIN, HIGH);
       }
       if (c == 'b') {
         digitalWrite(LED_PIN, LOW);
       }
       Serial.printf("read: %c\r\n", c);
     }
   }
   client.stop();
   Serial.println("Client disconnected.");
   Serial.println("");
 }
}

Поговорим теперь о подключении аппаратной части. Подключите кнопку между контактом P22 и GND. Подключите светодиод и резистор последовательно между контактом P16 и GND. Подключите аккумулятор к вашей плате на базе ESP32. В проекте мы используем ESP32 devkit со встроенным LDO. Посмотрите на максимальный уровень входного напряжения на вашей плате на базе ESP32, чтобы избежать повреждения.


Теперь позаботимся о программном обеспечении. Подключите библиотеку acebutton, найдя ее в менеджере библиотек.


Связь между двумя ESP32 через интернетСвязь между двумя ESP32 через интернет

Затем установим поддержку ESP32-Husarnet. Откройте Настройки Aduino IDE (Preferences), добавьте ссылку https://files.husarion.com/arduino/package_esp32_husarnet_index.json через Additional Board Manager URLs. Откройте менеджер плат (Boards manager) и найдите esp32-husarnet. Нажмите кнопку установки.


Связь между двумя ESP32 через интернет

Из списка плат выберете ESP32 Arduino (Husarnet). Откройте проект ESP32_ledstrip_webserver.ino. Измените строку 25 вашим кодом присоединения Husarnet (возьмите на https://app.husarnet.com).


Связь между двумя ESP32 через интернет

Измените строки 28 - 38, чтобы добавить свои учетные данные сети Wi-Fi. Сделайте все то же самое со второй платой, изменив только значение в строке 9 с 0 на 1. Включите оба модуля ESP32 и подождите около 15 секунд, чтобы устройства ESP32 подключились к сети Wi-Fi и установили соединение P2P (работает как в локальной сети, так и через Интернет). Вот полный код программы.



#include <WiFi.h>
#include <Husarnet.h>
#include <AceButton.h>

using namespace ace_button;

#define DEV_TYPE 0    // type "0" for 1st ESP32, and "1" for 2nd ESP32

const int BUTTON_PIN = 22;
const int LED_PIN = 16;

const char* hostName0 = "esp2esp0";
const char* hostName1 = "esp2esp1";


const char* husarnetJoinCode = "xxxxxxxxxxxxxxxxxxxxxx";

#define NUM_NETWORKS 2

const char* ssidTab[NUM_NETWORKS] = {
  "wifi-ssid-one",
  "wifi-ssid-two",
};

const char* passwordTab[NUM_NETWORKS] = {
  "wifi-pass-one",
  "wifi-pass-two",
};

AceButton btn(BUTTON_PIN);

HusarnetClient client;

uint16_t port = 8001;

#if DEV_TYPE == 0
HusarnetServer server(port);
#endif

void handleEvent(AceButton*, uint8_t, uint8_t);
void taskWifi( void * parameter );
void taskConnection( void * parameter );

void setup() {
  Serial.begin(115200);

  pinMode(BUTTON_PIN, INPUT_PULLUP);
  btn.setEventHandler(handleEvent);

  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  xTaskCreate(
    taskWifi,
    "taskWifi",
    10000,
    NULL,
    1,
    NULL);

  xTaskCreate(
    taskConnection,
    "taskConnection",
    10000,
    NULL,
    1,
    NULL);
}

void loop() {
  while (1) {
    btn.check();
    delay(1);
  }
}

void handleEvent(AceButton* button, uint8_t eventType,
                 uint8_t buttonState) {
  switch (eventType) {
    case AceButton::kEventPressed:
      Serial.println("pressed");
      break;
    case AceButton::kEventReleased:
      Serial.println("released");
      break;
  }
}

void taskWifi( void * parameter ) {
  while (1) {
    for (int i = 0; i < NUM_NETWORKS; i++) {
      Serial.print("Connecting to ");
      Serial.print(ssidTab[i]);
      WiFi.begin(ssidTab[i], passwordTab[i]);
      for (int j = 0; j < 10; j++) {
        if (WiFi.status() != WL_CONNECTED) {
          delay(500);
          Serial.print(".");
        } else {
          Serial.println("done");
          Serial.print("IP address: ");
          Serial.println(WiFi.localIP());
#if DEV_TYPE == 0
          Husarnet.join(husarnetJoinCode, hostName0);
#elif DEV_TYPE == 1
          Husarnet.join(husarnetJoinCode, hostName1);
#endif
          Husarnet.start();
          while (WiFi.status() == WL_CONNECTED) {
            delay(500);
          }
        }
      }
    }
  }
}

void taskConnection( void * parameter ) {
  uint8_t oldState = btn.getLastButtonState();

  while (1) {
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
    }

#if DEV_TYPE == 0

    server.begin();
    Serial.println("Waiting for client");

    do {
      delay(500);
      client = server.available();
      client.setTimeout(3);
    } while (client < 1);

#elif DEV_TYPE == 1

    Serial.printf("Connecting to %s\r\n", hostName0);
    while (client.connect(hostName0, port) == 0) {
      delay(500);
    }

#endif

    Serial.printf("Client connected: %d\r\n", (int)client.connected());

    unsigned long lastMsg = millis();
    auto lastPing = 0;

    while (client.connected()) {
      if (millis() - lastMsg > 6000) {
        Serial.println("ping timeout");
        break;
      }

      auto now = millis();
      if (now > lastPing + 4000) {
        client.print('p');
        lastPing = now;
      }

      if (oldState != btn.getLastButtonState()) {
        oldState = btn.getLastButtonState();
        if (oldState == 0) {
          client.print('a');
        } else {
          client.print('b');
        }
      }

      if (client.available()) {
        char c = client.read();

        if (c == 'p') {
          lastMsg = millis();
        }
        if (c == 'a') {
          digitalWrite(LED_PIN, HIGH);
        }
        if (c == 'b') {
          digitalWrite(LED_PIN, LOW);
        }

        Serial.printf("read: %c\r\n", c);
      }
    }
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}



© digitrode.ru


Теги: ESP32




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

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

Оставить комментарий
  • Группа: Гости
  • ICQ:
  • Регистрация: --
  • Статус:
  • Комментариев: 0
  • Публикаций: 0
^
Спасибо за интересный пример!
Подскажите пожалуйста -- какова задержка приема-передачи данных в этом проекте?
Т.е. если первый ESPЗ2 нажимает кнопку -- через какое время будет засвечен светодиод на втором ESP32 ?
  • Группа: Гости
  • ICQ:
  • Регистрация: --
  • Статус:
  • Комментариев: 0
  • Публикаций: 0
^
установил загрузил.... но в списке не могу найти ESP32 Arduino (Husarnet).
  • Группа: Гости
  • ICQ:
  • Регистрация: --
  • Статус:
  • Комментариев: 0
  • Публикаций: 0
^
Как можно передать сигнал яркости светодиода при помощи переменого резистора

Как можно передать яркость светодиода при помощи переменого резистора