Веб-сервер AJAX на ESP8266: динамическое обновление веб-страниц без их перезагрузки


Во многих приложениях интернета вещей (IoT) достаточно распространенной является ситуация, когда необходимо непрерывно, в режиме реального времени, производить мониторинг показаний с какого либо датчика. Самый простой способ сделать это – использовать модуль ESP8266 в качестве веб-сервера, на котором будет формироваться необходимая нам HTML страница с показаниями датчика (пример подобного проекта вы можете посмотреть в этой статье).

Внешний вид проекта веб-сервера AJAX на ESP8266

Но проблема при таком подходе заключается в том, что веб-браузеру необходимо будет периодически обновлять данную веб-страницу чтобы получать обновленные показания с датчика. Это не только неэффективно, но и требует значительного числа временных циклов работы процессора, во время которых он мог бы выполнять другие полезные задачи. Решение данной проблемы известно – это “Asynchronous JavaScript and XML” или, сокращенно, AJAX. С помощью технологии AJAX мы можем производить мониторинг данных в режиме реального времени без обновления всей веб-страницы, что значительно экономит ресурсы работы процессора. В данной статье мы рассмотрим использование веб-сервера с поддержкой AJAX в модуле ESP8266.

Что такое AJAX

Как мы уже выяснили ранее, AJAX расшифровывается как for “Asynchronous JavaScript and XML” и эта технология может быть использована для обновления содержимого части веб-страницы без полной перезагрузки всей страницы. Это достигается с помощью "стихийного/спонтанного" процесса запроса и приема данных. Функции AJAX’а позволяют производить обновления веб-контента асинхронно. Это означает, что браузеру нет необходимости обновлять веб-страницу целиком и он может обновить только часть контента страницы.

Примером работы технологии AJAX может служить ввод поискового запроса в поисковике Google. Как только мы в строке поиска Google начинаем вводить свой запрос, то Google сразу начинает показывать нам связанные с ним запросы. Во время этого процесса не происходит обновления содержимого всей страницы, но необходимая для обновления часть страницы обновляется в фоновом режиме с использованием AJAX.

Как работает AJAX

AJAX является комбинацией следующих элементов:

  1. XML (Extensible Markup Language – расширяемый язык разметки).
  2. JavaScript и HTML

XML – это расширяемый язык разметки. XML в основном используется для получения данных сервера в определенном формате. Хотя он может получать данные и в виде обычного текста. Когда пользователь посещает веб-страницу и происходит событие, в нашем случае это “Нажатие кнопки”, JavaScript создает объект XMLHttpRequest, который затем передает информацию в формате XML между веб-браузером и веб-сервером. Объект XMLHttpRequest отправляет запрос на обновленные данные страницы на веб-сервер, сервер обрабатывает запрос, ответ создается на стороне сервера и отправляется обратно в браузер, который затем использует JavaScript для обработки ответа и отображения его на веб-странице.

JavaScript выполняет процесс обновления в AJAX. Запрос на обновленное содержимое отформатирован в XML, чтобы сделать его понятным, а JavaScript обновляет содержимое для пользователя, просматривающего обновленную страницу.

Принцип работы AJAX наглядно показан на следующем рисунке.

Принцип работы AJAX

Как показано на приведенном рисунке, на запрос AJAX браузер отправляет запрос XMLHttpRequest на сервер с помощью javascript. Этот запрос (объект) включает дата, содержащие сведения о том, что конкретно было запрошено. Сервер в ответ передает только те данные, которые были запрошены клиентской стороной. После этого браузер получает данные и обновляет только ту часть веб-страницы, которую необходимо обновить вместо перезагрузки всей веб-страницы.

Необходимые компоненты

  1. Модуль NodeMCU ESP8266 (купить на AliExpress).
  2. Датчик температуры LM35 (купить на AliExpress).
  3. Светодиод (купить на AliExpress).
  4. Резистор 150 Ом (купить на AliExpress).
  5. Макетная плата.
  6. Соединительные провода.
  7. Кабель для программирования.

Схема проекта

Схема веб-сервера AJAX на основе NodeMCU ESP8266 представлена на следующем рисунке.

Схема веб-сервера AJAX на основе NodeMCU ESP8266Как видите, схема очень проста. Мы подключили светодиод через токоограничивающий резистор к контакту D0 платы NodeMCU ESP8266, мы будем управлять его переключениями с нашего веб-сервера. С датчика LM35 мы будем считывать показания температуры и соответствующим образом обновлять содержимое нашей веб-страницы. Датчик LM35 запитывается от контакта 3.3V платы NodeMCU ESP8266. Поскольку LM35 – это аналоговый датчик температуры, то его выходной контакт подключен к контакту A0 платы. Более подробно о подключении датчика LM35 к плате NodeMCU ESP8266 можно прочитать в этой статье.

