• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

WebServer CustomStepper

gerkimuyda

New member
while(!stepper.isDone()) {stepper.run();}
По поводу вашего решения: Задаем двигателю крутиться stepper.rotate(); - это постоянный поворот без окончания. Что получаем? На нас нападает сторожевой пес и кусает за попку!
Это кроме того, что мы блокируем работу всех остальных фоновых задач SDK (из видимых - вайфай отваливается).

Зачем городить костыли на захламленном неправильном коде, если проще написать сразу правильно?
Что нам надо? Зайти в цикл, пробежаться по нему и выйти вконце (без прерывания в середине).
Что делаем? Вставляем в него stepper.run(); чтобы работал наш моторчик.

Код:
void loop()  {
     if( !stepper.isDone() ) { stepper.run(); } // Для правильности и программной красоты вставим перед ним проверку.

/* Далее мы пишем код, в котором проверяем подключенность клиента и приход от него команд. Т.е. мы не блокируем работу цикла ожиданием команд,
    а выполняем блок действий ТОЛЬКО если есть команды, иначе - продолжаем работу цикла.
*/
  WiFiClient client = server.available();
   if( client ) {
      if( client.available() ) {
        String req = client.readStringUntil('\r');
        if( req.indexOf("/stepper/up") != -1 )   { /* тут выполняем stepper.disable(); чтобы прервать любые задачи двигателя и нужные нам новые настройки */ }
        /* другие блоки запросов */

       // Отдаем ответ на наш запрос
       client.print( String("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n") + respMsg );
     } //client.available
   } //client
} //loop()
@gerkimuyda очень тщательно проверил код - но разные замечания имеют разную степень влияния на конечный результат работы программы.
Поэтому я и говорю, что правильнее и проще с нуля написать код так, как он должен работать. Чем пытаться накостылять наставить костылей в этом глюкокоде. ;):)o_O

рискую получить кучу критики
Не переживайте. Мне очень нравится лаконичный и выдержанный стиль вашего общения на форуме. Также приятны совместные диалоги и попытки развязывания тех или иных вопросов.

Читал где-то что именно delay ибивает весь процесс, нужно использовать millis. Убрать delay , а правильно ли это будет? Или while заменить if.
delay - приостанавливает выполнение текущего кода на заданное время
millis - возвращает текущее время (со старта процессора)
Если перестроить саму структуру программы, избавившись от delay и white (тех участков, которые блокируют наш основной цикл) - это и будет правильным подходом.

Вот представим ситуацию, что вы в добавок к веб-клиенту решите подключить кнопки к вашему модулю, чтобы не только со смарта управлять поворотом жалюзи (или к чему будет прикреплен шаговый двигатель), но и с выключателя, расположенного возле окна. При старом подходе к алгоритму вы получите "затык" с ожиданием команд через http и полное игнорирование нажатий на кнопки! При новой структуре - вы можете продолжать спокойно работать и даже разобрать ситуацию, если пользователь зажмет кнопку "вверх" и при этом пошлет команду "вниз" (вдруг это хитрый способ блокировки управлением от баловства детей?) :cool:
 

gerkimuyda

New member
Не уверен, но вроде бы после '+ respMsg' необходимо добавить сакральные ' +"\r\n\r\n" '
С начала идут заголовки ответа (headers), потом само тело ответа, которое отделяется от заголовком двумя переводами строки (пустой строкой). В конце тела ответа можно не ставить перевод строки. В данном случае, оформление тела я возложил на respMsg. Которое может быть пустым (тогда ответ тоже будет пустым).

\r - carriage return (возврат каретки (курсора))
\n - new line ( новая строка)
Почему в паре? Когда мониторы еще были ламповыми, а принтеры - матричными, эти символы использовались для управления оформлением. Чтобы обновить текущую строку без перевода на новую (например вывести индикатор процентов выполненного), необходимо было перевести курсор на начало строки без перевода строки и поверх напечатать новую. А \n на принтере опускал позицию головки на следующую строку, но не возвращал ее в начало строки.
 
Последнее редактирование:

IgorFX

