====== Управление миниботом через Wi-Fi ======

===== Описание =====
В этом проекте мы подключим нашего робота к сети Wi-Fi, чтобы управлять им через интернет-страницу. Для этого построим страницу с кнопками действий и при нажатии на кнопку робот будет двигаться в указанную сторону 5 секунд.

===== Дополнительные модули =====
Предполагается что у Вас уже есть набор Минибот, и вы собрали его по инструкции в руководстве пользователя. Тогда дополнительно понадобится: 

^ Что нужно                                                                                                               ^  Кол-во, шт  ^
| [[https://smartelements.ru/collection/svyaz/product/wifi-modul-esp-12|Wi-Fi модуль ESP-12 (5 В)]] |  1           |
| [[https://smartelements.ru/collection/provoda-i-kabeli/product/nabor-provodov-20-sht-20sm-mama-mama|Провода мама-мама]] |  4           |


===== Библиотеки =====
  * [[http://files.smartelements.ru/know_libs/robotSE.zip|Библиотека robotSE (для робота)]]
  * [[http://files.smartelements.ru/know_libs/WiFiEsp.zip|Библиотека для WiFi]]
  * [[http://files.smartelements.ru/know_libs/AltSoftSerial.zip|Библиотека для эмуляции сериал соединения]]


<WRAP center round tip 80%>
Перед началом работы с WiFi-модулем настройте его на скорость обмена в 9600 бод. О том как это сделать, рассказано [[main:comm:esp12#Установка скорости обмена данными|на этой странице]].
</WRAP>
===== Порядок действий =====
==== Шаг 1. Пересоберите робота ====
  - С помощью отвёртки, входящей в комплект набора, снимите с платформы модуль ИК-приёмника
  - С помощью отвёртки, входящей в комплект набора, прикрепите на место модуля ИК-приёмника - [[https://smartelements.ru/collection/svyaz/product/wifi-modul-esp-12|Wi-Fi модуль]]
  - Присоедините Wi-Fi модуль с помощью проводов мама-мама к выводам мотор шилда по следующей схеме:

^ Вывод модуля^ Вывод шилда  |
| +            | +             |
| -            | -             |
| TX           | 8             |
| RX           | 9             |

==== Шаг 2. Установите библиотеки ====
Установите в Arduino IDE библиотеки, которые представлены по ссылкам выше. О том как устанавливаются библиотеки описано в руководстве пользователя, входящем в комплект, либо посетите соответствующий [[main:info:libs|раздел Базы Знаний]].



==== Шаг 3. Загрузите скетч на контроллер ====
Измените в скетче значения переменных **char ssid[]** = "SmartElements"; //имя сети wifi и **char pass[]** = "12345678"; //пароль от сети wifi на свои (имя вашей сети и пароль к ней).

<file Arduino>
#include "WiFiEsp.h" //подключение библиотеки WiFiEsp
#include <robotSE.h> //подключение библиотеки для работы с платформой.
#include <AltSoftSerial.h> //подключение библиотеки для эмуляции сериал соединения

AltSoftSerial wifiSerial; //создание виртуального сериал соединения (на 8 и 9 выводах)
 
char ssid[] = "SmartElements"; //имя сети wifi
char pass[] = "12345678"; //пароль от сети wifi
int status = WL_IDLE_STATUS; //статус сети wifi

robotSE robot; //создание объекта робота

WiFiEspServer server(80); //переменная для создания объекта сервера
 
//использование кольцевого буфера для увеличения скорости
RingBuffer buf(8);

/* Отправка и формирование страницы - ответа
 *  на сервер 
 */
void sendHttpResponse(WiFiEspClient& client)
{
  //формирование интернет-страницы
  client.print(
      "HTTP/1.1 200 OK\r\n"
      "Content-Type: text/html\r\n"
      "Connection: close\r\n" 
      "\r\n");
  client.print("<!DOCTYPE HTML>\r\n");
  client.print("<html>\r\n");
  client.print("<head>\r\n");
  client.print("<meta charset=\"utf-8\">\r\n");
  client.print("<title>Робопульт</title>\r\n");
  client.print("<style>\r\n");
  client.print(
      ".c {\r\n"
      "border: 1px solid #333;\r\n"
      "display: inline-block;\r\n" 
      "padding: 5px 15px;\r\n"       
      "text-decoration: none;\r\n"
      "color: #000;\r\n"
      "}\r\n");
  client.print("</style>\r\n");
  client.print("</head>\r\n");
  client.print("<div style=\"text-align:center;\">\r\n");
  client.print("<a href=\"/F\" class=\"c\">Вперёд</a>\r\n");
  client.print("<br><br>\r\n");
  client.print("<a href=\"/L\" class=\"c\">Влево</a>\r\n");
  client.print("<a href=\"/S\" class=\"c\">Стоп</a>\r\n");
  client.print("<a href=\"/R\" class=\"c\">Вправо</a>\r\n");
  client.print("<br><br>\r\n");
  client.print("<a href=\"/B\" class=\"c\">Назад</a>\r\n");
  client.print("</head>\r\n");
  client.print("</html>\r\n");
}
 
/* Вывод состояния сети и адреса для подключения к моджулю  
 */
void printWifiStatus()
{
  //вывод названия сети
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
 
  //вывод полученного модулем IP-адреса
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
 
  //вывод информации о адресе в браузере
  Serial.println();
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
  Serial.println();
}
 
void setup()
{
  //инициализация Serial-соединения для отладки
  Serial.begin(9600);
  //инициализация Serial-соединения для ESP-модуля
  wifiSerial.begin(9600);
  //инициализация ESP модуля
  WiFi.init(&wifiSerial);
 
  //проверка существования модуля
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi module not present");
    //если модуля нет, то не продолжать работу далее
    while (true);
  }
 
  //попытка подключения к wifi сети
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: "); //вывод надписи о попытке подключения
    Serial.println(ssid); //вывод названия сети
    //подключение к сети, используя имя и пароль
    status = WiFi.begin(ssid, pass);
  }
 
  Serial.println("You're connected to the network"); //вывод сообщения о подключении
  printWifiStatus(); //вывод статуса подключения
 
  //инициализация веб-сервера на порту № 80
  server.begin();
}
 
 
void loop()
{
  WiFiEspClient client = server.available();  //ожидание входящих клиентов
 
  if (client) {                               //если получен клиент,
    Serial.println("New client");             //вывести сообщение в Serial-порт
    buf.init();                               //инициализация буфера
    while (client.connected()) {              //цикл, пока клиент подключен
      if (client.available()) {               //если от клиента есть байты для чтения,
        char c = client.read();               //прочитать байт, а затем
        buf.push(c);                          //добавить его в буфер
 
        //если в строке получены два символа завершения строки
        //значит - это конец HTTP запроса, так что нужно отправить ответ
        if (buf.endsWith("\r\n\r\n")) {
          sendHttpResponse(client);
          break;
        }
 
        //проверить если запрос был одним из: "GET /R", "GET /G" или "GET /B":
        if (buf.endsWith("GET /F")) { //запрос изменения состояния красного цвета
          Serial.println("Forward"); //вывод отладочной информации
          robot.move_forward(); //движение робота вперед
          delay(5000); //задержка на 5 секунд
          robot.move_stop(); //остановка робота
        } else if (buf.endsWith("GET /L")) { //запрос изменения состояния зелёного цвета
          Serial.println("Left"); //вывод отладочной информации
          robot.move_left(); //движение робота влево
          delay(5000); //задержка на 5 секунд
          robot.move_stop(); //остановка робота
        } else if (buf.endsWith("GET /R")) { //запрос изменения состояния синего цвета
          Serial.println("Right"); //вывод отладочной информации
          robot.move_right(); //движение робота вправо
          delay(5000); //задержка на 5 секунд
          robot.move_stop(); //остановка робота
        } else if (buf.endsWith("GET /B")) { //запрос изменения состояния синего цвета
          Serial.println("Back"); //вывод отладочной информации
          robot.move_back(); //движение робота назад
          delay(5000); //задержка на 5 секунд
          robot.move_stop(); //остановка робота
        } else if (buf.endsWith("GET /S")) { //запрос изменения состояния синего цвета
          Serial.println("Stop"); //вывод отладочной информации
          robot.move_stop(); //остановка робота
        }
      }
    }
 
    //закрытие соединения
    client.stop();
    Serial.println("Client disconnected"); //вывод информации об отключении
  }
}
</file>

==== Шаг 4. Тестирование ====
После загрузки скетча, оставьте робота подключенным к компьютеру и откройте в Arduino IDE монитор порта. Для этого воспользуйтесь меню //Инструменты - Монитор порта//.
В скетче мы выводим отладочную информацию в монитор сериал порта. В том числе туда выводится информация о том, какой IP-адрес получил робот в вашей домашней сети. 

При старте работы информация в мониторе порта будут примерно такого вида:
<file>
[WiFiEsp] Initilization successful - 1.5.4
Attempting to connect to WPA SSID: SmartElements
[WiFiEsp] Connected to SmartElements
You're connected to the network
SSID: SmartElements
IP Address: 192.168.1.182

To see this page in action, open a browser to http://192.168.1.182

[WiFiEsp] Server started on port 80
</file>

Таким образом мы видим адрес, где мы должен появиться сайт нашего робота.

==== Шаг 5. Сайт ====
Откройте браузер на компьютере и зайдите на интернет-сайт, полученный в предыдущем шаге. Вы должны увидеть такую страницу:

{{ :http:know.smartelements.ru_main:upgkits:робопульт.jpg?nolink |}}

Нажмите на кнопку и убедитесь что робот выполняет команды.

++++Особенности при нажатии на кнопки|В связи с тем что мы используем эмуляцию сериал-соединения, модулю может не всегда хватать скорости связи, поэтому иногда страница может грузиться дольше чем при обычном соединении. Иногда требуется нажать на кнопку несколько раз чтобы ускорить процесс.++++

==== Шаг 6. Результат ====
Теперь отключите робота от компьютера, поставьте на ровную поверхность где для его движения будет достаточно места. Включите переключатель на Power-модуле. После включения, подождите какое-то время (примерно 20 секунд) и откройте страницу с адресом, полученным в предыдущем шаге. Управляйте роботом с помощью сайта. В зависимости от полученной команды робот будет двигаться в определённом направлении.