Starting Electronics: руководство по веб-серверам на Arduino. Часть3. Управление светодиодом с веб-страницы

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.


От переводчика. Поскольку при переводе и публикации на Хабре некоторые разделы оригинального руководства были скомпонованы друг с другом, то нумерация частей оригинала и перевода не совпадает — у нас это 3-я часть, а в оригинале — 5-я.

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

Мы уже умеем работать с веб-страницами, хранить их на SD карте памяти, а теперь ещё научимся в динамике управлять подключённым оборудованием.

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

Видео работы сервера и управления светодиодом с веб-страницы:


Сборка сервера и подключение светодиода


На фото ниже показано подключение светодиода к контроллеру Arduino. Светодиод подключён последовательно с резистором 470 Ом между выводом D2 контроллера и землёй (GND).

SD-карта в этом варианте веб-сервера не используется.


Аппаратное обеспечение веб-сервера для управления светодиодом

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


Веб-страница и HTML


Флажок снят


Страница веб-сервера содержит код, который позволяет с помощью флажка LED2 включить и выключить светодиод. Внешний вид веб-страницы:


Страница LED веб-сервера — флажок снят

HTML код, посылаемый веб-сервером браузеру:


HTML код (флажок снят)

Флажок установлен


После установки флажка для включения светодиода, веб-страница и HTML код выглядят так:


Флажок установлен

Обратите внимание, что после того как флажок был установлен, браузер добавил /?LED2=2 к URL адресу.


HTML код веб-страницы с установленным флажком

Здесь видно, что HTML код страницы, посылаемой сервером браузеру, изменился — было добавлено слово checked, что приводит к отображению на веб-странице установленного флажка.

Примечание переводчика. Тут важный момент опущен в умолчании и читателю может быть не совсем понятна логическая связь: браузер добавляет «/?LED2=2» к URL, а веб-сервер, реагируя на это дополнение, изменяет содержание самой веб-страницы, т. е. добавляет в неё «checked».

Новые HTML теги


В вышеприведенном коде страницы присутствуют два новых HTML тега: <form> и <input>.

HTML тег <form>


Форма (<form>) может содержать различные управляющие элементы, например такие как флажок, используемый в этом примере. Здесь method=«get» в открывающем теге формы приводит к отправке данных серверу с использованием HTTP GET запроса. Это также приводит к добавлению /?LED2=2 в URL адрес.

HTML тег <input>


С помощью тега <input> в HTML-форму могут быть добавлены различные управляющие элементы. Тег <input> одиночный и не имеет соответствующей закрывающей части.

В этом примере <input> используется для создания флажка. В этот тег входят следующие поля:

  • type=«checkbox» — отображает управляющий элемент в виде флажка;
  • name=«LED2» — имя элемента управления;
  • value=«2» — определяемое пользователем значение;
  • onclick=«submit();» — отправить данные формы при клике на элемент управления (флажок);
  • checked — признак установки флажка.

HTTP запрос и ответ


При установке флажка на веб-странице генерируется HTTP GET запрос, который отправляет имя и значение этого флажка на сервер.

Ниже приведен пример HTTP запроса, отправленного из браузера на сервер Arduino после установки флажка:

GET /?LED2=2 HTTP/1.1
Host: 10.0.0.20
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-ZA,en-GB;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://10.0.0.20/
Connection: keep-alive

При снятии флажка, из браузера на сервер Arduino отправляется следующий HTTP запрос:

GET / HTTP/1.1
Host: 10.0.0.20
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-ZA,en-GB;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://10.0.0.20/?LED2=2
Connection: keep-alive

Контроллер Arduino считывает заголовок HTTP запроса и проверяет наличие в нём текста «LED2=2», и, при его нахождении, включает и выключает светодиод.

Оба вышеуказанных запроса содержат текст «LED2=2», но разных местах. При установке флажка этот текст является частью строки GET запроса, а при снятии — частью Referer.

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

Скетч LED веб-сервера


Код скетча Arduino LED веб-сервера представлен ниже:

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

   Описание:  Arduino сервер с веб-страницей для управления светодиодом
  
  Оборудование:
    - Arduino Uno
    - Ethernet Shield
    - LED (D2)
    - Resistor 470 Ohm
                
  Программное обеспечение: среда разработки Arduino IDE, веб-страница в файле index.htm
  
  Ссылки:
    - WebServer example by David A. Mellis and modified by Tom Igoe
    - Ethernet library documentation: http://arduino.cc/en/Reference/Ethernet

  Дата создания:         11 января 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 запроса