New member
@gerkimuyda вы прям в воду глядите... т.е. в код))) это управление рулонной шторой). Будут и кнопки и фоторезистор. На 433Мгц управление думаю уже по пинам и питанию не пройдёт. У Wemos по 3,3 в проблема там стаб или микросхема дохнет( номинал 600мА, с учетом КНР /2 так и выходит из строя))
По коду теперь все понятно, огромное спасибо.
Есть ещё вопрос по поводу драйвера uln2003 довольно таки большой и прожорливый. Для Wemos есть шилд tb6612fng но там все рассчитано на два коллекторных двигателя и все это по i2c. Видео есть и код. Но как реализованно. Шилд можно перепрошить но это слишком сложно для меня по крайней мере. Или всё-таки можно скетчем обойтись?IMG_4682.JPGIMG_4681.JPG
 
Последнее редактирование:

gerkimuyda

New member
В схемотехнике я не так силен, как в программировании. Тут уж пусть другие товарищи подсказки сделают.
 

IgorFX

New member
Код:
void loop()  {
     if( !stepper.isDone() ) { stepper.run(); } // Для правильности и программной красоты вставим перед ним проверку.

/* Далее мы пишем код, в котором проверяем подключенность клиента и приход от него команд. Т.е. мы не блокируем работу цикла ожиданием команд,
    а выполняем блок действий ТОЛЬКО если есть команды, иначе - продолжаем работу цикла.
*/
  WiFiClient client = server.available();
   if( client ) {
      if( client.available() ) {
        String req = client.readStringUntil('\r');
        if( req.indexOf("/stepper/up") != -1 )   { /* тут выполняем stepper.disable(); чтобы прервать любые задачи двигателя и нужные нам новые настройки */ }
        /* другие блоки запросов */

       // Отдаем ответ на наш запрос
       client.print( String("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n") + respMsg );
     } //client.available
   } //client
} //loop()
Данный код не работает...страница не доступна. Если убрать if( client.available() ) то страница доступна...но все осталось как прежде делает шаг и все.
 

kab

New member
Код:
void loop()  {
     if( !stepper.isDone() ) { stepper.run(); } // Для правильности и программной красоты вставим перед ним проверку.

/* Далее мы пишем код, в котором проверяем подключенность клиента и приход от него команд. Т.е. мы не блокируем работу цикла ожиданием команд,
    а выполняем блок действий ТОЛЬКО если есть команды, иначе - продолжаем работу цикла.
*/
  WiFiClient client = server.available();
   if( client ) {
      if( client.available() ) {
        String req = client.readStringUntil('\r');
        if( req.indexOf("/stepper/up") != -1 )   { /* тут выполняем stepper.disable(); чтобы прервать любые задачи двигателя и нужные нам новые настройки */ }
        /* другие блоки запросов */

       // Отдаем ответ на наш запрос
       client.print( String("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n") + respMsg );
     } //client.available
   } //client
} //loop()
Данный код не работает...страница не доступна. Если убрать if( client.available() ) то страница доступна...но все осталось как прежде делает шаг и все.
Вы не совсем поняли, Вам надо взять первоначальный Ваш текст и поменять некоторые строчки по образцу, показанному @gerkimuyda. Перед проверкой поместите переработанный текст в сообщение - надо будет проверить, как Вы справились с заданием :):):).

После этого я еще покажу, где надо подправить - жизнь идет вперёд - появляются новые идеи
 

gerkimuyda

New member
Да, kab совершенно верно говорит: Если вы внимательно посмотрите мой код, то поймете, что это всего-лишь шаблон (или образец), построенный из вашего кода, и его необходимо поправить под себя. У меня двигателей нету, чтобы обкатать на практике ваш код. А по поводу http-сервера - есть и другие способы реализации его (примеров много в Ардуине). Я даже не проверял работоспособность, а просто скопировал ваши строчки. Попробуйте подходящий для вас пример из библиотеки esp8266.
И помните, что часто проблемы с библиотеками бывают уже решены и требуют только обновления версии. Поэтому всегда проверяйте, что у вас последняя версия (это касается и http-сервера и SDK в библиотеке esp8266 для ардуины). https://github.com/esp8266/Arduino/releases/download/2.4.0-rc2/package_esp8266com_index.json
 

IgorFX

New member
Да, kab совершенно верно говорит: Если вы внимательно посмотрите мой код, то поймете, что это всего-лишь шаблон (или образец), построенный из вашего кода, и его необходимо поправить под себя. У меня двигателей нету, чтобы обкатать на практике ваш код. А по поводу http-сервера - есть и другие способы реализации его (примеров много в Ардуине). Я даже не проверял работоспособность, а просто скопировал ваши строчки. Попробуйте подходящий для вас пример из библиотеки esp8266.
И помните, что часто проблемы с библиотеками бывают уже решены и требуют только обновления версии. Поэтому всегда проверяйте, что у вас последняя версия (это касается и http-сервера и SDK в библиотеке esp8266 для ардуины). https://github.com/esp8266/Arduino/releases/download/2.4.0-rc2/package_esp8266com_index.json
Ответ сервера закрывает соединение и рушит процесс stepper.run(). Закомментировал все работает.
Код:
void loop() 
{
  if( !stepper.isDone() )
    {
    stepper.run();
    }
    WiFiClient client = server.available();
    if( client )
      {
          String respMsg = "";
          Serial.println("new client");
          String req = client.readStringUntil('\r');       
          Serial.println(req);
          if( req.indexOf("/window/up") != -1 )  
            {
            stepper.setDirection(STOP);
            stepper.setDirection(CW);
            stepper.rotate(12);
            respMsg = "OK: MOTOR Going Up"; 
            }
          if( req.indexOf("/window/down") != -1 )  
             stepper.setDirection(STOP);
            stepper.setDirection(CCW);
            stepper.rotate(12);
            respMsg = "OK: MOTOR Going Down";   
            }
//      client.print( String("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n") + respMsg );
   }//client
} //loop()
 

IgorFX

New member
Код:
void loop()  {
     if( !stepper.isDone() ) { stepper.run(); } // Для правильности и программной красоты вставим перед ним проверку.
  WiFiClient client = server.available();
   if( client ) {
     " if( client.available() ) {"
        String req = client.readStringUntil('\r');
        if( req.indexOf("/stepper/up") != -1 )
{
digitalWrite(BUILD_IN_LED, HIGH);
}
       client.print( String("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n") + respMsg );
     "} //client.available"
   } //client
} //loop()
Сeрвер не доступен, если мы уберем строки выделенные кавычками все работает но только одно действие и ответ мы получим. попробуйте)
 

gerkimuyda

New member
Я вот вчера в другой теме приводил самый простой рабочий код сервера:
Код:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
ESP8266WebServer server(80);
void handleRoot() { server.send(200, "text/html", "<!DOCTYPE HTML>\r\n<html>Hello!</html>"); }
void setup() {
  WiFi.begin("ssid", "password");
  server.on("/", handleRoot);
  server.begin();
}
void loop() {  server.handleClient(); }
Никаких проблем с ним. Попробуйте. (Для каждого запроса создаете свою отдельную функцию и делаете привязку ее к запросу)
 

IgorFX

New member
Я вот вчера в другой теме приводил самый простой рабочий код сервера:
Код:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
ESP8266WebServer server(80);
void handleRoot() { server.send(200, "text/html", "<!DOCTYPE HTML>\r\n<html>Hello!</html>"); }
void setup() {
  WiFi.begin("ssid", "password");
  server.on("/", handleRoot);
  server.begin();
}
void loop() {  server.handleClient(); }
Никаких проблем с ним. Попробуйте. (Для каждого запроса создаете свою отдельную функцию и делаете привязку ее к запросу)
Сегодня начал разбирать похожий пример. А отдельными функциями это огород, они итак в библиотеке прописаны(пробовал кстати отдельно под каждое действие прописать).
Обновил библиотеки с гитхаба все тоже самое. Надо я так думаю в самих WiFi.h и webserver.h покопаться.

Хотя нет в данном примере к каждому запросу и прописывается функция. А в теле исполняем клиента.
 
Последнее редактирование:
Сверху Снизу