[Перевод] Starting Electronics: руководство по веб-серверам на Arduino. Часть 6. Автоматическое AJAX взаимодействие с веб-сервером

ljldh5pcgoxkys7hmrkx54fzeqy.jpeg

От переводчика. На шестом уроке мы добрались до практически полезного кода — с его помощью можно создать работающий пример «бесшовного» автоматического взаимодействия между клиентом (страницей в веб-браузере) и Arduino веб-сервером, который передаёт данные о состоянии подключённого оборудования и внутренних переменных.

Тут нужно помнить, что это только «концептуальный» и базовый пример такого взаимодействия, максимально упрощённый для лучшего понимания начинающими сути самой технологии. Когда вы поймёте принцип, то далее сможете как угодно улучшать и модернизировать этот код. Например, уделить внимание его быстродействию и безопасности.
При помощи небольшой модификации HTML и JavaScript кода в скетче Arduino из предыдущей части этого руководства, можно заставить веб-сервер автоматически обновлять статус кнопки на веб-странице. Ручное инициирование AJAX запросов, которое использовалось в предыдущей части, больше не нужно.

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

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


Скетч AJAX веб-сервера Arduino


Используйте то же оборудование, что и в предыдущей части этого руководства:

  • Контроллер Arduino Uno
  • Плата Ethernet Shield
  • Кнопка
  • Резистор 10 кОм
  • Соединительные провода


Кнопка подключается к плате Arduino/Ethernet Shield так, как показано на принципиальной схеме ниже. В изначальном состоянии вывод D3 контроллера подтянут к земле при помощи резистора 10 кОм (низкий потенциал, LOW или »0»), а после нажатия кнопки на вывод D3 подаётся высокий потенциал (HIGH или »1»).

xf-7tkqiqot8lgybnuhkrglkgfk.png

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

Модифицированный скетч:

/*--------------------------------------------------------------
  Скетч:      eth_websrv_AJAX_switch_auto

  Описание:  Arduino веб-сервер, отображающий состояние кнопки на веб-странице при помощи AJAX. Состояние кнопки обновляется автоматически.
  
  Оборудование: контроллер Arduino Uno, плата Ethernet Shield, кнопка.
                
  Программное обеспечение: среда разработки Arduino IDE
  
  Ссылки:
    - WebServer example by David A. Mellis and modified by Tom Igoe
    - Ethernet library documentation: http://arduino.cc/en/Reference/Ethernet
    - Learning PHP, MySQL & JavaScript by Robin Nixon, O'Reilly publishers

  Дата создания:         13 февраля 2013
 
  Автор:       W.A. Smith, http://startingelectronics.org
--------------------------------------------------------------*/

#include 
#include 

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(10, 0, 0, 20); // IP-адрес (нужно изменить на актуальный для вашей сети)
EthernetServer server(80);

String HTTP_req; // для хранения HTTP запроса

void setup() {
    Ethernet.begin(mac, ip);
    server.begin();
    Serial.begin(115200);
    pinMode(3, INPUT); // кнопка подключена к плате Arduino на пин D3
}

void loop() {
    EthernetClient client = server.available();

    if (client) {  // got client?
        boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {
                char c = client.read(); // получаем очередной байт (символ) от клиента
                HTTP_req += c; // сохраняем символ HTTP запроса
                if (c == '\n' && currentLineIsBlank) {
                    // Посылаем http заголовок
                    client.println("HTTP/1.1 200 OK");
                    client.println("Content-Type: text/html");
                    client.println("Connection: keep-alive");
                    client.println();

                    if (HTTP_req.indexOf("ajax_switch") > -1) {
                        // AJAX запрос состояния кнопки
                        GetSwitchState(client);
                    }
                    else {
                        // Посылка веб-страницы, содержащей JavaScript код и AJAX вызовы
                        client.println("");
                        client.println("");
                        
                        // Заголовок веб-страницы и встроенный в неё код JavaScript
                        client.println("");
                        client.println("Arduino Web Page");
                        client.println("");
                        client.println("");

                        // Тело веб-страницы
                        client.println("");
                        client.println("

Arduino AJAX Switch Status

"); client.println( "

Switch state: Not requested...

"); client.println(" "); client.println(""); } // Выводим принятый HTTP запрос в Serial Serial.print(HTTP_req); HTTP_req = ""; // очищаем строку запроса break; } if (c == '\n') { currentLineIsBlank = true; } else if (c != '\r') { currentLineIsBlank = false; } } // end if (client.available()) } // end while (client.connected()) delay(1); client.stop(); } // end if (client) } // loop // Посылка данных о состоянии кнопки браузеру void GetSwitchState(EthernetClient cl) { if (digitalRead(3)) { cl.println("Switch state: ON"); } else { cl.println("Switch state: OFF"); } }

Изменения в HTML и JavaScript коде


Ниже показаны изменения, внесенные в HTML файл, который скетч Arduino отправляет в веб-браузер (этот файл отправляется построчно с помощью функции client.println () в скетче).

vyiiri3p5l_vjcbbayissbbx_aw.jpeg

Модифицированный код веб-страницы для работы автоматических AJAX запросов.

Код кнопки веб-страницы


Во-первых, удаляется код, который создает кнопку на веб-странице, поскольку эта кнопка больше не нужна. На изображении выше он закомментирован.

Вызов функции GetSwitchState ()


Функция GetSwitchState (), которая раньше вызывалась при нажатии кнопки на веб-странице, теперь автоматически вызывается при загрузке страницы. Это достигается добавлением её вызова в тег body ().

Примечание переводчика: здесь речь идёт о JavaScript функции GetSwitchState (), а не об одноимённой Arduino функции, которая занимается определением состояния кнопки, подключённой к серверу.

Эта строка добавляется в HTML код веб-страницы при помощи вызова следующей функции:

client.println("");


Ежесекундные AJAX вызовы


Если мы не предпримем специальных действий и не изменим код для осуществления периодических вызовов, функция GetSwitchState () будет вызвана только один раз при загрузке веб-страницы.

Следующая строка кода добавляется в конец функции GetSwitchState (), чтобы эта функция автоматически вызывалась каждую секунду:

setTimeout('GetSwitchState()', 1000);


Эта строка JavaScript кода вызывает функцию GetSwitchState () (саму себя) каждые 1000 миллисекунд (каждую секунду). Таким образом каждую секунду выполняется AJAX запрос, который получает информацию о состоянии кнопки и обновляет её на веб-странице.

Этот код добавляется на веб-страницу при помощи следующей строки в Arduino скетче:

client.println("setTimeout('GetSwitchState()', 1000);");

От переводчика о 6-й части


Если в двух словах резюмировать произведённые автором руководства улучшения предыдущего скетча, то он просто добавил на страницу JavaScript код, который автоматически раз в секунду вызывает функцию GetSwitchState (), которая, в свою очередь, автоматически, без участия пользователя, производит AJAX запросы к Arduino серверу.

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

Этот пример реализует однонаправленную передачу информации (о состоянии кнопки) сервер — клиент, если сюда добавить ещё и передачу (пользовательских) данных от клиента к серверу, то мы получим полностью интерактивную и двунаправленную систему.

Часть 1, часть 2, часть 3, часть 4, часть 5.

p-u9l27ynelxi92bcmdxhu76ma8.png

© Habrahabr.ru