Веб-сервер в режиме точки доступа на Arduino UNO WiFi Rev2

Узнайте, как настроить плату в качестве точки доступа (AP), позволяя другим устройствам подключаться к ней.

Введение

В этом руководстве мы создадим так называемую точку доступа (Access Point). Точка доступа — это, по сути, беспроводная локальная сеть, которая в данном руководстве не будет подключена к Интернету. Это может быть практичным решением для проектов, не имеющих доступа к Интернету, но при этом нам всё равно нужно управлять и контролировать плату Arduino UNO WiFi Rev2 по беспроводной связи. Мы будем использовать функции библиотеки WiFiNINA, и настроим базовую конфигурацию, которая позволит нам управлять светодиодом (включение или выключение) и считывать значение с одного из аналоговых пинов.

Необходимое оборудование и программное обеспечение

Совет

Вы также можете использовать встроенный светодиод на Arduino UNO WiFi Rev2.

Схема подключения

Следуйте схеме подключения ниже, чтобы подключить светодиод к плате.

Схема подключения

Схема подключения.


Создание точки доступа

В этом руководстве практически не используется внешнее оборудование: нам нужен только светодиод, которым мы будем управлять удалённо. Но самые интересные аспекты заключаются в библиотеке, которую мы будем использовать: WiFiNINA. Эту библиотеку можно использовать для множества различных проектов с подключением, где мы можем как подключаться к WiFi, выполнять GET-запросы, так и — как мы рассмотрим в этом руководстве — создавать точку доступа (AP) и размещать веб-сервер, к которому можно подключиться.

Мы пройдём следующие шаги для создания веб-сервера на Arduino UNO WiFi Rev2:

  • Сначала нам нужно инициализировать библиотеку WiFiNINA.

  • Затем нам нужно создать учётные данные нашей точки доступа, введя SSID (имя сети) и PASS (пароль сети).

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

  • На телефоне или ноутбуке мы теперь можем найти точку доступа в списке доступных Wi-Fi сетей. Мы можем подключиться, используя тот же пароль, который мы создали в программе.

  • После подключения к Wi-Fi мы можем подключиться к конкретному IP-адресу платы с помощью обычного браузера (например, Chrome, Firefox).

  • Пока мы подключены, программа обнаруживает это и входит в цикл while().

  • В цикле while() две ссылки просто выводятся в формате HTML, который отображается в браузере.

  • Эти ссылки управляют светодиодом, подключённым к плате — просто «ON» (Вкл) или «OFF» (Выкл).

  • Если мы нажмём ссылку «ON», программа настроена на добавление «H» в конец URL, а если мы нажмём ссылку «OFF», мы добавим «L» в конец URL.

  • Если URL заканчивается на «H», светодиод включится, а если заканчивается на «L» — выключится. H означает «HIGH» (высокий уровень), а L — «LOW» (низкий уровень).

  • Также есть поле, отображающее значение, считанное с аналогового пина 1 (A1). Поскольку к нему ничего не подключено, мы будем считывать случайные значения.

И это та конфигурация, которую мы будем использовать в данном руководстве. Есть ещё несколько дополнительных функций, таких как проверка наличия последней прошивки и использования правильной платы, и эти потенциальные ошибки будут выводиться в Serial Monitor.

Программирование платы

  1. Сначала убедимся, что у нас установлены драйверы. Если мы используем Cloud Editor, ничего устанавливать не нужно. Если мы используем офлайн-редактор, нужно установить их вручную. Это можно сделать, перейдя в Tools > Board > Board Manager…. Здесь нам нужно найти Arduino megaAVR Boards и установить его.

  2. Теперь нам нужно установить необходимую библиотеку. Если мы используем Cloud Editor, ничего устанавливать не нужно. Если мы используем офлайн-редактор, просто перейдите в Tools > Manage libraries.. и найдите WiFiNINA и установите её.

  3. Теперь давайте рассмотрим некоторые основные функции этого скетча:

  • char ssid[] = "" — хранит имя сети.

  • char pass[] = "" — хранит пароль сети.

  • WiFi.begin(ssid) — создаёт открытую сеть.

  • WiFiServer server(80) — создаёт сервер, который прослушивает входящие подключения на указанном порту.

  • WiFiClient client — создаёт клиента, который может подключаться к указанному IP-адресу в Интернете.

  • server.begin() — указывает серверу начать прослушивание входящих подключений.

  • client.connected — проверяет наличие подключённых клиентов.

  • client.available — проверяет наличие доступных данных.

  • client.read — считывает доступные данные.

  • client.print() — выводит что-либо клиенту (например, HTML-код).

  • client.stop() — закрывает соединение.

Загрузите код на плату, убедившись, что выбраны правильная плата и порт.

Важно

Значения ssid и pass должны содержать минимум 8 символов.

#include <WiFiNINA.h>

char ssid[] = "yourNetwork";        // SSID вашей сети (имя)
char pass[] = "yourPassword";    // пароль вашей сети (используйте для WPA или как ключ для WEP)
int keyIndex = 0;                // номер индекса ключа вашей сети (нужен только для WEP)

int led =  LED_BUILTIN;
int status = WL_IDLE_STATUS;
WiFiServer server(80);

