ESP8266:Примеры/Управление ESP8266 при помощи Android-виджета

Материал из Онлайн справочника
Перейти к: навигация, поиск

Перевод: Максим Кузьмин (Cubewriter)
Перевел 47209 статей для сайта.

Контакты:

Проверка/Оформление/Редактирование: Мякишев Е.А.


Pixel Art Mini Meow Animated.gif Черновик


Управление ESP8266 при помощи Android-виджета

В этом проекте мы воспользуемся вот этим скетчем, с помощью которого создается защищенный паролем веб-сервер, управляющий включением/выключением двух GPIO-контактов ESP8266. Этот метод требует открытия браузера и вписывания IP-адреса, но гораздо проще было бы управлять GPIO-контактами ESP8266 прямо с экрана вашего смартфона. Именно описанием этого метода мы в этом руководстве и займемся.

Необходимое оборудование

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

В самом начале скетча мы подключаем библиотеку «ESP8266WiFi», а в следующих двух строчках задаем SSID и пароль для своей WiFi-сети, чтобы ESP8266 мог к ней подключиться.

  1. // Подключаем библиотеку «ESP8266WiFi»:
  2. #include <ESP8266WiFi.h>
  3.  
  4. // Пишем SSID и пароль для своей WiFi-сети:
  5. const char* ssid = "YOUR_NETWORK_NAME";
  6. const char* password = "YOUR_NETWORK_PASSWORD";

Далее создаем объект веб-сервера и задаем ему порт «8888»:

  1. // Создаем объект веб-сервера с номером порта «8888»:
  2. WiFiServer server(8888);

Создаем переменную «header» для хранения заголовка ответа на запрос, переменные «gpio5_state» и «gpio4_state» для хранения текущего состояния этих GPIO-контактов, а также переменные «gpio5_pin» и «gpio4_pin» для хранения номеров контактов GPIO4 и GPIO5.

  1. // Создаем несколько переменных:
  2. String header;
  3. String gpio5_state = "Off";
  4. String gpio4_state = "Off";
  5. int gpio5_pin = 5;
  6. int gpio4_pin = 4;

Далее создаем блок setup(), код в котором будет запущен только раз – при запуске ESP8266.

  1. // Код в этом блоке будет запущен только один раз:
  2. void setup() {
  3. }

Запускаем последовательную коммуникацию на скорости 115200 бод (для отладки). Переключаем оба GPIO-контакта в режим вывода данных (OUTPUT) и задаем им значение «LOW».

  1. // Этот код будет запущен только один раз:
  2. void setup() {
  3.   // Инициализируем последовательную коммуникацию (для отладки):
  4.   Serial.begin(115200);
  5.   delay(10);
  6.  
  7.   // Подготавливаем GPIO-контакты:
  8.   pinMode(gpio5_pin, OUTPUT);
  9.   digitalWrite(gpio5_pin, LOW);
  10.   pinMode(gpio4_pin, OUTPUT);
  11.   digitalWrite(gpio4_pin, LOW);

В следующем фрагменте кода запускаем подключение к WiFi-сети, ждем успешного подключения и печатаем в мониторе порта IDE Arduino IP-адрес ESP8266.

  1. // Подключаемся к WiFi-сети:
  2.   Serial.println();
  3.   Serial.print("Connecting to ");
  4.            //  "Подключаемся к "
  5.  
  6.   Serial.println(ssid);
  7.  
  8.   WiFi.begin(ssid, password);
  9.  
  10.   while (WiFi.status() != WL_CONNECTED) {
  11.   delay(500);
  12.   Serial.print(".");
  13.   }
  14.   Serial.println("");
  15.   Serial.println("WiFi connected");
  16.              //  "Подключились к WiFi"
  17.  
  18.   // Запускаем веб-сервер:
  19.   server.begin();
  20.   Serial.println("Web server running. Waiting for the ESP IP...");
  21.              //  "Веб-сервер запущен.
  22.              //  "Ждем получения IP-адреса ESP8266..."
  23.   delay(1000);
  24.  
  25.   // Печатаем IP-адрес ESP8266:
  26.   Serial.println(WiFi.localIP());
  27. }

