Web интерфейс управления сервоприводами ESP8266 есть скеч. цена в мере розумного
- Войдите на сайт для отправки комментариев
Вс, 24/05/2020 - 11:09
Подскажите что я делаю не так ? Позиция лево-право: undefined Позиция верх-вниз: работает нормально
За исправления кода скину $
Вот код можно компилировать.
#include <Servo.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
const char *ssid = "Aleksander";
const char *password = "11406080";
Servo myservo; // создаем экземпляр класса «Servo»,
Servo myservo1; // чтобы с его помощью управлять сервоприводом;
// большинство плат позволяют
// создать 12 объектов класса «Servo»
// GPIO-контакт, к которому подключен сервопривод:
static const int servoPin = 13;
static const int servo1Pin = 14;
// создаем веб-сервер на порте «80»:
WiFiServer server(80);
// переменная для хранения HTTP-запроса:
String header;
String header1;
// несколько переменных для расшифровки значения в HTTP-запросе GET:
String valueString = String(5);
String valueString1 = String(5);
int pos1 = 0;
int pos2 = 0;
int pos11 = 0;
int pos22 = 0;
void setup() {
Serial.begin(115200);
myservo.attach(servoPin); // привязываем сервопривод,
myservo.attach(servo1Pin); // подключенный к контакту «servoPin»,
// к объекту «myservo»
// подключаемся к WiFi при помощи заданных выше SSID и пароля:
Serial.print("Connecting to "); // "Подключаемся к "
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// печатаем локальный IP-адрес и запускаем веб-сервер:
Serial.println("");
Serial.println("WiFi connected."); // "WiFi подключен."
Serial.println("IP address: "); // "IP-адрес: "
Serial.println(WiFi.localIP());
server.begin();
}
void loop(){
// начинаем прослушивать входящих клиентов:
WiFiClient client = server.available();
if (client) { // если подключился новый клиент,
Serial.println("New Client."); // печатаем сообщение
// «Новый клиент.»
// в мониторе порта;
String currentLine = ""; // создаем строку для хранения
// входящих данных от клиента;
while (client.connected()) { // цикл while() будет работать
// все то время, пока клиент
// будет подключен к серверу;
if (client.available()) { // если у клиента есть данные,
// которые можно прочесть,
char c = client.read(); // считываем байт, а затем
Serial.write(c); // печатаем его в мониторе порта
header += c;
if (c == '\n') { // если этим байтом является
// символ новой строки
// если получили два символа новой строки подряд,
// то это значит, что текущая строчка пуста;
// это конец HTTP-запроса клиента,
// а значит – пора отправлять ответ:
if (currentLine.length() == 0) {
// HTTP-заголовки всегда начинаются
// с кода ответа (например, «HTTP/1.1 200 OK»)
// и информации о типе контента
// (чтобы клиент понимал, что получает);
// в конце пишем пустую строчку:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
// "Соединение: отключено"
client.println();
// показываем веб-страницу:
client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
client.println("<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial; margin-left:auto; margin-right:auto;}");
client.println(".slider { width: 300px; }</style>");
client.println("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>");
// веб-страница:
client.println("</head><body><h1>ESP8266 Управление сервомотором антенны</h1>");
// "Управление сервомотором
// с помощью платы ESP32"
client.println("<p>Позиция верх-вниз: <span id=\"servoPos\"></span></p>");
client.println("<input type=\"range\" min=\"0\" max=\"180\" class=\"slider\" id=\"servoSlider\" onchange=\"servo(this.value)\" value=\""+valueString+"\"/>");
client.println("<p>Позиция лево-право: <span id=\"servoPos1\"></span></p>");
client.println("<input type=\"range\" min=\"0\" max=\"180\" class=\"slider1\" id=\"servoSlider1\" onchange=\"servo1(this.value1)\" value1=\""+valueString1+"\"/>");
client.println("<script>var slider = document.getElementById(\"servoSlider\");");
client.println("var slider1 = document.getElementById(\"servoSlider1\");");
client.println("var servoP = document.getElementById(\"servoPos\"); servoP.innerHTML = slider.value;");
client.println("var servoP1 = document.getElementById(\"servoPos1\"); servoP1.innerHTML = slider1.value1;");
client.println("slider.oninput = function() { slider.value = this.value; servoP.innerHTML = this.value; }");
client.println("slider1.oninput = function() { slider1.value1 = this.value1; servoP1.innerHTML = this.value1; }");
client.println("$.ajaxSetup({timeout:1000}); function servo(pos) { ");
client.println("$.get(\"/?value=\" + pos + \"&\"); {Connection: close};}");
client.println("$.ajaxSetup({timeout:1000}); function servo1(pos1) { ");
client.println("$.get(\"/?value=\" + pos1 + \"&\"); {Connection: close};}</script>");
client.println("</body></html>");
//GET /?value=180& HTTP/1.1
if(header.indexOf("GET /?value=")>=0) {
pos1 = header.indexOf('=');
pos2 = header.indexOf('&');
pos11 = header1.indexOf('=');
pos22 = header1.indexOf('&');
valueString = header.substring(pos1+1, pos2);
valueString1 = header1.substring(pos11+1, pos22);
// вращаем ось сервомотора:
myservo.write(valueString.toInt());
Serial.println(valueString);
myservo1.write(valueString1.toInt());
Serial.println(valueString1);
}
// конец HTTP-ответа задается
// с помощью дополнительной пустой строки:
client.println();
// выходим из цикла while():
break;
} else { // если получили символ новой строки,
// очищаем текущую строку «currentLine»:
currentLine = "";
}
} else if (c != '\r') { // если получили любые данные,
// кроме символа возврата каретки,
currentLine += c; // добавляем эти данные
// в конец строки «currentLine»
}
}
}
// очищаем переменную «header[]»:
header = "";
header1 = "";
// отключаем соединение:
client.stop();
Serial.println("Client disconnected.");
// "Клиент отключился."
Serial.println("");
}
}
Если верх-вниз действительно работает, то поправлю скетч для лево-право за 500р, fridgetester@mail.ru
ЗЫ: оплата, разумеецца, вперёд.
zDimaBY - вставьте код правильно, с номерами строк, чтоб я мог указать вам ошибку
#include <Servo.h> #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> const char *ssid = "Aleksander"; const char *password = "11406080"; Servo myservo; // создаем экземпляр класса «Servo», Servo myservo1; // чтобы с его помощью управлять сервоприводом; // большинство плат позволяют // создать 12 объектов класса «Servo» // GPIO-контакт, к которому подключен сервопривод: static const int servoPin = 13; static const int servo1Pin = 14; // создаем веб-сервер на порте «80»: WiFiServer server(80); // переменная для хранения HTTP-запроса: String header; String header1; // несколько переменных для расшифровки значения в HTTP-запросе GET: String valueString = String(5); String valueString1 = String(5); int pos1 = 0; int pos2 = 0; int pos11 = 0; int pos22 = 0; void setup() { Serial.begin(115200); myservo.attach(servoPin); // привязываем сервопривод, myservo.attach(servo1Pin); // подключенный к контакту «servoPin», // к объекту «myservo» // подключаемся к WiFi при помощи заданных выше SSID и пароля: Serial.print("Connecting to "); // "Подключаемся к " Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } // печатаем локальный IP-адрес и запускаем веб-сервер: Serial.println(""); Serial.println("WiFi connected."); // "WiFi подключен." Serial.println("IP address: "); // "IP-адрес: " Serial.println(WiFi.localIP()); server.begin(); } void loop(){ // начинаем прослушивать входящих клиентов: WiFiClient client = server.available(); if (client) { // если подключился новый клиент, Serial.println("New Client."); // печатаем сообщение // «Новый клиент.» // в мониторе порта; String currentLine = ""; // создаем строку для хранения // входящих данных от клиента; while (client.connected()) { // цикл while() будет работать // все то время, пока клиент // будет подключен к серверу; if (client.available()) { // если у клиента есть данные, // которые можно прочесть, char c = client.read(); // считываем байт, а затем Serial.write(c); // печатаем его в мониторе порта header += c; if (c == '\n') { // если этим байтом является // символ новой строки // если получили два символа новой строки подряд, // то это значит, что текущая строчка пуста; // это конец HTTP-запроса клиента, // а значит – пора отправлять ответ: if (currentLine.length() == 0) { // HTTP-заголовки всегда начинаются // с кода ответа (например, «HTTP/1.1 200 OK») // и информации о типе контента // (чтобы клиент понимал, что получает); // в конце пишем пустую строчку: client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println("Connection: close"); // "Соединение: отключено" client.println(); // показываем веб-страницу: client.println("<!DOCTYPE html><html>"); client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"); client.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"); client.println("<link rel=\"icon\" href=\"data:,\">"); client.println("<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial; margin-left:auto; margin-right:auto;}"); client.println(".slider { width: 300px; }</style>"); client.println("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>"); // веб-страница: client.println("</head><body><h1>ESP8266 Управление сервомотором антенны</h1>"); // "Управление сервомотором // с помощью платы ESP32" client.println("<p>Позиция верх-вниз: <span id=\"servoPos\"></span></p>"); client.println("<input type=\"range\" min=\"0\" max=\"180\" class=\"slider\" id=\"servoSlider\" onchange=\"servo(this.value)\" value=\""+valueString+"\"/>"); client.println("<p>Позиция лево-право: <span id=\"servoPos1\"></span></p>"); client.println("<input type=\"range\" min=\"0\" max=\"180\" class=\"slider1\" id=\"servoSlider1\" onchange=\"servo1(this.value1)\" value1=\""+valueString1+"\"/>"); client.println("<script>var slider = document.getElementById(\"servoSlider\");"); client.println("var slider1 = document.getElementById(\"servoSlider1\");"); client.println("var servoP = document.getElementById(\"servoPos\"); servoP.innerHTML = slider.value;"); client.println("var servoP1 = document.getElementById(\"servoPos1\"); servoP1.innerHTML = slider1.value1;"); client.println("slider.oninput = function() { slider.value = this.value; servoP.innerHTML = this.value; }"); client.println("slider1.oninput = function() { slider1.value1 = this.value1; servoP1.innerHTML = this.value1; }"); client.println("$.ajaxSetup({timeout:1000}); function servo(pos) { "); client.println("$.get(\"/?value=\" + pos + \"&\"); {Connection: close};}"); client.println("$.ajaxSetup({timeout:1000}); function servo1(pos1) { "); client.println("$.get(\"/?value=\" + pos1 + \"&\"); {Connection: close};}</script>"); client.println("</body></html>"); //GET /?value=180& HTTP/1.1 if(header.indexOf("GET /?value=")>=0) { pos1 = header.indexOf('='); pos2 = header.indexOf('&'); pos11 = header1.indexOf('='); pos22 = header1.indexOf('&'); valueString = header.substring(pos1+1, pos2); valueString1 = header1.substring(pos11+1, pos22); // вращаем ось сервомотора: myservo.write(valueString.toInt()); Serial.println(valueString); myservo1.write(valueString1.toInt()); Serial.println(valueString1); } // конец HTTP-ответа задается // с помощью дополнительной пустой строки: client.println(); // выходим из цикла while(): break; } else { // если получили символ новой строки, // очищаем текущую строку «currentLine»: currentLine = ""; } } else if (c != '\r') { // если получили любые данные, // кроме символа возврата каретки, currentLine += c; // добавляем эти данные // в конец строки «currentLine» } } } // очищаем переменную «header[]»: header = ""; header1 = ""; // отключаем соединение: client.stop(); Serial.println("Client disconnected."); // "Клиент отключился." Serial.println(""); } }Через https://kwork.ru работаете ?
код списали что ли, ничего в нем не смыслите?
строка 36 и 37 - одна должна быть myservo.attach(), а вторая myservo1.attach() - а у вас обе строки для одного и того же серво
строка 36 и 37 это понимаю.. но не понимаю как брать запрос с 2-х ползунков один показывает значения undefined
Списал, смыслю но не все например с 124 до 130 не очень понимаю
строка 36 и 37 это понимаю..
так исправляйте, так работать заведомо не будет
Исправил. https://ibb.co/jvW830v но думаю на это ничего не повлияло имею виду "Позиция лево-право: undefined"
а, увидел, у вас еще код сайта неверный, строчки 116-119 видимо изначально брали из примера, где был один запрос, и тупо скопировали дважды? - так работать не будет.
И еще в строке 124 и дальше всунули какой-то header1, не понимая, что это значит.
В итоге у вас в коде передается только один параметр слайдера, не важно какой...
В общем, переписать это несложно, но уже выходит за рамки "помощи в форуме". Обращайтесь к фриджетестеру выше
fridgetester - помог, спасибо большое. Все решено.
А можно ли вместо запроса
а так написать можно?
client.println("$.ajaxSetup({timeout:1000}); function servo(pos_1, pos_2) { "); // принять два значения (позиция первого сервопривода и второго) client.println("$.get(\"/?value1=\" + pos_1 + \"&value2=\" + pos_2 + \"&\");{Connection: close};}");Или лучше всё-таки сделать отдельные функции для каждого сервопривода? И проверять на соответствие
if(header.indexOf("GET /?value1=")>=0) // первый сервопривод if(header.indexOf("GET /?value2=")>=0) // второйПодскажите пожалуйста, кто разбирается!
В 1 функцию.
<!doctype html> <html dir="ltr" lang="ru"> <head> <meta charset="utf-8"> <title>Новая вкладка</title> </head> <body> <script> let header = "GET /?value1=45&value2=90&value3=105& HTTP/1.1"; let positions =[]; // массив для позиций символов в строке if(header.indexOf("GET /?value")>=0) { // если начало заголовка появилось... let currentPos = header.indexOf('='); while (currentPos != -1) { positions.push(currentPos); currentPos = header.indexOf('=', currentPos+1); } currentPos = header.indexOf('&'); while (currentPos != -1) { positions.push(currentPos); currentPos = header.indexOf('&', currentPos+1); } } let valueString1 = header.substring(positions[0]+1, positions[3]); let valueString2 = header.substring(positions[1]+1, positions[4]); let valueString3 = header.substring(positions[2]+1, positions[5]); console.log(valueString1); console.log(valueString2); console.log(valueString3); console.log(positions); </script> </body> </html>в него "запихиваются" значения всех найденных позиций символа "=", а затем аналогичным образом, символа "&". Используется метод "push"
positions.push(currentPos); // запихнуть текущую позицию в массив currentPos = header.indexOf('=', currentPos+1);<!doctype html> <html dir="ltr" lang="ru"> <head> <meta charset="utf-8"> <title>Новая вкладка</title> </head> <body> <script> let header = "GET /?value1=45&value2=90&value3=105& HTTP/1.1"; let positions =[]; // массив для позиций символов в строке if(header.indexOf("GET /?value")>=0) { // если начало заголовка появилось... let currentLeftPos = header.indexOf('='); let currentRightPos = header.indexOf('&'); while (currentLeftPos != -1 || currentRightPos != -1) { positions.push(currentLeftPos); // запихнуть левую позицию positions.push(currentRightPos); // запихнуть правую позицию currentLeftPos = header.indexOf('=', currentLeftPos+1); currentRightPos = header.indexOf('&', currentRightPos+1); } } let valueString1 = header.substring(positions[0]+1, positions[1]); let valueString2 = header.substring(positions[2]+1, positions[3]); let valueString3 = header.substring(positions[4]+1, positions[5]); console.log(valueString1); console.log(valueString2); console.log(valueString3); console.log(positions); </script> </body> </html>Не тоже самое. Операция ++ выполняется после того , как будет выполнено основное выражение, а +1 сначала будет прибавлено 1, а потом уже выполнено основное выражение.
Такова особенность выражения ++
Не забываем про наличие операции ++currentPos :)
Да с плюсами перед переменной работает! Однако странно, что в отладчике, НЕ видно как currentPos увеличивается на 1.
Как не пиши, хоть ++currentPos, хоть currentPos+1 все равно.
Что это? Глюк отладчика или так и должно быть?
А вот если написать так, видно!
positions.push(currentPos); currentPos++; currentPos = header.indexOf('=', currentPos);У вас же не си. Зависания это может быть проблема отладчика, брaузера, да всего чего угодно. Может у вас где то брейк установлен и срабатывает. Зачем вы вообще отлаживаете этот простейший код ? Проверьте без отладчика и двигайтесь дальше.
Вот смотрите строка
currentLeftPos = header.indexOf('=', currentLeftPos++);
Происходит следующее в момент работы header.indexOf значение currentLeftPos равно 12, по окончании работы оно увеличивается на единицу и становится 13, но поиск проводился с символа номер 12, а этот символ удовлетворяет условиям, поскольку вы присваиваете результат header.indexOf этой переменной, то она вновь становится 12
currentLeftPos = header.indexOf('=', currentLeftPos+1);
currentLeftPos = header.indexOf('=', ++currentLeftPos);
<!doctype html> <html dir="ltr" lang="ru"> <head> <meta charset="utf-8"> <title>Новая вкладка</title> </head> <body> <script> let header = "GET /?value1=45&value2=90&value3=105& HTTP/1.1"; let positions =[]; // массив для позиций символов в строке if(header.indexOf("GET /?value")>=0) { // если начало заголовка появилось... let currentLeftPos = header.indexOf('='); let currentRightPos = header.indexOf('&'); while (currentLeftPos != -1 || currentRightPos != -1) { alert(currentLeftPos+' '+currentRightPos); positions.push(currentLeftPos); // запихнуть левую позицию positions.push(currentRightPos); // запихнуть правую позицию currentLeftPos = header.indexOf('=', currentLeftPos++); currentRightPos = header.indexOf('&', currentRightPos++); } } let valueString1 = header.substring(positions[0]+1, positions[1]); let valueString2 = header.substring(positions[2]+1, positions[3]); let valueString3 = header.substring(positions[4]+1, positions[5]); console.log(valueString1); console.log(valueString2); console.log(valueString3); console.log(positions); </script> </body> </html>Большое спасибо Вам за детальное объяснение!
#include <Servo.h> #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <WiFiUdp.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #include <ArduinoOTA.h> // Библиотека для OTA-прошивки const char *ssid = "Aleksander"; //Имя сети вайфай const char *password = "11406080"; // пароль вайфай Servo myservo; // создаем экземпляр класса «Servo», Servo myservo1; // чтобы с его помощью управлять сервоприводом; // большинство плат позволяют // создать 12 объектов класса «Servo» // GPIO-контакт, к которому подключен сервопривод: static const int servoPin = 5; static const int servo1Pin = 4; // создаем веб-сервер на порте «80»: WiFiServer server(80); // переменная для хранения HTTP-запроса: String header; // несколько переменных для расшифровки значения в HTTP-запросе GET: String valueString = String(170); String valueString1 = String(180); int pos1 = 0; int pos2 = 0; void setup() { Serial.begin(115200); myservo.attach(servoPin, 544, 1520);; // привязываем сервопривод, myservo1.attach(servo1Pin); // подключенный к контакту «servoPin», // к объекту «myservo» // подключаемся к WiFi при помощи заданных выше SSID и пароля: Serial.print("Connecting to "); // "Подключаемся к " Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } ArduinoOTA.setHostname("ESP8266_Серво-привод_антенны"); // Задаем имя сетевого порта //ArduinoOTA.setPassword((const char *)"0000"); // Задаем пароль доступа для удаленной прошивки ArduinoOTA.begin(); // Инициализируем OTA // печатаем локальный IP-адрес и запускаем веб-сервер: Serial.println(""); Serial.println("WiFi connected."); // "WiFi подключен." Serial.println("IP address: "); // "IP-адрес: " Serial.println(WiFi.localIP()); server.begin(); } void loop(){ ArduinoOTA.handle(); // Всегда готовы к прошивке // начинаем прослушивать входящих клиентов: WiFiClient client = server.available(); if (client) { // если подключился новый клиент, Serial.println("New Client."); // печатаем сообщение // «Новый клиент.» // в мониторе порта; String currentLine = ""; // создаем строку для хранения // входящих данных от клиента; while (client.connected()) { // цикл while() будет работать // все то время, пока клиент // будет подключен к серверу; if (client.available()) { // если у клиента есть данные, // которые можно прочесть, char c = client.read(); // считываем байт, а затем Serial.write(c); // печатаем его в мониторе порта header += c; if (c == '\n') { // если этим байтом является // символ новой строки // если получили два символа новой строки подряд, // то это значит, что текущая строчка пуста; // это конец HTTP-запроса клиента, // а значит – пора отправлять ответ: if (currentLine.length() == 0) { // HTTP-заголовки всегда начинаются // с кода ответа (например, «HTTP/1.1 200 OK») // и информации о типе контента // (чтобы клиент понимал, что получает); // в конце пишем пустую строчку: client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println("Connection: close"); // "Соединение: отключено" client.println(); // показываем веб-страницу: client.println("<!DOCTYPE html><html>"); client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"); client.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"); client.println("<link rel=\"icon\" href=\"data:,\">"); client.println("<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial; margin-left:auto; margin-right:auto;}"); client.println(".slider { width: 300px; }</style>"); client.println("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>"); // веб-страница: client.println("</head><body><h1>ESP8266 Управление сервомотором антенны</h1>"); // "Управление сервомотором // с помощью платы ESP32" client.println("<p>Позиция верх-вниз: <span id=\"servoPos\"></span></p>"); client.println("<input type=\"range\" min=\"70\" max=\"180\" class=\"slider\" id=\"servoSlider\" onchange=\"servo(this.value)\" value=\""+valueString+"\"/>"); client.println("<p>Позиция лево-право: <span id=\"servoPos1\"></span></p>"); client.println("<input type=\"range\" min=\"0\" max=\"180\" class=\"slider\" id=\"servoSlider1\" onchange=\"servo1(this.value)\" value=\""+valueString1+"\"/>"); client.println("<script>var slider = document.getElementById(\"servoSlider\");"); client.println("var slider1 = document.getElementById(\"servoSlider1\");"); client.println("var servoP = document.getElementById(\"servoPos\"); servoP.innerHTML = slider.value;"); client.println("var servoP1 = document.getElementById(\"servoPos1\"); servoP1.innerHTML = slider1.value;"); client.println("slider.oninput = function() { slider.value = this.value; servoP.innerHTML = this.value; }"); client.println("slider1.oninput = function() { slider1.value = this.value; servoP1.innerHTML = this.value; }"); client.println("$.ajaxSetup({timeout:1000}); function servo(pos) { "); client.println("$.get(\"/?value=\" + pos + \"&\"); {Connection: close};}"); client.println("function servo1(pos) { "); client.println("$.get(\"/?value1=\" + pos + \"&\"); {Connection: close};}</script>"); client.println("</body></html>"); //GET /?value=180& HTTP/1.1 if(header.indexOf("GET /?value=")>=0) { pos1 = header.indexOf('='); pos2 = header.indexOf('&'); valueString = header.substring(pos1+1, pos2); //Rotate the servo myservo.write(valueString.toInt()); Serial.print("Got servro val: "); Serial.println(valueString); } else if(header.indexOf("GET /?value1=")>=0) { pos1 = header.indexOf('='); pos2 = header.indexOf('&'); valueString1 = header.substring(pos1+1, pos2); //Rotate the servo myservo1.write(valueString1.toInt()); Serial.print("Got servro1 val: "); Serial.println(valueString1); } // конец HTTP-ответа задается // с помощью дополнительной пустой строки: client.println(); // выходим из цикла while(): break; } else { // если получили символ новой строки, // очищаем текущую строку «currentLine»: currentLine = ""; } } else if (c != '\r') { // если получили любые данные, // кроме символа возврата каретки, currentLine += c; // добавляем эти данные // в конец строки «currentLine» } } } // очищаем переменную «header[]»: header = ""; // отключаем соединение: client.stop(); Serial.println("Client disconnected."); // "Клиент отключился." Serial.println(""); } }Готовый код. Кому нужно будет.
Готовый код. Кому нужно будет.
не взлетит, сайт ссылки ломает...к примеру 98 строка
Не ломает, открой код в отдельном окошке, там строка без переносов.
Не ломает, открой код в отдельном окошке, там строка без переносов.
у меня сломано (FIREFOX) поправил как надо:
client.println("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>");
Насколько я понял, это подгружается библиотека jQuery с какого-то удаленного сервера, и это значит, что без доступа к нему скетч нормально работать не будет! Интересно, как добавить её прямо в память модуля и использовать локально?
Если бы не куча дополнительных символов, то наверно просто вставить содержимое между тегами <script> </script> в которых стоит ссылка на источник.
На SPIFFS положить, если влезет.
84 килобайта, влезет. Только со SPIFFS грузится будет долго, нужно с кешированием шаманить. Только воз из этого скрипта могут быть обращения к другим ресурсам, это точно нужно проверять.
Браузер закэширует. Наврядли стоит ESP-шкой CDN заменять.
{try{return new e.XMLHttpRequest} // первое (i["X-Requested-With"]="XMLHttpRequest") // второеНи к каким внешним ресурсам, насколько я понял, библиотека не обращается.
Значит файл с ней можно загрузить в файловую систему и просто указать на него ссылку?
И эта строка
client.println("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>");
bool handleFileRead(String path){ // Функция работы с файловой системой if(path.endsWith("/")) path += "index.html"; // Если устройство вызывается по корневому адресу, то должен вызываться файл index.html (добавляем его в конец адреса) else if(path.endsWith("/jquery.min.js")) path += "jquery.min.js"; // файл библиотеки String contentType = getContentType(path); // С помощью функции getContentType (описана ниже) определяем по типу файла (в адресе обращения) какой заголовок необходимо возвращать по его вызову if(SPIFFS.exists(path)){// Если в файловой системе существует файл по адресу обращения File file = SPIFFS.open(path, "r"); // Открываем файл для чтения size_t sent = HTTP.streamFile(file, contentType);// Выводим содержимое файла по HTTP, указывая заголовок типа содержимого contentType file.close();// Закрываем файл return true;// Завершаем выполнение функции, возвращая результатом ее исполнения true (истина) } return false; // Завершаем выполнение функции, возвращая результатом ее исполнения false (если не обработалось предыдущее условие) } // и еще нужна функция для возврата правильного заголовка String getContentType(String filename){ // Функция, возвращающая необходимый заголовок типа содержимого в зависимости от расширения файла if (filename.endsWith(".html")) return "text/html";// Если файл заканчивается на ".html", то возвращаем заголовок "text/html" и завершаем выполнение функции else if (filename.endsWith(".css")) return "text/css";// Если файл заканчивается на ".css", то возвращаем заголовок "text/css" и завершаем выполнение функции else if (filename.endsWith(".js")) return "application/javascript";// Если файл заканчивается на ".js", то возвращаем заголовок "application/javascript" и завершаем выполнение функции else if (filename.endsWith(".png")) return "image/png";// Если файл заканчивается на ".png", то возвращаем заголовок "image/png" и завершаем выполнение функции else if (filename.endsWith(".jpg")) return "image/jpeg";// Если файл заканчивается на ".jpg", то возвращаем заголовок "image/jpg" и завершаем выполнение функции else if (filename.endsWith(".gif")) return "image/gif";// Если файл заканчивается на ".gif", то возвращаем заголовок "image/gif" и завершаем выполнение функции else if (filename.endsWith(".ico")) return "image/x-icon";// Если файл заканчивается на ".ico", то возвращаем заголовок "image/x-icon" и завершаем выполнение функции return "text/plain";// Если ни один из типов файла не совпал, то считаем что содержимое файла текстовое, отдаем соответствующий заголовок и завершаем выполнение функции }Нет конечно. Скорее всего нужно так:
if(path.endsWith("/jquery.min.js")) path ="/jquery.min.js";Только вот , по моему, стандартный SPIFFS не поддерживает две точки в имени. Так что имя файлы нужно привести к нормальному виду. Более того конструкция
if(path.endsWith("/")) path +="index.html"не однозначна, например на запрос типа /blablabla/ она будет пытаться отправить файл /blablabla/index.html, которого , конечно, на диске не будет.Хранить в коде можно как угодно - как удобнее программе. Например в одном моём проекте, где нужно хранить много ссылок на разные HTTP-ресурсы, они хранятся в виде URL-ов без префикса протокола (http://). Протокол хранится отдельно - двоичным числом. Да и сами URL-ы хранятся в сжатом виде и тупым текстовым поиском их не найдёшь.
client.println("<script>"); // начало скрипта jquery_min = SPIFFS.open("/jquery_min.txt", "r"); // открыть файл с текстом скрипта и присвоить его содержимое jquery_min if (!jquery_min) { Serial.println("file open failed");} // "открыть файл не удалось" } while (jquery_min.available()) { client.print(char(jquery_min.read())); // вывод всех символов } jquery_min.close(); client.println("</script>"); //конец скриптаКод целиком
#include <Servo.h> #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <WiFiUdp.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #include <FS.h> // Библиотека файловой системы #include <ArduinoOTA.h> // Библиотека OTA-прошивки const char *ssid = "SSID"; //Имя сети вайфай const char *password = "password"; // пароль вайфай File jquery_min; // для чтения файла Servo myservo; // создаем экземпляр класса «Servo», Servo myservo1; // чтобы с его помощью управлять сервоприводом; // большинство плат позволяют // создать 12 объектов класса «Servo» // GPIO-контакт, к которому подключен сервопривод: static const int servoPin = 5; static const int servo1Pin = 4; // создаем веб-сервер на порте «80»: WiFiServer server(80); // переменная для хранения HTTP-запроса: String header; String valueString = String(170); String valueString1 = String(180); int pos1 = 0; int pos2 = 0; void setup() { Serial.begin(115200); SPIFFS.begin(); // инициализируем библиотеку для работы с файловой системой Serial.print("Connecting to "); myservo.attach(servoPin, 544, 1520);; // привязываем сервопривод, myservo1.attach(servo1Pin); // подключенный к контакту «servoPin», // к объекту «myservo» // подключаемся к WiFi при помощи заданных выше SSID и пароля: Serial.print("Connecting to "); // "Подключаемся к " Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } ArduinoOTA.setHostname("ESP8266_Серво-привод_антенны"); // Задаем имя сетевого порта //ArduinoOTA.setPassword((const char *)"0000"); // Задаем пароль доступа для удаленной прошивки ArduinoOTA.begin(); // Инициализируем OTA // печатаем локальный IP-адрес и запускаем веб-сервер: Serial.println(""); Serial.println("WiFi connected."); // "WiFi подключен." Serial.println("IP address: "); // "IP-адрес: " Serial.println(WiFi.localIP()); server.begin(); } void loop() { ArduinoOTA.handle(); // Всегда готовы к прошивке // начинаем прослушивать входящих клиентов: WiFiClient client = server.available(); if (client) { // если подключился новый клиент, Serial.println("New Client."); // печатаем сообщение // «Новый клиент.» // в мониторе порта; String currentLine = ""; // создаем строку для хранения // входящих данных от клиента; while (client.connected()) { // цикл while() будет работать // все то время, пока клиент // будет подключен к серверу; if (client.available()) { // если у клиента есть данные, // которые можно прочесть, char c = client.read(); // считываем байт, а затем Serial.write(c); // печатаем его в мониторе порта header += c; if (c == '\n') { // если этим байтом является // символ новой строки // если получили два символа новой строки подряд, // то это значит, что текущая строчка пуста; // это конец HTTP-запроса клиента, // а значит – пора отправлять ответ: if (currentLine.length() == 0) { // HTTP-заголовки всегда начинаются // с кода ответа (например, «HTTP/1.1 200 OK») // и информации о типе контента // (чтобы клиент понимал, что получает); // в конце пишем пустую строчку: client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println("Connection: close"); // "Соединение: отключено" client.println(); // показываем веб-страницу: client.println("<!DOCTYPE html><html>"); client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"); client.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"); client.println("<link rel=\"icon\" href=\"data:,\">"); client.println("<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial; margin-left:auto; margin-right:auto;}"); client.println(".slider { width: 300px; }</style>"); client.println("<script>"); // начало скрипта jquery_min = SPIFFS.open("/jquery_min.txt", "r"); // открыть файл с текстом скрипта и присвоить его содержимое jquery_min if (!jquery_min) { Serial.println("file open failed"); // "открыть файл не удалось" } while (jquery_min.available()) { client.print(char(jquery_min.read())); // вывод всех символов } jquery_min.close(); client.println("</script>"); //конец скрипта // веб-страница: client.println("</head><body><h1>ESP8266 Управление сервомотором антенны</h1>"); // "Управление сервомотором // с помощью платы ESP32" client.println("<p>Позиция верх-вниз: <span id=\"servoPos\"></span></p>"); client.println("<input type=\"range\" min=\"70\" max=\"180\" class=\"slider\" id=\"servoSlider\" onchange=\"servo(this.value)\" value=\"" + valueString + "\"/>"); client.println("<p>Позиция лево-право: <span id=\"servoPos1\"></span></p>"); client.println("<input type=\"range\" min=\"0\" max=\"180\" class=\"slider\" id=\"servoSlider1\" onchange=\"servo1(this.value)\" value=\"" + valueString1 + "\"/>"); client.println("<script>var slider = document.getElementById(\"servoSlider\");"); client.println("var slider1 = document.getElementById(\"servoSlider1\");"); client.println("var servoP = document.getElementById(\"servoPos\"); servoP.innerHTML = slider.value;"); client.println("var servoP1 = document.getElementById(\"servoPos1\"); servoP1.innerHTML = slider1.value;"); client.println("slider.oninput = function() { slider.value = this.value; servoP.innerHTML = this.value; }"); client.println("slider1.oninput = function() { slider1.value = this.value; servoP1.innerHTML = this.value; }"); client.println("$.ajaxSetup({timeout:1000}); function servo(pos) { "); client.println("$.get(\"/?value=\" + pos + \"&\"); {Connection: close};}"); client.println("function servo1(pos) { "); client.println("$.get(\"/?value1=\" + pos + \"&\"); {Connection: close};}</script>"); client.println("</body></html>"); //GET /?value=180& HTTP/1.1 if (header.indexOf("GET /?value=") >= 0) { pos1 = header.indexOf('='); pos2 = header.indexOf('&'); valueString = header.substring(pos1 + 1, pos2); //Rotate the servo myservo.write(valueString.toInt()); Serial.print("Got servro val: "); Serial.println(valueString); } else if (header.indexOf("GET /?value1=") >= 0) { pos1 = header.indexOf('='); pos2 = header.indexOf('&'); valueString1 = header.substring(pos1 + 1, pos2); //Rotate the servo myservo1.write(valueString1.toInt()); Serial.print("Got servro1 val: "); Serial.println(valueString1); } // конец HTTP-ответа задается // с помощью дополнительной пустой строки: client.println(); // выходим из цикла while(): break; } else { // если получили символ новой строки, // очищаем текущую строку «currentLine»: currentLine = ""; } } else if (c != '\r') { // если получили любые данные, // кроме символа возврата каретки, currentLine += c; // добавляем эти данные // в конец строки «currentLine» } } } // очищаем переменную «header[]»: header = ""; // отключаем соединение: client.stop(); Serial.println("Client disconnected."); // "Клиент отключился." Serial.println(""); } }84 килобайта, влезет. Только со SPIFFS грузится будет долго, нужно с кешированием шаманить.
Да, Вы абсолютно правы! Эта простая страничка грузится почти 9 секунд! И даже реакция на перемещение ползунков примерно 1 секунда!
spiffs работает приемлемо. Веб-сервер медленный.
spiffs работает приемлемо. Веб-сервер медленный.
Переход на внешнюю SDшку с фатом дает прирост скорости в два раза.