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 - вставьте код правильно, с номерами строк, чтоб я мог указать вам ошибку
Через 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 - помог, спасибо большое. Все решено.
А можно ли вместо запроса
а так написать можно?
Или лучше всё-таки сделать отдельные функции для каждого сервопривода? И проверять на соответствие
Подскажите пожалуйста, кто разбирается!
В 1 функцию.
в него "запихиваются" значения всех найденных позиций символа "=", а затем аналогичным образом, символа "&". Используется метод "push"
Не тоже самое. Операция ++ выполняется после того , как будет выполнено основное выражение, а +1 сначала будет прибавлено 1, а потом уже выполнено основное выражение.
Такова особенность выражения ++
Не забываем про наличие операции ++currentPos :)
Да с плюсами перед переменной работает! Однако странно, что в отладчике, НЕ видно как currentPos увеличивается на 1.
Как не пиши, хоть ++currentPos, хоть currentPos+1 все равно.
Что это? Глюк отладчика или так и должно быть?
А вот если написать так, видно!
У вас же не си. Зависания это может быть проблема отладчика, брaузера, да всего чего угодно. Может у вас где то брейк установлен и срабатывает. Зачем вы вообще отлаживаете этот простейший код ? Проверьте без отладчика и двигайтесь дальше.
Вот смотрите строка
currentLeftPos = header.indexOf('=', currentLeftPos++);
Происходит следующее в момент работы header.indexOf значение currentLeftPos равно 12, по окончании работы оно увеличивается на единицу и становится 13, но поиск проводился с символа номер 12, а этот символ удовлетворяет условиям, поскольку вы присваиваете результат header.indexOf этой переменной, то она вновь становится 12
currentLeftPos = header.indexOf('=', currentLeftPos+1);
currentLeftPos = header.indexOf('=', ++currentLeftPos);
Большое спасибо Вам за детальное объяснение!
Готовый код. Кому нужно будет.
Готовый код. Кому нужно будет.
не взлетит, сайт ссылки ломает...к примеру 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 заменять.
Ни к каким внешним ресурсам, насколько я понял, библиотека не обращается.
Значит файл с ней можно загрузить в файловую систему и просто указать на него ссылку?
И эта строка
client.println("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>");
Нет конечно. Скорее всего нужно так:
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-ы хранятся в сжатом виде и тупым текстовым поиском их не найдёшь.
Код целиком
84 килобайта, влезет. Только со SPIFFS грузится будет долго, нужно с кешированием шаманить.
Да, Вы абсолютно правы! Эта простая страничка грузится почти 9 секунд! И даже реакция на перемещение ползунков примерно 1 секунда!
spiffs работает приемлемо. Веб-сервер медленный.
spiffs работает приемлемо. Веб-сервер медленный.
Переход на внешнюю SDшку с фатом дает прирост скорости в два раза.