Объяснение программы веб-сервера AJAX для модуля ESP8266

Подготовка NodeMCU ESP8266 для загрузки кода программы

Если до этого вы еще не загружали программы в вашу плату NodeMCU ESP8266, то ее необходимо подготовить для загрузки кода. Для этого выполните следующую последовательность шагов.

1. В Arduino IDE выберите пункт меню File–>Preferences–>Settings.

Выбор пункта меню File–>Preferences–>Settings в Arduino IDE

2. Введите строку https://arduino.esp8266.com/stable/package_esp8266com_index.json в поле ‘Additional Board Manager URL’ и нажмите ‘Ok’.

Добавление поддержки модуля ESP8266 в Arduino IDE

3. После этого откройте Tools > Board > Boards Manager (менеджер плат) и в поле поиска введите ESP8266, затем в открывшихся результатах поиска выберите самую последнюю версию платы и нажмите на кнопку install (установить).

Установка последней версии платы ESP8266 в Arduino IDE

4. После того как установка будет закончена, выберите пункт меню Tools ->Board -> и в нем выберите NodeMCU 1.0 (ESP-12E Module). После этого вы сможете программировать вашу NodeMCU с помощью Arduino IDE.

Создание заголовочного файла для HTML страницы

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

Сначала создайте новый файл в блокноте и сохраните его с расширением .h – это расширение для заголовочных файлов языка C. Назовите этот файл “index.h” и скопируйте в него представленный HTML код веб-страницы. Представленный код ответственен за визуальную часть нашей веб-страницы.

Примечание: не забывайте поместить этот заголовочный файл в каталог, в котором будет располагаться код нашей основной программы для NodeMCU.

Объяснение кода программы

Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.

Первым делом в программе мы подключим заголовочные файлы используемых библиотек: “ESP8266WiFi.h”, “WiFiClient.h” и “ESP8266WebServer.h”.

Далее мы подключим заголовочный файл нашей веб-страницы, который мы создали ранее. Не забудьте его поместить в тот же самый каталог, где будет находиться файл с кодом основной программы для ESP8266.

После этого укажите идентификатор сети (SSID) и пароль для вашей Wi-Fi сети – они будут необходимы чтобы ваша NodeMCU могла подключаться к сети Интернет.

Далее создадим объект ESP8266WebServer с именем "сервер" и портом по умолчанию 80.

Затем запрограммируем функцию handleRoot для обработки веб-страницы и передачи всей веб-страницы на клиентскую сторону когда это будет необходимо.

Также запрограммируем функцию sensor_data для чтения данных температуры и передачи их на веб-страницу после необходимых преобразований.

Внутри функции led_control информация, поступающая от веб-страницы, будет приниматься и сравниваться с определенными значениями чтобы управлять состоянием светодиода.

Далее, для подключения NodeMCU ESP8266 к сети Интернет, мы будем вызывать функцию WiFi.begin() с идентификатором сети и паролем в качестве аргументов. Затем мы будем проверять установлено ли соединение с сетью с помощью функции WiFi.status() и затем после успешного соединения печатать в окне монитора последовательной связи IP адрес нашей платы.

Затем мы будем вызывать функции “handleRoot”, “led_control” и “sensor_data” когда клиент будет запрашивать URL с индексами "/", “/led_set” и “/adcread”.

Тестирование работы веб-сервера AJAX

Перед тестированием работы проекта убедитесь в том, что ваш роутер включен. Подайте питанию на схему проекта. В нашем случае мы используем питание через кабель USB, но можно использовать и внешний источник питания.

Затем нам необходимо определить IP адрес платы NodeMCU ESP8266 – в нашем проекте он будет печататься в окне монитора последовательной связи Arduino IDE. Откройте окно монитора последовательной связи и нажмите кнопку сброса (Reset button) на NodeMCU один раз, после этого ее IP адрес должен напечататься в окне монитора последовательной связи. Скопируйте этот IP адрес в адресную строку вашего браузера.

Определенный IP адрес платы NodeMCU ESP8266 выведен в окно монитора последовательной связи

