В этой статье мы рассмотрим управление сервомотором из веб-браузера с помощью Arduino и Wi-Fi модуля ESP8266. Модуль ESP8266 будет устанавливать соединение между сервомотором и веб-браузером с использованием IP адреса и затем при перемещении слайдера в веб-браузере ось сервомотора будет поворачиваться на соответствующий угол. Настроив перенаправление соединения (Port Forwarding) в своем роутере вы сможете управлять сервомотором из любой точки мира по сети интернет.
Ранее на нашем сайте мы уже рассматривали управление сервомотором с помощью Arduino, с помощью MATLAB и Arduino, с помощью микроконтроллера AVR. Также по этой ссылке вы можете посмотреть все проекты на нашем сайте, связанные с управлением сервомотором.
Необходимые компоненты
- Плата Arduino Uno (купить на AliExpress).
- Сервомотор sg90 (купить на AliExpress).
- Wi-Fi модуль ESP8266 (купить на AliExpress).
- Резистор 1 кОм (3 шт.) (купить на AliExpress).
- Соединительные провода.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Работа схемы
Схема устройства представлена на следующем рисунке.
Первым делом необходимо соединить модуль ESP8266 с платой Arduino. Модуль ESP8266 работает с напряжением 3.3V, поэтому его нежелательно подсоединять к 5V платы Arduino поскольку это может повредить его. Соедините контакты VCC и CH_PD модуля с контактом 3.3V платы Arduino. Контакт RX модуля ESP8266 работает с напряжением 3.3V, поэтому он не будет работать правильно, если мы подсоединим его непосредственно к плате Arduino. Поэтому нам необходимо сделать делитель напряжения, который будет конвертировать 5V в 3.3V. Это можно сделать с помощью последовательного соединения трех резисторов как показано на схеме. Соедините контакт TX модуля ESP8266 с контактом 4 платы Arduino, а контакт RX модуля ESP8266 - с контактом 5 платы Arduino при помощи резисторов.
Wi-Fi модуль ESP8266 обеспечивает нашему проекту доступ в сеть интернет. Он является весьма дешевым, но в тоже время достаточно "мощным" устройством и может подсоединяться к большинству известных микроконтроллеров, поэтому он так часто используется в проектах, связанных с интернетом вещей (IOT).
Затем соединим сервомотор с платой Arduino. Соедините контакты VCC и землю сервомотора к контактам 5V и земле платы Arduino, а сигнальный контакт сервомотора – к контакту 9 платы Arduino.
Внешний вид используемого нами сервомотора показан на следующем рисунке.
Как будет работать наш проект
Чтобы запустить наш проект вам необходимо сделать HTML файл, который будет открывать веб-страницу. Для этого вам необходимо будет скопировать HTML код, приведенный ниже в данной статье и сохранить его в блокнот. Расширение у созданного файла должно быть ‘.html’. То есть, к примеру, если вы хотите назвать файл ‘servo’, то полностью имя файла будет ‘servo.html’, чтобы его легко можно было открыть в веб-браузере.
После этого вы должны поместить jQuery файл в ту же самую папку куда вы поместили html файл. Скачать необходимые файлы вы можете по следующей ссылке – скачать HTML файл и jQuery файл. После скачивания файлы необходимо извлечь из архива. jQuery представляет собой библиотеку Java Script, которая содержит JS функции для осуществления DOM операций (DOM - Document Object Model - объектная модель документов) и обеспечивает стандартный интерфейс для доступа и управления HTML-объектами.
Теперь откройте скачанный html файл в веб-браузере, вы должны увидеть примерно следующую картинку:
После этого вставьте код программы для Arduino (приведен в конце статьи) в Arduino IDE, измените в этом коде имя пользователя и пароль для сети Wi-Fi на свои данные и загрузите программу в плату Arduino. В последовательном мониторе (Serial Monitor) вы можете увидеть IP адрес. Напечатайте этот IP адрес в поле на веб-странице. Теперь если вы будете двигать слайдер на представленной веб-странице, то сервомотор будет двигаться в соответствии с положением ползунка слайдера. Таким образом, вы можете управлять сервомотором с веб-страницы.
Код программы для HTML файла
Полный текст программы HTML файла, который вы скачали по вышеприведенной ссылке, выглядит следующим образом.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<!DOCTYPE html > <html> <head> <title>Web controlled Servo</title> <script src="jquery.js"></script> </head> <body> <h1> <b> Web Controlled Servo by circuitdigest.com </b> </h1> <h4> <b> Enter the IP address of esp8266 shown in the serial monitor below </b> </h4> <div style="margin: 0; width:500px; height:80px;"> <FORM NAME="form" ACTION="" METHOD="GET"> ESP8266 IP Address: <INPUT TYPE="text" NAME="inputbox" VALUE="192.168.0.9"> </FORM> </div> <h3> Scroll it to move servo 1 </h3> <input type="range" min="20" max="170" onmouseup="servo1(this.value)" /> </body> <script> $.ajaxSetup({timeout:1000}); function servo1(angle) { TextVar = form.inputbox.value; ArduinoVar = "http://" + TextVar + ":80"; $.get( ArduinoVar, { "sr1": angle }) ; {Connection: close}; } </script> </html> |
Тег <!DOCTYPE html > сообщает веб-браузеру какую версию html мы использовали для написания нашего кода. Этот тэг должен быть записан в самом верху документа, все остальные строки файла должны быть записаны после него.
Код, записанный между тегами <html> </html>, считывается браузером. То есть эти теги обозначают начало и конец html-документа. Код, записанный вне этих тегов, не будет отображаться на веб-странице. Теги <head> </head> используются для задания названия документа, ссылок, jQuery и стилей. Мы в нашем коде указали название веб-страницы и скрипт jQuery. Данные, записанные между тегами <title></title>, будут обозначать название вкладки в браузере. В нашем коде мы дали ей имя “Web Controlled Servo”.
Теги <script></script> используются чтобы подключить jQuery, который представляет собой библиотеку JavaScript и значительно упрощает наш код.
Теги body используются чтобы определить такие элементы на веб-странице как текстовые поля, слайдеры, кнопки и т.д. Также мы можем определить размеры этих элементов. Теги заголовков h1, h2, h3, h4, h5 и h6 используются для задания размера шрифта этих заголовков. В нашем коде мы использовали заголовки h1, h3 и h4.
Затем мы создали текстовое поле (textbox) чтобы записать в нем IP адрес. Он будет соответствовать IP адресу ESP8266, который будет передавать данные на этот IP адрес. После этого в коде файла мы создаем слайдер (input type="range") который будет передавать значение функции “servo1”, которое будет соответствовать углу поворота оси сервомотора от 20 до 170 градусов.
1 2 3 4 5 6 7 |
function servo1(angle) { TextVar = form.inputbox.value; ArduinoVar = "http://" + TextVar + ":80"; $.get( ArduinoVar, { "sr1": angle }) ; {Connection: close}; } |
Затем эта функция будет исполняться и передавать значение плате Arduino, чтобы она повернула ось сервомотора на нужный угол и закрыла бы соединение.
Исходный код программы для платы Arduino
Полный код программы приведен в конце статьи. Здесь же обсудим наиболее важные участки кода.
Для начала нам необходимо подключить библиотеку последовательной связи (Software Serial) и библиотеку для работы с сервомотором. Если у вас нет этих библиотек, то вам необходимо их установить перед загрузкой кода в плату Arduino. Затем необходимо инициализировать контакты, к которым мы подключили модуль ESP8266. Сообщение ‘DEBUG true’ будет показано в сообщениях от ESP8266 в окне монитора последовательной связи (Serial Monitor). Затем инициализируем контакт servo и объявим переменную для сервомотора.
1 2 3 4 5 6 |
#include <SoftwareSerial.h> #include <Servo.h> SoftwareSerial esp(4, 5); //set ESP8266 RX pin = 5, and TX pin = 4 #define DEBUG true //display ESP8266 messages on Serial Monitor #define servopin 9 //servo 1 on digital port 9 Servo ser; //servo 1 |
Затем сообщим плате Arduino к какому ее контакту мы подключили сервомотор и повернем ось серводвигателя на максимальную позицию. Затем установим скорость последовательной связи для модуля ESP8266 – 115200 бод/с.
1 2 3 4 5 |
ser.attach(servopin); ser.write(maxpos); ser.detach(); Serial.begin(115200); esp.begin(115200); |
Следующий участок кода соединяет модуль ESP8266 с вашим Wi-Fi роутером и сообщает вам IP адрес по которому вы будете соединяться с веб-страницей и получать от нее данные.
1 2 3 4 5 6 7 8 |
sendData("AT+RST\r\n", 2000, DEBUG); //сбросить модуль sendData("AT+CWMODE=1\r\n", 1000, DEBUG); //установить режим станции sendData("AT+CWJAP=\"Arsenal\",\"12345678\"\r\n", 2000, DEBUG); // соединиться с wifi сетью while(!esp.find("OK")) { //подождать соединения } sendData("AT+CIFSR\r\n", 1000, DEBUG); //показать IP адрес sendData("AT+CIPMUX=1\r\n", 1000, DEBUG); //разрешить множественные соединения sendData("AT+CIPSERVER=1,80\r\n", 1000, DEBUG); //start web server on port 80 |
В функции void loop() модуль ESP8266 будет проверять получены ли данные или нет. Если данные получены, то они будут считываться и отображаться в окне монитора последовательной связи, также будет производиться поворот оси сервомотора в соответствии с этими данными.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
if (esp.available()) //проверка получены ли данные модулем ESP8266 { if (esp.find("+IPD,")) //если там новая команда { String msg; esp.find("?"); //двигаем курсор до тех пор пока не будет найдена команда msg = esp.readStringUntil(' '); //считываем сообщение String command = msg.substring(0, 3); //то, что это команда, идентифицируется первыми 3 символами "sr1" String valueStr = msg.substring(4); // следующие 3 символа идентифицируют необходимый угол поворота оси сервомотора int value = valueStr.toInt(); //преобразуем в integer (число целого типа) if (DEBUG) { Serial.println(command); Serial.println(value); } |
Наконец, функция sendData используется для передачи команд модулю ESP8266 и проверяет его ответ.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
String sendData(String command, const int timeout, boolean debug) { String response = ""; esp.print(command); long int time = millis(); while ( (time + timeout) > millis()) { while (esp.available()) { char c = esp.read(); response += c; } } if (debug) { Serial.print(response); } return response; } |
Для демонстрации работы нашего проекта (смотрите видео в конце статьи) мы использовали локальный сервер. Но чтобы подобным образом управлять серводвигателем из любой точки мира, вам необходимо перенаправить порт 80 (используется для HTTP или интернета) на ваш локальный или частный IP адрес (192.168*) вашего устройства. После перенаправления порта все входящие соединения будут перенаправляться на этот локальный адрес, после этого вам будет необходимо открыть HTML файл, который вы скачали ранее в этой статье, и там в текстовом поле ввести публичный IP адрес вашего интернета. Вы можете настроить перенаправление порта залогинившись в своем роутере (192.168.1.1) и найти в настройках роутера опцию для перенаправления порта.
Далее приведен полный текст программы.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
#include <SoftwareSerial.h> //Including the software serial library #include <Servo.h> //including the servo library SoftwareSerial esp(4, 5); #define DEBUG true //This will display the ESP8266 messages on Serial Monitor #define servopin 9 //connect servo on pin 9 Servo ser; //variable for servo int current_pos = 170; int v = 10; int minpos = 20; int maxpos = 160; void setup() { ser.attach(servopin); ser.write(maxpos); ser.detach(); Serial.begin(115200); esp.begin(115200); sendData("AT+RST\r\n", 2000, DEBUG); //This command will reset module sendData("AT+CWMODE=1\r\n", 1000, DEBUG); //This will set the esp mode as station mode sendData("AT+CWJAP=\"wifi-name\",\"wifi-password\"\r\n", 2000, DEBUG); //This will connect to wifi network while(!esp.find("OK")) { //this will wait for connection } sendData("AT+CIFSR\r\n", 1000, DEBUG); //This will show IP address on the serial monitor sendData("AT+CIPMUX=1\r\n", 1000, DEBUG); //This will allow multiple connections sendData("AT+CIPSERVER=1,80\r\n", 1000, DEBUG); //This will start the web server on port 80 } void loop() { if (esp.available()) //check if there is data available on ESP8266 { if (esp.find("+IPD,")) //if there is a new command { String msg; esp.find("?"); //run cursor until command is found msg = esp.readStringUntil(' '); //read the message String command = msg.substring(0, 3); //command is informed in the first 3 characters "sr1" String valueStr = msg.substring(4); //next 3 characters inform the desired angle int value = valueStr.toInt(); //convert to integer if (DEBUG) { Serial.println(command); Serial.println(value); } delay(100); //move servo to desired angle if(command == "sr1") { //limit input angle if (value >= maxpos) { value = maxpos; } if (value <= minpos) { value = minpos; } ser.attach(servopin); //attach servo while(current_pos != value) { if (current_pos > value) { current_pos -= 1; ser.write(current_pos); delay(100/v); } if (current_pos < value) { current_pos += 1; ser.write(current_pos); delay(100/v); } } ser.detach(); //dettach } } } } String sendData(String command, const int timeout, boolean debug) { String response = ""; esp.print(command); long int time = millis(); while ( (time + timeout) > millis()) { while (esp.available()) { char c = esp.read(); response += c; } } if (debug) { Serial.print(response); } return response; } |