boolean LED_status = 0;   // состояние светодиода, по умолчанию выключен

void setup() {
    Ethernet.begin(mac, ip);
    server.begin();
    Serial.begin(115200);
    pinMode(2, OUTPUT);       // светодиод на D2
}

// Изменение состояния светодиода и посылка HTML кода состояния флажка
void ProcessCheckbox(EthernetClient cl) {
    if (HTTP_req.indexOf("LED2=2") > -1) {  // определения наличия флажка
        // изменяем статус светодиода
        if (LED_status) {
            LED_status = 0;
        }
        else {
            LED_status = 1;
        }
    }
    
    if (LED_status) {    // включаем светодиод
        digitalWrite(2, HIGH);
        // checkbox is checked
        cl.println("<input type=\"checkbox\" name=\"LED2\" value=\"2\" \
        onclick=\"submit();\" checked>LED2");
    }
    else {              // выключаем светодиод
        digitalWrite(2, LOW);
        // checkbox is unchecked
        cl.println("<input type=\"checkbox\" name=\"LED2\" value=\"2\" \
        onclick=\"submit();\">LED2");
    }
}

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

    if (client) {
        boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {
                char c = client.read(); // читаем 1 байт (символ) из запроса
                HTTP_req += c;  // добавляем полученный символ к строке запроса
                if (c == '\n' && currentLineIsBlank) {
                    client.println("HTTP/1.1 200 OK");
                    client.println("Content-Type: text/html");
                    client.println("Connection: close");
                    client.println();
                    // send web page
                    client.println("<!DOCTYPE html>");
                    client.println("<html>");
                    client.println("<head>");
                    client.println("<title>Arduino LED Control</title>");
                    client.println("</head>");
                    client.println("<body>");
                    client.println("<h1>LED</h1>");
                    client.println("<p>Click to switch LED on and off.</p>");
                    client.println("<form method=\"get\">");

                    ProcessCheckbox(client); // вызов функции работы со светодиодом

                    client.println("</form>");
                    client.println("</body>");
                    client.println("</html>");
                    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)
}

Работа скетча


Этот скетч является модифицированной версией скетча eth_websrv_page из урока «Базовый веб-сервер на Arduino».

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

Функция ProcessCheckbox() проверяет, содержит ли в HTTP запросе текст «LED2=2». Если HTTP запрос действительно содержит этот текст, то состояние светодиода будет изменяться, а также соответствующим образом будет изменяться и сама веб-страница отправляемая браузеру.

Улучшения скетча


Этот скетч был сделан максимально простым для наилучшего понимания принципов его работы, но в него можно внести улучшения и сделать его более функциональным.

Сейчас скетч проверяет только само наличие текста «LED2=2» в HTTP запросе, чтобы определить был ли установлен флажок или нет. Было бы лучше проверять где (в какой строке) находится текст «LED2=2» в HTTP сообщении. Это позволило бы избежать возможную рассинхронизацию состояния светодиода и отображения этого состояния на веб-странице.

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


Вот мы уже добрались до управления оборудованием с веб-страницы. Если вы внимательно прошли все предыдущие уроки, то уже можете самостоятельно экспериментировать с вышеприведённым кодом и начать управлять не только светодиодом, но и другими компонентами, например, реле. Вы можете также самостоятельно модифицировать скетч и добавить работу с несколькими актуаторами.

Переведённых частей становится всё больше, вот ссылки на предыдущие части руководства:

Часть 1, часть 2.


Источник: https://habr.com/ru/company/timeweb/blog/712120/


Интересные статьи

Интересные статьи

Долгое время беспроводные сети WiFi предполагали наличие проводной сети между точками доступа. Даже название «точка доступа» предполагает, что эти устройства работают на уровне доступа для подключен...
Подразделение Microsoft Research недавно опубликовало предварительный выпуск Lean 4. Предыдущие версии Lean были сосредоточены на том, чтобы быть помощником по доказ...
Роботом-пылесосом iRobot Roomba можно управлять голосовыми командами, запуская уборку или отправляя пылесос в док-станцию. Я уже рассказывал о том, как «общаться» с Roomba через сервер io...
Когда я только начал своё путешествие к науке о данных, я потратил много времени на то, чтобы понять, с чего начать, что я должен узнать в первую очередь и какие ресурсы должен использова...
Shell wallpaper by manapi Отладка сценариев bash — это как поиск иголки в стоге сена, тем более, когда новые дополнения появляются в существующей кодовой базе без своевременного ...