Убедитесь в том, что ваш компьютер и NodeMCU ESP8266 подключены к одной и той же Wi-Fi сети. После того, как вы введете IP адрес в адресную строку вашего браузера у вас в браузере должна открыться веб-страница, формируемая нашим веб-сервером на основе NodeMCU ESP8266, с которой вы сможете управлять состоянием светодиода и наблюдать показания температуры, считываемые с датчика lm35.

Веб-страница, формируемая нашим веб-сервером AJAX

Исходный код программы (скетча)

Видео, демонстрирующее работу проекта

Источник статьи

(Проголосуй первым!)
Загрузка...
6 897 просмотров

Комментарии

Веб-сервер AJAX на ESP8266: динамическое обновление веб-страниц без их перезагрузки — 11 комментариев

  1. Добрый день.
    Подскажите пож-ста, а как обновлять несколько переменных (допустим:
    Temp1(C): 0
    Temp2(C): 0
    Temp3(C): 0)
    без перезагрузки страницы?

      • HTML:
        ...

        Temp(C): 0
        Temp_1(C): 0
        Temp_2(C): 0
        LED State: NA

        ...

        // вот в этом коде так?

        function getData() {
        var xhttp = new XMLHttpRequest(); //Temp(C)
        xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
        document.getElementById("adc_val").innerHTML =
        this.responseText;
        }
        };
        xhttp.open("GET", "adcread", true);
        xhttp.send();

        var xhttp = new XMLHttpRequest(); // Temp_1(C)
        xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
        document.getElementById("adc_val_1").innerHTML =
        this.responseText;
        }
        };
        xhttp.open("GET", "adcread_1", true);
        xhttp.send();

        var xhttp = new XMLHttpRequest(); // // Temp_2(C)
        xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
        document.getElementById("adc_val_2").innerHTML =
        this.responseText;
        }
        };
        xhttp.open("GET", "adcread_2", true);
        xhttp.send();
        }

        или по другому как то?

        • А вы в html коде связали Temp(C), Temp_1(C) и Temp_2(C) с обработчиками adc_val, adc_val_1 и adc_val_2? И в скетч нужно внести изменения, вам же теперь три числа надо передавать, а не одно

          • HTML:
            ......

            Temp(C): 0
            Temp_1(C): 0
            Temp_2(C): 0
            LED State: NA

            .....

            скетч - изменения
            void sensor_data()
            {
            int a = analogRead(A0);
            int temp= a/4.35;
            String sensor_value = String(temp);
            server.send(200, "text/plane", sensor_value);
            }

            void sensor_data_1()
            {
            int a = analogRead_1(A0);
            int temp= a/4.35;
            String sensor_value = String(temp);
            server.send(200, "text/plane", sensor_value);
            }

            void sensor_data_2()
            {
            int a = analogRead_2(A0);
            int temp= a/4.35;
            String sensor_value = String(temp);
            server.send(200, "text/plane", sensor_value);
            }

            ....
            server.on("/adcread", sensor_data);
            server.on("/adcread_1", sensor_data_1);
            server.on("/adcread_2", sensor_data_2);

            получается так?

          • HTML:
            ......

            ""
            Temp(C): "0"
            Temp_1(C): "0"
            Temp_2(C): "0"
            LED State: "NA"
            ""
            .....

            без ковычек " в сообщении запись не отображается

          • HTML:
            ......

            *div**h2*
            Temp(C): *span id="adc_val"*0*/span*br*
            Temp_1(C): *span id="adc_val_1"*0*/span**br*
            Temp_2(C): *span id="adc_val_2"*0*/span**br**br*
            LED State: *span id="state"*NA*/span*
            */h2*
            .....
            произвел замену знака < на * иначе нет отображения в сообщении

            • Я понял. Это ограничения на вредоносный код в комментариях так работают, к сожалению. Я вижу что в html файле вы добавили поддержку трех переменных, а вот в скетче вы считываете всего одно значение температуры. Как вы этим одним значением собираетесь менять три ваших значения на экране?

            • Благодарю за урок, код работает (с учетом изменений в скетче)!
              Да, на каждую переменную идет свой запрос.

              А можно ли одним запросом передавать значения N переменных и затем их отображать со своими id в HTML странице. Может это JSON - но как?

              От админа: я рад что у вас получилось, но, к сожалению, на ваш очередной вопрос ответа не знаю

    • body style="background-color: #f9e79f - цвет фона
      А для изменения цвета текста нужно дописывать код, например, можно так:
      h1 style="color:#ff0000">AJAX BASED ESP8266 WEBSERVER
      То есть дописать нужно к существующему коду style="color:#ff0000"

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *