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

—

от автора

От переводчика. На шестом уроке мы добрались до практически полезного кода — с его помощью можно создать работающий пример «бесшовного» автоматического взаимодействия между клиентом (страницей в веб-браузере) и 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»).

В скетч 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 <SPI.h> #include <Ethernet.h>  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("<!DOCTYPE html>");                         client.println("<html>");                                                  // Заголовок веб-страницы и встроенный в неё код JavaScript                         client.println("<head>");                         client.println("<title>Arduino Web Page</title>");                         client.println("<script>");                         client.println("function GetSwitchState() {");                         client.println("nocache = \"&nocache=\"\                                                          + Math.random() * 1000000;");                         client.println("var request = new XMLHttpRequest();");                         client.println("request.onreadystatechange = function() {");                         client.println("if (this.readyState == 4) {");                         client.println("if (this.status == 200) {");                         client.println("if (this.responseText != null) {");                         client.println("document.getElementById(\"switch_txt\")\ .innerHTML = this.responseText;");                         client.println("}}}}");                         client.println(                         "request.open(\"GET\", \"ajax_switch\" + nocache, true);");                         client.println("request.send(null);");                         client.println("setTimeout('GetSwitchState()', 1000);");                         client.println("}");                         client.println("</script>");                         client.println("</head>");                          // Тело веб-страницы                         client.println("<body onload=\"GetSwitchState()\">");                         client.println("<h1>Arduino AJAX Switch Status</h1>");                         client.println(                         "<p id=\"switch_txt\">Switch state: Not requested...</p>");                         client.println("</body>");                         client.println("</html>");                     }                     // Выводим принятый 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() в скетче).

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

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

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

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

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

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

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

client.println("<body onload=\"GetSwitchState()\">"); 

Ежесекундные 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.


ссылка на оригинал статьи https://habr.com/ru/company/timeweb/blog/717772/


Комментарии

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

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