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

skylekvnny5pg5yy33bgppvyat8.jpeg

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

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

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

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


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


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

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

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

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


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


Флажок снят


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

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

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

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

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


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

0qpwagkhjaurcbahcj94dw3ulk0.jpeg
Флажок установлен

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

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

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

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

Новые HTML теги


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

HTML тег


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

HTML тег


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

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

  • 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 
#include 

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("LED2");
    }
    else {              // выключаем светодиод
        digitalWrite(2, LOW);
        // checkbox is unchecked
        cl.println("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("");
                    client.println("");
                    client.println("");
                    client.println("Arduino LED Control");
                    client.println("");
                    client.println("");
                    client.println("

LED

"); client.println("

Click to switch LED on and off.

"); client.println(""); ProcessCheckbox(client); // вызов функции работы со светодиодом client.println(""); client.println(" "); client.println(""); 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.

p-u9l27ynelxi92bcmdxhu76ma8.png

© Habrahabr.ru