Некорректно работает скетч c Acselstepper. у одного двига припадки.

Тема в разделе "Моторы, сервоприводы, робототехника", создана пользователем РоманИ, 25 фев 2019.

  1. РоманИ

    РоманИ Нерд

    Уважаемы коллеги! Прошу помощи в проверке скетча! Ситуация такая. Бьюсь над сверлилкой плат в полуавтоматическом режиме. координатный столик приводится двумя шаговиками из принтера. По ТТЗ координатный столик управляется джойстиком (быстрая подача) или 4-я кнопками (дискретный режим по 2.54 мм).
    суть проблемы: при управлении джойстиком по оси Y мотор работает не корректно. Двигается не равномерно, может остановиться, а может совершить скачек назад с бешеной скоростью. дискретное перемещение работает при этом в основном корректно. В случае,удаления части программы, касающейся дискретного перемещения, управление джойстиком приносит только радость, чем оправдывает свое название.
    замечание! подозрение на некорректный код. библиотеку Acselstepper до конца не понимаю. Описание команд не привносит правильного понимания, поэтому буду признателен, если кто ссылку кинет на подробное разжевывывание Acselsteppera.
    Код (C++):
    #include <AccelStepper.h>
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    AccelStepper motorX(1,6,7); //использует пин 7 и 6 для dir и step, 1 - режим "external driver"
    AccelStepper motorY(1,11,12); //использует пин 12 и 11 для dir и step, 1 - режим "external driver"                              
    AccelStepper motorZ(1,5,2); //использует пин 2 и 5 для dir и step, 1 - режим "external driver"
    LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей

    #define Enable3    0 // устанавливаем пин активизации драйвера оси Z
    #define Enable2    1  // устанавливаем  пин активизации драйвера оси Y
    #define MOT_PIN    3  // устанавливаем пин мотора дрели
    #define Enable1    4  // устанавливаем пин активизации драйвера Х
    #define DR_PIN     9  //устанавливаем  пин кнопки вертикальной подачи дрели
    #define SW_1       10 // устанавливаем пин переключателя шага дискретного перемещения
    #define SW_2       13 // утанавливаем пин второго шага дискретного премещения
    #define KNOB_PIN   A0 // вход кнопок дискретного перемещения
    #define POTDR_PIN  A1 // потенуиометр скорости вращения дрели
    #define POTJX      A7 // потенциометр джойстика по оси Х
    #define POTJY     A6  //потенциометр джойстика  по оси Y
    int J6;               // переменная джойстика по осии Х
    int J7;               // переменная джойстика по оси Y
    int dir1;             // переменная направления движения при управлении джойстиком по оси Х
    int dir2;             // переменная направления движения при управлении джойстиком по оси Y
    int AA0;               // переменная а/входа кнопок дискретного перемещения
    void setup() {
      lcd.init();                 // инициируем дисплей              
      lcd.backlight();            // Включаем подсветку дисплея
      lcd.setCursor(2, 1);        // устанавливаем курсор
      lcd.print("version 3.2");   // выводим на экран номер версии программы

      pinMode(Enable3, OUTPUT);   // Настраиваем вывод Enable3 на работу в режиме выхода
      pinMode(Enable2, OUTPUT);   // Настраиваем вывод Enable2 на работу в режиме выхода
      pinMode(MOT_PIN, OUTPUT);   // Настраиваем вывод MOT_PIN на работу в режиме выхода
      pinMode(Enable1, OUTPUT);   // Настраиваем вывод Enable1 на работу в режиме выхода                      
      pinMode(DR_PIN, INPUT);     // настраиваем вывод DR_PIN на работу в режиме ввода                
      pinMode(SW_1, INPUT);       // Настраиваем вывод SW_1 на работу в режиме выхода
      pinMode(SW_2, INPUT);       // Настраиваем вывод SW_2 на работу в режиме выхода
                 
      pinMode (KNOB_PIN, INPUT);  // Настраиваем вывод KNOB_PIN на работу в режиме входа
      pinMode (POTDR_PIN, INPUT); // Настраиваем вывод POTDR_PIN на работу в режиме входа
      pinMode (POTJX, INPUT);     // Настраиваем вывод POTJX на работу в режиме входа
      pinMode (POTJY, INPUT);     // Настраиваем вывод POTJY на работу в режиме входа

      digitalWrite(Enable1, LOW); //отключаем драйверы                                  
      digitalWrite(Enable2, LOW); //отключаем драйверы      
      digitalWrite(Enable3, LOW); //отключаем драйверы      

      motorX.setMaxSpeed(15000);     //устанавливаем максимальную скорость вращения ротора двигателя (шагов/секунду)по оси Х
      motorX.setAcceleration(15000); //устанавливаем ускорение (шагов/секунду^2) по оси Х
      motorY.setMaxSpeed(15000);     //устанавливаем максимальную скорость вращения ротора двигателя (шагов/секунду)по оси Y
      motorY.setAcceleration(15000); //устанавливаем ускорение (шагов/секунду^2) по оси Y
      motorZ.setMaxSpeed(500);       //устанавливаем макс скорость вращения ротора двигателя (шагов/секунду)по оси Х
      motorZ.setAcceleration(500);   //устанавливаем ускорение (шагов/секунду^2) по оси Z
      motorZ.setCurrentPosition(0);      // типа думал  обнулять сначала ось Z
      motorZ.moveTo(-500);               // Хрен чего, но без этого работает не правильно т.е.  первый ход вниз  в половину меньше чем откат назад и все последующие ходы вперед назад
      motorZ.setSpeed(50);               // устанавливаем скорость хрен чего
      motorZ.runToPosition();            // такая же ботва
      delay (2000);
    }
     

    Вложения:

  2. РоманИ

    РоманИ Нерд

    продолжение скетча
    Код (C++):
    void loop() {
    int Value = analogRead(POTDR_PIN); // присваиваем переменной Value значения потенциометра А1 сигнал шим дрели
    int  revspeed = Value/4;           // делим занчение переменной (0..1024) на 4 (0..255)
    analogWrite(MOT_PIN, revspeed);    // подаем на вывод мотора дрели ШИМ сигнал
      //LCD();                          // команда вызова подпрограммы вывода на дисплей значений J6 & J7
    int DR_KNOB = digitalRead(DR_PIN); // считиваем кнопку 9 привода вертикальной подачи
    if (DR_KNOB==HIGH){                // если она нажата
                       drill();         // выполняем подпрограмму сверления
                       }
      J6=analogRead (POTJX);            // считываем значение а\входа 6 присваеваем переменной J6 (джойстик Х)
      J7=analogRead (POTJY);            // считываем значение а\входа 7 присваеваем переменной J7 (джойстик Y)
      if (J6<440){                      //  определяем положение джойстика от вертикального
                dir1=1;                 // определяем направление движения по оси Х
                digitalWrite (Enable1,HIGH);
                } else if (J6>585){  
                                dir1=-1; // определяем положение движения  по оси Х в обратную сторону
                                digitalWrite (Enable1,HIGH);
                                } else {  //если вертикально , тогда стоим на месте по оси Х
                                       J6=0;
                                       digitalWrite (Enable1,LOW);
                                       }
    if (J6!=0){                          // если джойстик по оси Х отклонен
              motorX.move(20*dir1);      // двигаемся мотор Х на 20 шагов ( я так думаю)
              }
    if (J7<440){                         // аналогичный кусок кода для оси Y
                dir2=1;
                digitalWrite (Enable2,HIGH);
                } else if (J7>585){
                                dir2=-1;
                                digitalWrite (Enable2,HIGH);
                                } else {
                                       J7=0;
                                       digitalWrite (Enable2,LOW);
                                       }
       if (J7!=0){
              motorY.move(20*dir2);
              }
        motorX.run();                     //запускаем в прокрутку работу мотора Х
        motorY.run();                    // запускаем работу мотора Y
     
        AA0=analogRead (KNOB_PIN);       // считываем значение а\входа 0 присваеваем переменной А0
      if (AA0<700){                     // Если нажата хоть каккая то кнопка оправляем исполнять подпрограмму дискретного перемещения fixstep()
                fixstep(AA0);           // закладываем значение  сигнала на А0
                   }
    }

    void drill() {                     // функция запуска привода мотора Z  привода подачи дрели
      digitalWrite(Enable3, HIGH);       // включаем драйвер Z
      motorZ.moveTo(500);              // Хрен чего
      motorZ.setSpeed(50);             // устанавливаем скорость хрен чего
      motorZ.runToPosition();          // типа чё мотора Z
      motorZ.moveTo(-motorZ.currentPosition()); // типа чё с минусом
      motorZ.runToPosition();           // типа опять мотроа Z
      digitalWrite(Enable3, LOW);       // теперь деактивируем драйвер Z
      }

    void fixstep(int AF0){              // подпрограмма получает значение с вывода АО и присваивает AF0
      if (AF0 < 600) {                  // Значение меньше 600 – нажата кнопка right
        digitalWrite(Enable2, HIGH);    // активируем драйвер
        motorY.setSpeed(30);           // непонятно для чего
        motorY.runToNewPosition(80);    // как я понял перемещаем на 80 шагов Y
        motorY.setCurrentPosition(0);   // если не обнулять, то перемещение происходит однократно (???)
        digitalWrite(Enable2, LOW);     // деактивируем драйвер
        }
      else if (AF0 < 680) {             // Значение больше 600, но меньше 680 – нажата кнопка up
        digitalWrite(Enable1, HIGH);    // активируем драйвер
        motorX.setSpeed(30);           // непонятно для чего
        motorX.runToNewPosition(80);    // как я понял перемещаем на 80 шагов Х
        motorX.setCurrentPosition(0);   // если не обнулять, то перемещение происходит однократно (???)
        digitalWrite(Enable1, LOW);
        }
      else if (AF0< 700) {              //  Значение больше 680, но меньше 700 – нажата кнопка LEFT
         digitalWrite(Enable2, HIGH);   // активируем драйвер
         motorY.setSpeed(30);          // непонятно для чего
         motorY.runToNewPosition(-80);  // как я понял перемещаем на 80 шагов Y в обратную сторону
         motorY.setCurrentPosition(0);  // если не обнулять, то перемещение происходит однократно (???)
         digitalWrite(Enable2, LOW);
        }
      else if (AF0< 750) {              // Значение больше 700, но меньше 750 – нажата кнопка DOWN
         digitalWrite(Enable1, HIGH);   // активируем драйвер
         motorX.setSpeed(30);          // непонятно для чего
         motorX.runToNewPosition(-80);  // как я понял перемещаем на 80 шагов Х в обратную сторону
         motorX.setCurrentPosition(0);  // если не обнулять, то перемещение происходит однократно (???)
         digitalWrite(Enable1, LOW);    // деактивируем драйвер
        }
        delay(200);
    }
     
    Последнее редактирование: 25 фев 2019
  3. Tomasina

    Tomasina Сушитель лампочек Модератор

    Закомментируй весь вывод на дисплей - проблема остается?
    Описание команд Acсelstepper я выкладывал тут.
     
  4. РоманИ

    РоманИ Нерд

    вывод на дисплей вообще убрал, ибо он мешал (тормозил ) . он был нужен при программировании контролировать положение джойстика. надобность в дисплее пока отпала.
    победил судороги. удалось запихнуть в отдельную функцию. Спасибо откликнувшимся
     
  5. РоманИ

    РоманИ Нерд

    описание комманд видел спасибо. а вот уразуметь полностью не удается. например почему в коде необходимо обнулять текущее положение в фунции кода fixstep см. выше
    или как сделать относительное перемещение на определенное количество шагов. или в фунции drill() пермещение двигателя происходит первый раз на 500 (250 ?)вниз потом возврат на 1000 (500), а последующие циклы ровно 1000 (500) туда 1000 (500) обратно? это удалось победить задав в войд сетап сразу (-500). Но понимания процесса нет
     
  6. РоманИ

    РоманИ Нерд

    нет проблема не побеждена :mad:. причем косячит только ось Y крутит в одну сторону, а потом как с цепи срывается и резкий откат

    не знаю на что думать программная или аппаратная часть косячит. ось Х все окей . Может китайский джойстик?
     
  7. Tomasina

    Tomasina Сушитель лампочек Модератор

    Количество шагов на оборот (в сетапе) соответствует реальным параметрам двигателя? У принтерных там может быть и не 200, а 76 или 120, они всякие бывают.
    Есть возможность на ось Y поставить другой двигатель для проверки?
    Еще для отслеживания можно выводить на ЖК или в терминал инфу о координатах ДО движения и ПОСЛЕ (чтобы сверить с фактически пройденной). Но выводить именно до начала и после окончания, а не в процессе движения.