Помогите решить, зависает код esp8266

Тема в разделе "ESP8266, ESP32", создана пользователем AlltaiR, 29 ноя 2022.

  1. AlltaiR

    AlltaiR Нуб

    Всем привет.
    Такая проблема: создал пару кнопок в HTML, чтобы управлять шаговым двигателем. Суть при нажатии кнопки вверх двигатель делает заданное в коде количество оборотов, вниз аналогично. С браузера посылаю запрос по выданному IP/get1 (вверх). Если прокрутился до конца, посылаю запрос IP/get2 крутится в низ, т.е. все нормально. НО если нажал вверх и во время движения нажал вниз, то скрипт зависает и больше ни на что не реагирует.
    Подскажите что нужно поправить, что бы не нужно было ждать пока он докрутится до конца, а можно было прервать и направить в противоположную сторону.
    Спасибо.
    Код (C++):
    #include <CustomStepper.h>
    #include <ESP8266WiFi.h>
    #include <ESP8266WebServer.h>
    #define verh 0
    #define niz 8      
    long schet = 0; //Счетчик шагов
    long shagi = 0;
    CustomStepper stepper(32, 33, 25, 26);
    const char* ssid = "xxxxx";  
    const char* password = "xxxxx";  
    ESP8266WebServer server(80);
     
    void setup() {
      Serial.begin(115200);
      delay(100);
      Serial.println("Connecting to ");
      Serial.println(ssid);
      WiFi.begin(ssid, password);  
      while (WiFi.status() != WL_CONNECTED)
      {
        delay(1000);
        Serial.print(".");
      }
      Serial.println("");
      Serial.println("WiFi connected..!");
      Serial.print("Got IP: ");
      Serial.println(WiFi.localIP());
     
      server.on("/get1", get1);
      server.on("/get2", get2);
     
      server.begin();
      Serial.println("HTTP server started");
     
      stepper.setRPM(12);   // Устанавливаем кол-во оборотов в минуту
      stepper.setSPR(2048);
    }
     
    void get1()
    {
      shagi = niz;
      server.send ( 200, "text/plain", "works well" );
    }
     
    void get2()
    {  
      shagi = verh;
      server.send ( 200, "text/plain", "works well" );
    }
     
    void loop() {
      server.handleClient();  // обработка входящих WEB запросов
     
     if (stepper.isDone() && schet < shagi){
        Serial.println("Up");
        stepper.setDirection(CCW);   // Устанавливает направление вращения. Может принимать 3 значения: CW - по часовой, CCW - против часовой
        stepper.rotateDegrees(45);   // В градусах
        schet++;  
        }
      if (stepper.isDone() && schet > shagi){
        Serial.println("Down");
        stepper.setDirection(CW);
        stepper.rotateDegrees(45);
        schet--;  
        }
    stepper.run();
    }
     
  2. Unixon

    Unixon Оракул Модератор

    Поставьте отладочных принтов в loop().
    Если тыркнуть два раза "вверх" или два раза "вниз", не дожидаясь конца движения, тоже виснет?
     
  3. AlltaiR

    AlltaiR Нуб

    После нажатия в противоположную сторону, больше ни на что не реагирует, тыкал по несколько раз.
     
  4. parovoZZ

    parovoZZ Гуру

    видимо, прежде чем подавать команду, необходимо проверить вращается ли двигатель. Если да, то подать команду стоп, а далее выполнить запрошенную команду. Если запрошенная команда уже выполняется, то команду отклонить.
     
  5. AlltaiR

    AlltaiR Нуб

    Здесь в первой строчке проверяем завершил ли мотор движение stepper.isDone()
    Код (C++):
    if (stepper.isDone() && schet > shagi){  // завершил движение
        Serial.println("Down");
        stepper.setDirection(CW);  // задаем направление
        stepper.rotateDegrees(45);  //угол в градусах
        schet--;  //прибавляем значение
        }
     
  6. parovoZZ

    parovoZZ Гуру

    и где здесь команда СТОП?
     
  7. AlltaiR

    AlltaiR Нуб

    "проверить вращается ли двигатель. Если да, то подать команду стоп"
    Так зачем команда стоп, если мы проверили что двигатель не вращается?
    Или я чего-то не понял?
     
  8. AlltaiR

    AlltaiR Нуб

    Тоже самое пробовал, но через кнопку, все нормально работает, нажимаешь в момент вращения и начинает крутить в другую сторону.
    В чем подвох не пойму.
    Я новичок в этом, старайтесь пожалуйста объяснить простыми словами, что поправить.
    Код (C++):
    #include <CustomStepper.h>
    #include "GyverButton.h"
    #define verh 0
    #define niz 4          //Число шагов для положения
    #define seredina 2
    boolean stop = 0;
    long schet = 0; //Счетчик шагов
    long shagi = 0;
    CustomStepper stepper(32, 33, 25, 26);
    GButton butt1(17); // Кнопка

    void setup() {
      Serial.begin(9600);
      stepper.setRPM(12);
      stepper.setSPR(2048);
      butt1.setTimeout(700);
      butt1.setType(LOW_PULL);
      butt1.setDirection(NORM_CLOSE); // NORM_OPEN - кнопка нормально-разомкнутая NORM_CLOSE - нормально-замкнутая
      butt1.setTickMode(AUTO);  //Выставляем опрос кнопок в режим АВТО
    }

    void loop() {

    if (butt1.isSingle()){shagi = niz;}  //одно нажатие
    if (butt1.isDouble()){shagi = verh;} //два нажатия
    if (butt1.isHolded()){shagi = schet; stop = 1;}

    if (stepper.isDone() && schet < shagi){
        Serial.println("Time1");
        stepper.setDirection(CCW);
        stepper.rotate(1);
        schet++;
        }
      if (stepper.isDone() && schet > shagi){
        Serial.println("Time2");
        stepper.setDirection(CW);
        stepper.rotate(1);
        schet--;
        }
      if (stepper.isDone() && stop == 1){
        Serial.println("Time3");
        stepper.setDirection(STOP);
        stepper.rotate();
        stop = 0;    
        }
    stepper.run();
    }
     
    Последнее редактирование: 29 ноя 2022
  9. Unixon

    Unixon Оракул Модератор

    Откуда у вас конкретно библиотека CustomStepper?
    Если отсюда ( https://github.com/jogaye/Citi7-21/tree/master/Arduino/Libraries/CustomStepper ), то оно само шаги считает.

    Мне код loop() не нравится, это не автомат, а какая то ерунда.
    Код (C++):

    #define CMD_NONE 0
    #define CMD_CCW  1
    #define CMD_CW   2
    #define CMD_STOP 3

    void loop()
    {
      int cmd = CMD_NONE;
      if (butt1.isSingle()) { cmd = CMD_CCW; }
      if (butt1.isDouble()) { cmd = CMD_CW; }
      if (butt1.isHolded()) { cmd = CMD_STOP; }

      switch (cmd)
      {
       default: case CMD_NONE:
       {
         stepper.run();
         break;
       }
       case CMD_CCW:
       {
         stepper.setDirection(CCW);
         stepper.rotateDegrees(45);
         break;
       }
       case CMD_CW:
       {
         stepper.setDirection(CW);
         stepper.rotateDegrees(45);
         break;
       }
       case CMD_STOP:
       {
         stepper.setDirection(STOP);
         break;
       }
      }
    }
     
     
  10. AlltaiR

    AlltaiR Нуб

    Unixon благодарю за ваш вариант кода, попробую. Но с кнопкой у меня и так работает, мне бы найти причину почему через веб команды подвисает.
    Да библиотеку использую именно эту.
     
  11. Unixon

    Unixon Оракул Модератор

    Сначала убедитесь, что это вообще из-за веб, а не из-за поломанной логики.

    Отлаживайте по частям.
    1) Подачу команд можно имитировать по таймеру без реальной их передачи на устройство. Естественно, время подбираете так, чтобы серва успевала или не успевала отработать предыдущую команду.
    2) Проверить прием команд устройством можно без управления сервой, просто ответом в терминал.
    3) Все вместе.

    Вот если 1 и 2 по отдельности будут работать, а вместе нет, тогда есть с чем разбираться.