void setup() {
  //Инициализация Serial и ожидание открытия порта:
  Serial.begin(9600);
  while (!Serial) {
    ; // ожидание подключения последовательного порта. Нужно только для нативного USB-порта
  }

  Serial.println("Access Point Web Server");

  pinMode(led, OUTPUT);      // устанавливаем режим пина светодиода

  // проверка наличия WiFi модуля:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // не продолжаем
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // выводим имя сети (SSID);
  Serial.print("Creating access point named: ");
  Serial.println(ssid);

  // Создаём открытую сеть. Измените эту строку, если хотите создать сеть WEP:
  status = WiFi.beginAP(ssid, pass);
  if (status != WL_AP_LISTENING) {
    Serial.println("Creating access point failed");
    // не продолжаем
    while (true);
  }

  // ожидание 10 секунд для подключения:
  delay(10000);

  // запускаем веб-сервер на порту 80
  server.begin();

  // вы подключены, поэтому выводим статус
  printWiFiStatus();
}


void loop() {
  // сравниваем предыдущий статус с текущим
  if (status != WiFi.status()) {
    // статус изменился, обновляем переменную
    status = WiFi.status();

    if (status == WL_AP_CONNECTED) {
      // устройство подключилось к AP
      Serial.println("Device connected to AP");
    } else {
      // устройство отключилось от AP, и мы снова в режиме прослушивания
      Serial.println("Device disconnected from AP");
    }
  }

  WiFiClient client = server.available();   // прослушиваем входящих клиентов

  if (client) {                             // если есть клиент,
    Serial.println("new client");           // выводим сообщение в последовательный порт
    String currentLine = "";                // создаём строку для хранения входящих данных от клиента
    while (client.connected()) {            // цикл, пока клиент подключён
      if (client.available()) {             // если есть байты для чтения от клиента,
        char c = client.read();             // читаем байт, затем
        Serial.write(c);                    // выводим его в Serial Monitor
        if (c == '\n') {                    // если байт — символ новой строки

          // если текущая строка пуста, значит мы получили два символа новой строки подряд.
          // это конец HTTP-запроса клиента, поэтому отправляем ответ:
          if (currentLine.length() == 0) {
            // HTTP-заголовки всегда начинаются с кода ответа (например, HTTP/1.1 200 OK)
            // и типа контента, чтобы клиент знал, что следует далее, затем пустая строка:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // содержимое HTTP-ответа следует после заголовка:
            client.print("Click <a href=\"/H\">here</a> turn the LED on<br>");
            client.print("Click <a href=\"/L\">here</a> turn the LED off<br>");

            int randomReading = analogRead(A1);
            client.print("Random reading from analog pin: ");
            client.print(randomReading);

            // HTTP-ответ заканчивается ещё одной пустой строкой:
            client.println();
            // выходим из цикла while:
            break;
          }
          else {      // если получили символ новой строки, очищаем currentLine:
            currentLine = "";
          }
        }
        else if (c != '\r') {    // если получили что-то кроме символа возврата каретки,
          currentLine += c;      // добавляем к концу currentLine
        }

        // Проверяем, был ли запрос клиента "GET /H" или "GET /L":
        if (currentLine.endsWith("GET /H")) {
          digitalWrite(led, HIGH);               // GET /H включает светодиод
        }
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(led, LOW);                // GET /L выключает светодиод
        }
      }
    }
    // закрываем соединение:
    client.stop();
    Serial.println("client disconnected");
  }
}

void printWiFiStatus() {
  // выводим SSID сети, к которой подключены:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // выводим IP-адрес WiFi-модуля:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // выводим, куда перейти в браузере:
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);

}

Тестирование

После успешной загрузки кода откройте Serial Monitor — он должен выглядеть как на изображении ниже.

Информация, выведенная в Serial Monitor

Информация, выведенная в Serial Monitor.

Это означает, что мы успешно создали точку доступа. Чтобы подключиться к ней, можно использовать ноутбук или смартфон с поддержкой Wi-Fi. Нам нужно будет отключиться от текущей Wi-Fi сети, поэтому проще использовать телефон для подключения. Перейдите в настройки телефона и откройте список Wi-Fi сетей. Имя сети, которое мы создали ранее, должно появиться в списке — для подключения нужно ввести пароль, который мы задали.

Поиск платы и подключение к ней

Поиск платы и подключение к ней.

После подключения к Wi-Fi мы можем ввести URL (IP-адрес платы) в браузере. Это тот адрес, который был выведен в Serial Monitor. Теперь мы должны увидеть практически пустую страницу с двумя ссылками в верхнем левом углу: «Click here to turn the LED on» и «Click here to turn the LED off», а также текст: «Random reading from analog pin: xxx». В зависимости от того, используете ли вы компьютер или телефон, страница будет выглядеть как на изображении ниже.

Доступ к плате через браузер

Доступ к плате через браузер.

При взаимодействии со ссылками вы должны увидеть, как светодиод, подключённый к пину 2, включается и выключается в зависимости от того, что вы нажимаете, и теперь мы успешно создали способ удалённого взаимодействия с Arduino UNO WiFi Rev2. Каждый раз, когда мы нажимаем на эти ссылки, Serial Monitor будет выводить информацию о запросах, как показано на изображении ниже.

Клиент подключён

Клиент подключён.

Устранение неполадок

Если код не работает, вот некоторые распространённые проблемы, которые может потребоваться устранить:

  • Не обновлена последняя прошивка для платы.

  • Не установлен пакет плат (Board Package), необходимый для платы.

  • Не установлена библиотека WiFiNINA.

  • Не введены SSID и PASS: помните, они чувствительны к регистру.

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

Заключение

В этом руководстве мы узнали, как создать точку доступа и как разместить веб-сервер, к которому можно подключиться. Мы научились управлять светодиодом удалённо, а также отображать значение аналогового пина в браузере. Этот метод может быть очень полезен при создании беспроводной системы датчиков и исполнительных устройств. Если у вас есть несколько плат с поддержкой Wi-Fi, мы также можем подключить их к одной и той же точке доступа.