Блок loop() отвечает за то, что будет происходить, когда новый клиент установит соединение с веб-сервером. То есть код в loop() будет постоянно прослушивать новых клиентов. Соответственно, если к веб-серверу подключится новый клиент, он начнет подключаться к нему.

  1. // Код в блоке loop() будет постоянно повторяться:
  2. void loop() {
  3. // Прослушиваем новых клиентов:
  4.  WiFiClient client = server.available();

Булева переменная «blank_line» ниже служит для того, чтобы определить конец HTTP-запроса. Кроме того, в этом фрагменте кода используется цикл while(), который будет работать все то время, пока клиент будет подключен к веб-серверу.

  1. if (client) {
  2.     Serial.println("New client");  //  "Новый клиент"
  3.     // Булева переменная, предназначенная
  4.     // для определения конца HTTP-запроса:
  5.     boolean blank_line = true;
  6.     while (client.connected()) {
  7.       if (client.available()) {

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

По умолчанию именем пользователя будет «user», а паролем – «pass». Чуть ниже я расскажу о том, как их поменять. Если пользователь введет правильные имя пользователя и пароль, то получит доступ к веб-странице для управления GPIO-контактами ESP8266.

  1. // Проверяем, правильные ли введены имя пользователя и пароль:
  2. if(header.indexOf("dXNlcjpwYXNz") >= 0) {

В следующем фрагменте кода проверяется, на какую кнопку веб-страницы нажал пользователь. По сути, в нем проверяется, какой вы хотите открыть URL.

К примеру, кликая на кнопку «OFF» для контакта GPIO5, вы открываете ссылку «http://192.168.1.22:8888/gpio5off». Код смотрит на эту ссылку и при помощи нескольких else if() сверяется с тем, что ему нужно сделать. В случае со ссылкой «http://192.168.1.22:8888/gpio5off» он переключит контакт GPIO5 («gpio5_pin») в состояние «LOW».

  1.           // Проверяем, правильные ли введены
  2.           // имя пользователя и пароль:
  3.           if(header.indexOf("dXNlcjpwYXNz") >= 0) {
  4.             // Залогинивание прошло успешно:
  5.             client.println("HTTP/1.1 200 OK");
  6.             client.println("Content-Type: text/html");
  7.             client.println("Connection: close");
  8.                        //  "Соединение: отключено"
  9.             client.println();
  10.             // Включаем/выключаем GPIO-контакты:
  11.             if(header.indexOf("GET / HTTP/1.1") >= 0) {
  12.                 Serial.println("Main Web Page");
  13.                            //  "Главная веб-страница"
  14.             }  
  15.             else if(header.indexOf("GET /gpio5on HTTP/1.1") >= 0){
  16.                 Serial.println("GPIO 5 On");
  17.                            //  "Контакт GPIO5 включен"
  18.                 gpio5_state = "On";
  19.                 digitalWrite(gpio5_pin, HIGH);
  20.             }
  21.             else if(header.indexOf("GET /gpio5off HTTP/1.1") >= 0){
  22.                 Serial.println("GPIO 5 Off");
  23.                            //  "Контакт GPIO5 выключен"
  24.                 gpio5_state = "Off";
  25.                 digitalWrite(gpio5_pin, LOW);
  26.             }
  27.             else if(header.indexOf("GET /gpio4on HTTP/1.1") >= 0){
  28.                 Serial.println("GPIO 4 On");
  29.                            //  "Контакт GPIO4 включен"
  30.                 gpio4_state = "On";
  31.                 digitalWrite(gpio4_pin, HIGH);
  32.             }
  33.             else if(header.indexOf("GET /gpio4off HTTP/1.1") >= 0){
  34.                 Serial.println("GPIO 4 Off");
  35.                            //  "Контакт GPIO4 выключен"
  36.                 gpio4_state = "Off";
  37.                 digitalWrite(gpio4_pin, LOW);
  38.             }

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

Более подробно о Bootstrap можно почитать по этой ссылке.

На веб-странице будет 4 кнопки для включения/выключения (переключения между состояниями «HIGH» и «LOW») двух светодиодов, подключенных к контактам GPIO5 и GPIO4.

Кнопки – это HTML-теги <a href=””></a> с CSS-классом, который придает им вид кнопки. Когда вы нажимаете на кнопку, вам открывается другая страница с URL, соответствующим этой кнопке. Именно так ESP8266 и узнает, что ей нужно сделать (т.е. включить или выключить светодиод, и какой именно).

  1. // Ваша веб-страница:
  2. client.println("<!DOCTYPE HTML>");
  3. client.println("<html>");
  4. client.println("<head>");
  5. client.println("<meta name=\"viewport\" content=\"width=device-width, initialscale=1\">");
  6. client.println("<link rel=\"stylesheet\"
  7. href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css\">");
  8. client.println("</head><div class=\"container\">");
  9. client.println("<h1>Web Server</h1>");
  10. client.println("<h2>GPIO 5 - Current State: " + gpio5_state);
  11. client.println("<div class=\"row\">");
  12. client.println("<div class=\"col-md-2\"><a href=\"/gpio5on\" class=\"btn btn-block
  13. btn-lg btn-success\" role=\"button\">ON</a></div>");
  14. client.println("<div class=\"col-md-2\"><a href=\"/gpio5off\" class=\"btn btn-block
  15. btn-lg btn-danger\" role=\"button\">OFF</a></div>");
  16. client.println("</div>");
  17. client.println("<h2>GPIO 4 - Current State: " + gpio4_state);
  18. client.println("<div class=\"row\">");
  19. client.println("<div class=\"col-md-2\"><a href=\"/gpio4on\" class=\"btn btn-block
  20. btn-lg btn-success\" role=\"button\">ON</a></div>");
  21. client.println("<div class=\"col-md-2\"><a href=\"/gpio4off\" class=\"btn btn-block
  22. btn-lg btn-danger\" role=\"button\">OFF</a></div>");
  23. client.println("</div></div></html>");

Если вы введете неправильные имя пользователя и пароль, в браузере будет напечатано сообщение «Authentication failed» («Аутентификация не удалась»).

  1. // Неправильные имя пользователя и пароль,
  2. // поэтому HTTP-запрос завершился неудачей...
  3. else {
  4.  client.println("HTTP/1.1 401 Unauthorized");
  5.  client.println("WWW-Authenticate: Basic realm=\"Secure\"");
  6.  client.println("Content-Type: text/html");
  7.  client.println();
  8.  client.println("<html>Authentication failed</html>");
  9. }

Строчки кода в конце скетча очищают переменную «header», завершают цикл loop() и завершают подключение.

  1.         header = "";
  2.         break;
  3.         }
  4.         if (c == '\n') {
  5.           // Когда нужно перейти к следующей строчке:
  6.           blank_line = true;
  7.         }
  8.         else if (c != '\r') {
  9.           // Когда в текущей строке найден символ:
  10.           blank_line = false;
  11.         }
  12.       }
  13.     }  
  14.     // Завершаем подключение к клиенту:
  15.     delay(1);
  16.     client.stop();
  17.     Serial.println("Client disconnected.");
  18.                //  "Клиент отключился."
  19.   }
  20. }

Как задать собственные имя пользователя и пароль

В скетче, который мы разобрали выше, именем пользователя является «user», а паролем – «pass». Уверен, вы захотите задать вместо них собственные имя пользователя и пароль. Пройдите по этой ссылке. В первом поле впишите следующее:

your_username:your_password

Примечание: Обратите внимание, что между именем пользователя и паролем нужно вписать «:».

В моем случае это «user:pass».

Затем нажмите на зеленую кнопку «Encode» – это сгенерирует строку в формате Base64. В моем случае это «dXNlcjpwYXNz».

Скопируйте ее и вставьте в это место скетча:

  1. // Проверяем, правильные ли введены имя пользователя и пароль:
  2. if(header.indexOf("dXNlcjpwYXNz") >= 0) {

Совет: Эта 80-ая строчка скетча, и в ней также присутствует оператор if().

Загружаем код

Подключите ESP8266 к ПК и откройте IDE Arduino. Кликните по «Инструменты» > «Плата» (Tools > Board) и выберите подключенную плату.

Выберите COM-порт, к которому подключена ваша плата.

Проверив все настройки, нажмите на кнопку «Загрузка» (Upload):

Upload button.png

Подождите несколько секунд, пока не увидите сообщение «Загрузка завершена» (Done uploading) в левом нижнем углу IDE Arduino.

Копируем IP-адрес ESP8266

Загрузив веб-серверный скетч на ESP8266, кликните в IDE Arduino на «Инструменты» > «Монитор порта» (Tools > Serial Monitor). Монитор порта – это окно, где ESP8266, загрузившись, напечатает свой IP-адрес.

Мой IP-адрес – это «192.168.1.22» (см. на скриншоте ниже). Ваш IP-адрес, скорее всего, будет другим. Сохраните его, т.к. позднее вы с его помощью перейдете на страницу веб-сервера.

Esp8266 protected web server serial monitor ip address 1.PNG

Важно: Выставьте скорость монитора порта на 115200 бод, иначе вы просто ничего не увидите.

Проблема – В мониторе порта не печатается IP-адрес

Если у вас возникла такая проблема, можно попробовать сделать следующее:

  1. Оставьте монитор порта открытым;
  2. ESP-12E (или FTDI-программатор) должен оставаться подключенным к ПК;
  3. Перезапустите ESP-12E, нажав на встроенную в него кнопку.

Спустя секунду ESP8266 должна напечатать в мониторе порта свой IP-адрес.

Устанавливаем программу для сканирования IP-адресов

Если IP-адрес в мониторе порта по-прежнему не появляется, то вам нужно будет установить на свой ПК программу для сканирования IP-адресов. Она будет искать все девайсы в вашей сети.

  1. Загрузите ее (это бесплатно). Можете выбрать между Advanced IP Scanner (Windows) и Angry IP Scanner (MAC OS X, Windows или Linux);
  2. Установите программу (в это время ESP8266 должен быть включен, и на нем должен работать скетч, написанный нами выше);
  3. Откройте программу для сканирования IP-адресов и нажмите на кнопку «Сканировать» (Scan);

Дайте процессу завершиться (это должно занять несколько минут).

Заходим на веб-сервер

Перед заходом на веб-сервер нужно сделать следующее:

  • Перезапустите ESP8266;
  • Откройте браузер;
  • Впишите в его адресную строку IP-адрес, скопированный ранее из монитора порта IDE Arduino, и добавьте в конце «8888» (в моем случае – «192.168.1.22:8888»);
  • Нажмите на  ↵ Enter .

После этого в браузере должно выскочить окно с запросом ввести имя пользователя и пароль:

Esp8266 secure web server auth window 1.PNG
  • Введите имя пользователя и пароль
  • Залогиньтесь

В результате в браузере должна загрузиться примерно такая страница:

Esp8266 secure web server main page 1.PNG

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

Устанавливаем приложение HTTP Request Shortcuts

Для этого проекта мы воспользуемся бесплатным Android-приложением HTTP Request Shortcuts, позволяющим выполнять HTTP-запросы GET/POST простым нажатием на кнопку прямо на домашнем экране смартфона, избавляя от необходимости вбивать IP-адрес ESP8266 в браузер.

Поищите в онлайн-магазине Google Play Store «HTTP Request Shortcuts», а затем установите приложение. Далее кликните на кнопку «Открыть».

HTTP Request Shortcuts google play 1.jpg

Создаем кнопку «ON» («ВКЛ») для контакта GPIO5

Чтобы создать виджет, при нажатии переключающий контакт GPIO5 в состояние «ON», кликните по синей кнопке с плюсом в правом нижнем углу приложения.

HTTP Request Shortcuts main page.jpg

Выберите пункт «From scratch».

HTTP Request Shortcuts menu create 1.jpg

Вы можете задать следующие настройки виджета:

  • Shortcut name (Название виджета): ON – GPIO5;
  • Иконка: Изображение, показываемое на домашнем экране смартфона;
  • Method (Тип запроса): GET;
  • URL (ссылка): Здесь нужно вписать «http://IP_АДРЕС_ВАШЕЙ_ESP:8888/gpio5on». В моем случае получилась ссылка «http://192.168.1.22:8888/gpio5on»;
HTTP Request Shortcuts edit shortcuts 1.jpg
  • Authentication Method (Метод аутентификации) – Basic Authentication (Базовая аутентификация)
  • Username (Имя пользователя) – user
  • Password (Пароль) – pass
HTTP Request Shortcuts edit shortcuts 2.jpg
  • Response Type (Тип ответа) – Simple Toast (Простое уведомление)
  • Timeout (Таймаут) – short (3 seconds) (короткий (3 секунды))
  • Delay execution (Задержка выполнения) – No delay (Без задержки)
  • When not connected to the internet (Когда не подключен к интернету) – drop the request (отклонить запрос)
HTTP Request Shortcuts edit shortcuts 3.jpg
HTTP Request Shortcuts edit shortcuts 4.jpg

Чтобы сохранить настройки, кликните на галочку в правом верхнем углу экрана.

Создаем кнопку «OFF» («ВЫКЛ») для контакта GPIO5

Нам также нужно будет создать кнопку «OFF» для контакта GPIO5. Вот ее настройки:

  • Shortcut name: OFF – GPIO5;
  • Иконка. Изображение, показываемое на домашнем экране смартфона;
  • Method: GET;
  • URL: Здесь нужно вписать «http://IP_АДРЕС_ВАШЕЙ_ESP:8888/gpio5off». В моем случае получилась ссылка «http://192.168.1.22:8888/gpio5off»;
  • Authentication Method: Basic Authentication;
  • Username: user;
  • Password: pass;
  • Response Type: Simple Toast;
  • Timeout: short (3 seconds);
  • Delay execution: No delay;
  • When not connected to the internet: drop the request;

Чтобы сохранить настройки, нажмите на галочку в правом верхнем углу экрана.

Добавляем виджеты на домашний экран

Чтобы добавить виджет на домашний экран смартфона, просто зажмите кнопку «ON – GPIO 5».

HTTP Request Shortcuts edit shortcuts 11.jpg

В появившемся меню выберите пункт «Place on home screen» (Разместить на домашнем экране). Потом сделайте то же самое для виджета «OFF – GPIO 5».

HTTP Request Shortcuts edit shortcuts 6.jpg

Тестируем

Обе иконки должны появиться на домашнем экране смартфона. Теперь попробуйте понажимать на виджеты. Если при нажатии на них GPIO-контакты ESP8266 меняют значение с «ON» на «OFF» и обратно, то все работает как надо.

HTTP Request Shortcuts edit shortcuts 5.jpg

Вот и все. Код, загруженный на ESP8266, также готов для управления контактом GPIO4. Поэтому рекомендую проделать для его настройки все те же шаги, что и для настройки GPIO5. Кроме того, этот проект можно без труда перенастроить и под управление другими устройствами.

Схема

Загрузив код на ESP8266, подключите компоненты друг к другу, как показано на схеме ниже (для подключения светодиодов можно воспользоваться резисторами номиналом между 270 Ом и 470 Ом).

Esp8266 two leds protected web server 1.png

Код

  1. /*********
  2.   Rui Santos
  3.   Complete project details at http://randomnerdtutorials.com  
  4. *********/
  5.  
  6. // Including the ESP8266 WiFi library
  7. #include <ESP8266WiFi.h>
  8.  
  9. // Replace with your network details
  10. const char* ssid = "YOUR_NETWORK_NAME";
  11. const char* password = "YOUR_NETWORK_PASSWORD";
  12.  
  13. // Web Server on port 8888
  14. WiFiServer server(8888);
  15.  
  16. // variables
  17. String header;
  18. String gpio5_state = "Off";
  19. String gpio4_state = "Off";
  20. int gpio5_pin = 5;
  21. int gpio4_pin = 4;
  22.  
  23. // only runs once
  24. void setup() {
  25.   // Initializing serial port for debugging purposes
  26.   Serial.begin(115200);
  27.   delay(10);
  28.  
  29.   // preparing GPIOs
  30.   pinMode(gpio5_pin, OUTPUT);
  31.   digitalWrite(gpio5_pin, LOW);
  32.   pinMode(gpio4_pin, OUTPUT);
  33.   digitalWrite(gpio4_pin, LOW);
  34.  
  35.   // Connecting to WiFi network
  36.   Serial.println();
  37.   Serial.print("Connecting to ");
  38.   Serial.println(ssid);
  39.  
  40.   WiFi.begin(ssid, password);
  41.  
  42.   while (WiFi.status() != WL_CONNECTED) {
  43.     delay(500);
  44.     Serial.print(".");
  45.   }
  46.   Serial.println("");
  47.   Serial.println("WiFi connected");
  48.  
  49.   // Starting the web server
  50.   server.begin();
  51.   Serial.println("Web server running. Waiting for the ESP IP...");
  52.   delay(1000);
  53.  
  54.   // Printing the ESP IP address
  55.   Serial.println(WiFi.localIP());
  56. }
  57.  
  58. // runs over and over again
  59. void loop() {
  60.   // Listenning for new clients
  61.   WiFiClient client = server.available();
  62.  
  63.   if (client) {
  64.     Serial.println("New client");
  65.     // boolean to locate when the http request ends
  66.     boolean blank_line = true;
  67.     while (client.connected()) {
  68.       if (client.available()) {
  69.         char c = client.read();
  70.         header += c;
  71.  
  72.         if (c == '\n' && blank_line) {
  73.  
  74.           // checking if header is valid
  75.           // dXNlcjpwYXNz = 'user:pass' (user:pass) base64 encode
  76.    
  77.           Serial.print(header);
  78.          
  79.           // Finding the right credential string
  80.           if(header.indexOf("dXNlcjpwYXNz") >= 0) {
  81.             //successful login
  82.             client.println("HTTP/1.1 200 OK");
  83.             client.println("Content-Type: text/html");
  84.             client.println("Connection: close");
  85.             client.println();
  86.             // turns the GPIOs on and off
  87.             if(header.indexOf("GET / HTTP/1.1") >= 0) {
  88.                 Serial.println("Main Web Page");
  89.             }  
  90.             else if(header.indexOf("GET /gpio5on HTTP/1.1") >= 0){
  91.                 Serial.println("GPIO 5 On");
  92.                 gpio5_state = "On";
  93.                 digitalWrite(gpio5_pin, HIGH);
  94.             }
  95.             else if(header.indexOf("GET /gpio5off HTTP/1.1") >= 0){
  96.                 Serial.println("GPIO 5 Off");
  97.                 gpio5_state = "Off";
  98.                 digitalWrite(gpio5_pin, LOW);
  99.             }
  100.             else if(header.indexOf("GET /gpio4on HTTP/1.1") >= 0){
  101.                 Serial.println("GPIO 4 On");
  102.                 gpio4_state = "On";
  103.                 digitalWrite(gpio4_pin, HIGH);
  104.             }
  105.             else if(header.indexOf("GET /gpio4off HTTP/1.1") >= 0){
  106.                 Serial.println("GPIO 4 Off");
  107.                 gpio4_state = "Off";
  108.                 digitalWrite(gpio4_pin, LOW);
  109.             }
  110.             // your web page
  111.             client.println("<!DOCTYPE HTML>");
  112.             client.println("<html>");
  113.             client.println("<head>");
  114.             client.println("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
  115.             client.println("<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css\">");                                                                    
  116.             client.println("</head><div class=\"container\">");
  117.             client.println("<h1>Web Server</h1>");
  118.             client.println("<h2>GPIO 5 - Current State: " + gpio5_state);          
  119.             client.println("<div class=\"row\">");
  120.             client.println("<div class=\"col-md-2\"><a href=\"/gpio5on\" class=\"btn btn-block btn-lg btn-success\" role=\"button\">ON</a></div>");
  121.             client.println("<div class=\"col-md-2\"><a href=\"/gpio5off\" class=\"btn btn-block btn-lg btn-danger\" role=\"button\">OFF</a></div>");                                                                    
  122.             client.println("</div>");
  123.             client.println("<h2>GPIO 4 - Current State: " + gpio4_state);      
  124.             client.println("<div class=\"row\">");
  125.             client.println("<div class=\"col-md-2\"><a href=\"/gpio4on\" class=\"btn btn-block btn-lg btn-success\" role=\"button\">ON</a></div>");                                                                    
  126.             client.println("<div class=\"col-md-2\"><a href=\"/gpio4off\" class=\"btn btn-block btn-lg btn-danger\" role=\"button\">OFF</a></div>");
  127.             client.println("</div></div></html>");    
  128.           }
  129.        // wrong user or passm, so http request fails...  
  130.         else {            
  131.            client.println("HTTP/1.1 401 Unauthorized");
  132.            client.println("WWW-Authenticate: Basic realm=\"Secure\"");
  133.            client.println("Content-Type: text/html");
  134.            client.println();
  135.            client.println("<html>Authentication failed</html>");
  136.         }  
  137.         header = "";
  138.         break;
  139.         }
  140.         if (c == '\n') {
  141.           // when starts reading a new line
  142.           blank_line = true;
  143.         }
  144.         else if (c != '\r') {
  145.           // when finds a character on the current line
  146.           blank_line = false;
  147.         }
  148.       }
  149.     }  
  150.     // closing the client connection
  151.     delay(1);
  152.     client.stop();
  153.     Serial.println("Client disconnected.");
  154.   }
  155. }

См.также

Внешние ссылки