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

++++ В чём отличия от прошлого урока? | 

В уроке [[main:upgkits:wifibot|]] мы заметили неудобство связанное с медленным откликом интернет-страницы. Это связано в том числе с использованием программной эмуляции Serial соединения, ведь скорость обмена данными при таком соединении сильно ограничена. В отличие от прошлого урока, где сервером выступал контроллер Smart UNO, в данном уроке Web-сервером будет сам Wi-Fi модуль. Ведь он имеет свой контроллер на плате (под металлическим корпусом), который как раз и возьмёт на себя функции отображения интернет-страницы и обработки http-запросов. Это и позволит разгрузить контролер UNO, и выполнять запросы быстро. Результат запросов в свою очередь будет передан контроллеру UNO, и тот будет управлять движением робота. 

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

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

^ Что нужно                                                                                                               ^  Кол-во, шт  ^
| [[https://smartelements.ru/collection/svyaz/product/wifi-modul-esp-12|Wi-Fi модуль ESP-12 (5 В)]] |  1           |


===== Библиотеки =====
  * [[http://files.smartelements.ru/know_libs/robotSE.zip|Библиотека robotSE (для робота)]]


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

==== Шаг 2. Установите пакет ESP8266 ====
Установите пакет для работы с ESP8266, он нужен для работы с платами из семейства ESP8266 (wi-fi модулями) прямо из Arduino IDE. Для этого откройте Arduino IDE, и перейдите в меню **Файл -> Настройки**. В поле **"Дополнительные ссылки для менеджера плат"** добавьте строку:
<file>
https://arduino.esp8266.com/stable/package_esp8266com_index.json
</file>

{{ :main:upgkits:settings.jpg?nolink |}}

И нажмите ОК. Далее откройте меню **Инструменты -> Платы -> Менеджер** плат и введите в окне поиска **"ESP8266"**. После этого нажмите кнопку "Установить" и дождитесь окончания установки.
{{ :main:upgkits:boardmanager.jpg?nolink |}}

==== Шаг 3. Подключите Wi-Fi модуль ====
Для того чтобы дальше работать с модулем, понадобится подключить его через Smart UNO к компьютеру.

<WRAP center round info 80%>
Обратите внимание! Чтобы схема с подключением работала, необходимо соединить проводом выводы RESET и GND платы контроллера.
</WRAP>

{{ :main:info:esp_uno_connecting.png?nolink |}}

После того как вы подключили модуль к контроллеру, подключите контроллер к компьютеру с помощью USB-кабеля.

==== Шаг 4. Загрузите скетч на Wi-Fi модуль ====
В этом шаге загрузим скетч на модуль через контроллер Smart UNO. 
<file Arduino>
//подключение библиотек
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

const char* ssid = "SmartElements"; //имя вашей сети
const char* password = "12345678"; //пароль от сети

ESP8266WebServer server(80); //создание объекта сервера

//создание сайта
String webPage =   "<!DOCTYPE HTML>"
  "<html>"
  "<head>"
  "<meta charset=\"utf-8\">"
  "<title>Робопульт</title>"
  "<style>"
      "a {"
   "outline: none;"
    "text-decoration: none;"
    "display: inline-block;"
    "color: white;"
    "padding: 20px 30px;"
    "margin: 10px 20px;"
    "border-radius: 10px;"
    "font-family: 'Montserrat', sans-serif;"
    "text-transform: uppercase;"
    "letter-spacing: 2px;"
    "background-image: linear-gradient(to right, #9EEFE1 0%, #4830F0 51%, #9EEFE1 100%);"
    "background-size: 200% auto;"
    "box-shadow: 0 0 20px rgba(0,0,0,.1);"
    "transition: .5s;}"
    "a:hover {background-position: right center;}"
  "</style>"
  "</head>"
  "<div style=\"text-align:center;\">"
  "<a href=\"/F\">Вперёд</a>"
  "<br><br>"
  "<a href=\"/L\">Влево</a>"
  "<a href=\"/S\">Стоп</a>"
  "<a href=\"/R\">Вправо</a>"
  "<br><br>"
  "<a href=\"/B\">Назад</a>"
  "</div>"
  "</html>";

void setup(){
  delay(1000); //задержка в 1 секунду
  Serial.begin(115200); //инициализация Serial-соединения
  WiFi.begin(ssid, password); //подключение к сети
  Serial.print("Trying to connect to "); //вывод информации для отладки
  Serial.println(ssid); //вывод информации для отладки

  while (WiFi.status() != WL_CONNECTED) { //подключение к сети
    delay(500);
    Serial.print(".");
  }
  
  Serial.println(""); //вывод информации для отладки
  Serial.print("Connected to ");  //вывод информации для отладки
  Serial.println(ssid); //вывод информации для отладки
  Serial.print("IP address: ");  //вывод информации для отладки (полученный IP адрес)
  Serial.println(WiFi.localIP()); //вывод информации для отладки
  
  server.on("/", [](){ //обработка общего запроса страницы
    server.send(200, "text/html", webPage); //отправка ответа "ОК" и веб-страницы
  });
  server.on("/F", [](){ //обработка запроса /F
    server.send(200, "text/html", webPage); //отправка ответа "ОК" и веб-страницы
    Serial.println("F"); //отправка команды в Serial-порт
  });
  server.on("/L", [](){ //обработка запроса /F
    server.send(200, "text/html", webPage); //отправка ответа "ОК" и веб-страницы
    Serial.println("L"); //отправка команды в Serial-порт
  });
  server.on("/R", [](){ //обработка запроса /R
    server.send(200, "text/html", webPage); //отправка ответа "ОК" и веб-страницы
    Serial.println("R"); //отправка команды в Serial-порт
  });
  server.on("/S", [](){ //обработка запроса /S
    server.send(200, "text/html", webPage); //отправка ответа "ОК" и веб-страницы
    Serial.println("S"); //отправка команды в Serial-порт
  });
  server.on("/B", [](){ //обработка запроса /B
    server.send(200, "text/html", webPage); //отправка ответа "ОК" и веб-страницы
    Serial.println("B"); //отправка команды в Serial-порт
  });
  server.begin(); //запуск сервера
  Serial.println("HTTP server started"); //вывод отладочной информации
}
 
void loop(){
  server.handleClient(); //обработка запросов с сайта
}
</file>

Теперь откройте в Arduino IDE меню **Инструменты -> Плата** и выберите из списка плату **Generic ESP8266 Module**.
{{ :main:upgkits:choose_boardesp.jpg?nolink |}}

Другие настройки в меню **Инструменты** приведите к виду:
  * **Upload speed**: 115200
  * **CPU Freequency**: 80 MHz
  * **Crystal Freequency**: 26 MHz
  * **Flash size**: 512 Kb (FS:64 OTA:214)
  * **Flash mode**: DIO
  * **Flash Freequency**: 40 MHz

{{ :main:upgkits:upload_settings_esp8266.jpg?nolink |}}

Выполните команду Скетч -> Загрузка. После этого на Wi-Fi модуле выполните следующие действия:
  - Нажмите кнопку **PRG** на модуле и держите её нажатой
  - Пока держите нажатой кнопку PRG, нажмите на модуле кнопку **RST** и отпустите её
  - Отпустите кнопку **PRG**

Так вы переведёте модуль в режим загрузки. Дождитесь окончания загрузки в окне. Загрузка выглядит примерно так:
<file>
esptool.py v2.8
Serial port COM24
Connecting........_
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 18:fe:34:f8:92:ef
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0240
Compressed 293952 bytes to 214173...

Writing at 0x00000000... (7 %)
Writing at 0x00004000... (14 %)
Writing at 0x00008000... (21 %)
Writing at 0x0000c000... (28 %)
Writing at 0x00010000... (35 %)
Writing at 0x00014000... (42 %)
Writing at 0x00018000... (50 %)
Writing at 0x0001c000... (57 %)
Writing at 0x00020000... (64 %)
Writing at 0x00024000... (71 %)
Writing at 0x00028000... (78 %)
Writing at 0x0002c000... (85 %)
Writing at 0x00030000... (92 %)
Writing at 0x00034000... (100 %)
Wrote 293952 bytes (214173 compressed) at 0x00000000 in 18.7 seconds (effective 125.8 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
</file>

//Примечание: Из-за особенностей загрузки через плату UNO, при загрузке может не сразу находиться COM порт, или долго выполняться подключение. Попробуйте отключить кабель USB и подключить его снова, или попробовать другой порт. (Не забываете после этого переводить модуль в режим загрузки). Если у Вас не получается загрузить скетч на Wi-Fi модуль через контроллер UNO, вы всегда можете воспользоваться быстрым и надёжным способом: [[https://smartelements.ru/collection/moduli/product/usb-uart-bridge|Модуль USB-UART на базе чипа CP2102]]//

==== Шаг 5. Определение IP-адреса ====
После того как скетч на модуль будет загружен, нажмите на модуле кнопку RST (или отключите кабель и подключите снова). Откройте монитор порта, настройте его на скорость обмена 115200 бод.

{{ :main:upgkits:serial_monitor_esp.jpg?nolink |}}

В монитор будет выведена отладочная информация, посмотрите какой IP-адрес будет присвоен модулю.

<file>
Trying to connect to SmartElements
..
Connected to SmartElements
IP address: 192.168.1.182
HTTP server started
</file>

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

==== Шаг 6. Откройте страницу ====
В прошлом шаге мы получили IP-адрес нашего пульта управления роботом (интернет-страница) и теперь можем открыть её в браузере.

{{ :main:upgkits:робопульт.jpg?nolink |}}

==== Шаг 7. Загрузка скетча управления роботом на контроллер ====
Настало время загрузить скетч для управления роботом.

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

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

void setup()
{
  //инициализация Serial-соединения для получения команд от WiFi модуля
  Serial.begin(115200);
}


void loop()
{
  String command = Serial.readStringUntil('\n'); //чтение строки из Serial-порта
  command.trim(); //обрезать строку (убрать незначащие символы)

  if (command == "F") { //если это команда F
    robot.move_forward(); //двигаться вперед
  }
  if (command == "L") { //если это команда L
    robot.move_left(); //двигаться влево
  }
  if (command == "S") { //если это команда S
    robot.move_stop(); //остановиться
  }
  if (command == "R") { //если это команда R
    robot.move_right(); //двигаться вправо
  }
  if (command == "B") { //если это команда B
    robot.move_back(); //двигаться назад
  }

}
</file>

Загрузите данный скетч на контроллер. Не забудьте установить в меню **Инструменты -> Плата** плату Arduino UNO.
После загрузки отключите контроллер от компьютера.

==== Шаг 8. Сборка и запуск ====
Если Вы пользовались контроллером для загрузки скетча на Wi-Fi модуль, то установите Motor shield на место и подключите все необходимые провода моторов и питания к шилду.

В выводы "мама" с надписью **UART** установите Wi-Fi модуль вертикально, соблюдая распиновку (+ в +, - в -, TX в RX, RX в TX).
Установите переключатель питания на Power модуле в положение ON. 
Перейдите на страницу управления роботом как указано в шаге 6, и управляйте движением робота через интернет.

//Примечание: Так как мы загружали код напрямую на Wi-Fi модуль, то вся информация, которая была на модуле была затёрта (например, прошивка для работы с АТ-командами). Для того чтобы восстановить прошивку воспользуйтесь статьёй [[main:info:flashingesp|]]//