GyverStepper. Обсуждение библиотеки

Greendumb

✩✩✩✩✩✩✩
22 Апр 2021
2
0
Здравствуйте!
В кодинге не сильно разбираюсь, в основном делаю все на примерах и по наитию, и вот столкнулся с такой проблемой, которую сам не могу решить:
скетч:
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <GyverStepper.h>
GStepper<STEPPER2WIRE> stepper(800, D8, D7, D6);

char auth[] = "...";
char ssid[] = "...";
char pass[] = "...";

void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  stepper.setRunMode(FOLLOW_POS);
  stepper.setMaxSpeed(1000);
  stepper.setAcceleration(1000);
 }

BLYNK_WRITE(V1)
{
  int pinValue = param.asInt();
  stepper.setTarget(pinValue);
}

void loop()
{
  Blynk.run();
}
То есть суть скетча: получить значение с виртуального пина V1 в приложении и передать его в stepper.setTarget() для перемещения на указанное значение.
Такой вариант самый простой и он работает, например, с сервой и другими библиотеками для шаговиков, но с GyverStepper почему-то нет. Видимо он не хочет работать внутри функции BLYNK_WRITE().
Добавлял для проверки "качалку" мотора туда-сюда
C++:
void loop() {
  Blynk.run();
// просто крутим туды-сюды
  if (!stepper.tick()) {
    static bool dir;
    dir = !dir;
    stepper.setTarget(dir ? -400 : 400);
  }
Работает, значит глобального конфликта библиотек нет.

Возможно есть какой-то вариант применить значение переменной pinValue за пределами функции BLYNK_WRITE() и добавить, например, stepper.setTarget(pinValue) в void loop()?

Очень хочу чтобы эта связка заработала, т.к. Blynk очень удобен, а библиотека GyverStepper наверное единственная, с которой удобно работать с TMC2208.

Буду рад любой помощи! Заранее благодарю!
 

fetus

✩✩✩✩✩✩✩
12 Дек 2020
17
0
Задача тикать шаговик в прерывании таймера на esp32 . Нашел библиотеку...светодиод когда один - мигает , шаговик или светик вместе с шаговиком ни в какую. Кто имел дело с этой библиотекой? Может я что то не так делаю?
C++:
#include "ESP32TimerInterrupt.h"
#include <GyverStepper.h>
GStepper<STEPPER2WIRE> stepper(1, 32, 33);

void IRAM_ATTR TimerHandler0(void)
{
  static bool toggle0 = false;

  digitalWrite(22, toggle0);
  toggle0 = !toggle0;
}


/*
void IRAM_ATTR TimerHandler1(void)
{
   stepper.tick();
}
*/

// Instantiate ESP32 timer0 and 1
ESP32Timer ITimer0(3);
//ESP32Timer ITimer1(1);

void setup()
{

  // режим следования к целевй позиции
  stepper.setRunMode(FOLLOW_POS);

  // установка макс. скорости в шагах/сек
  stepper.setMaxSpeed(400);

  // установка ускорения в шагах/сек/сек
  stepper.setAcceleration(500);

//ITimer1.attachInterruptInterval(stepper.getMinPeriod(), TimerHandler1);

  ITimer0.attachInterruptInterval(100000, TimerHandler0);

  pinMode(22, OUTPUT);

}

void loop()
{
  // просто крутим туды-сюды
  if (!stepper.tick()) {  // тут всё равно вызываем для смены направления
    static bool dir;
    dir = !dir;
    stepper.setTarget(dir ? -400 : 400);
  }



  // задержка, чтобы показать работу степпера в прерывании
  delay(100);
}
 

fetus

✩✩✩✩✩✩✩
12 Дек 2020
17
0
Заменил в библиотеке GyverStepper все float на double.....заработало.
 

vovaself

✩✩✩✩✩✩✩
24 Июл 2019
6
0
Как использовать Motor Shield L293D и управление шаговым двигателем через библиотеку GyverStepper ?
Может у кого-нибудь есть пример ?
Спасибо
 

vovaself

✩✩✩✩✩✩✩
24 Июл 2019
6
0

Вложения

AlexGyver

★★★★★★✩
Команда форума
30 Июл 2018
359
569
@vovaself, это шилд на основе сдвиговых регистров, лучше его выбросить и взять обычный нормальный драйвер. Либо возиться в режиме "виртуального драйвера" с ручной упаковкой битов, но это абсолютного того не стоит
 

DAER

✩✩✩✩✩✩✩
17 Дек 2021
21
0
У меня каретка совершает движения туда-сюда относительно некоего центра +/- 2000 шагов (worksteps ).
Хочу сделать, чтобы при нажатии концевика
  • мотор остановился;
  • откатился назад на 8000 шагов;
  • возобновил движения +/- 2000 шагов.

Вместо этого получаю
  • мотор останавливается;
  • откатывается на 8000 шагов назад;
  • потом ВОЗВРАЩАЕТСЯ на 8000 шагов вперёд;
  • потом продолжает движение +/- 2000 шагов

Помогите понять, почему он возвращается?
И как сделать, чтобы не возвращался?



C++:
...
volatile boolean F_KONC_A = 0; // ФЛАГ 
void Initial_position() {   //ФУНКЦИЯ ОБРАБОТКИ ПРЕРЫВАНИЯ
    F_KONC_A = 1;
      }
//********************************************************************************
...
void setup() {
attachInterrupt(0, Initial_position, RISING); //ОБЪЯВЛЕНИЕ ПРЕРЫВАНИЯ


//********************************************************************************
void loop() {

 if (!stepper1.tick() && F_KONC_A ==0) {  //это обычное движение туда-сюда
    static bool dir;
    dir = !dir;
    stepper1.setTarget(dir ? !worksteps : worksteps);
  }
if (!stepper1.tick() && F_KONC_A ==1){ //если флаг поднят
    stepper1.reset();
    stepper1.setTarget(-8000);
    F_KONC_A = 0;
}
 
}
 

bort707

★★★★★★✩
21 Сен 2020
2,926
876
Помогите понять, почему он возвращается?
потому что позиция задается в шагах относительно НАЧАЛЬНОГО старта, а не от предыдущего шага.
Вот вы задали мотору следовать к позиции -8000, а потом предлагаете ему качаться между 0 и 2000. Как он должен попасть к позиции 0, если он сейчас на -8к? - конечно вернутся назад на 8 тыс шагов, не иначе

Кстати, уверены ли вы, что правильно понимаете, что у вас происходит в строке 18?
 

Lumenjer

★★★✩✩✩✩
10 Дек 2020
220
112
@DAER, По прибытию на точку возврата (после срабатывания концевика) вам нужно еще раз сбросить текущую позицию на 0, а тогда уже двигаться вперед (но не назад, ясное дело), в общем вам нужно доработать логику после возврата на -8000

C++:
void loop() {

 if (!stepper1.tick() && F_KONC_A ==0) {  //это обычное движение туда-сюда
    static bool dir;
    if (F_KONC_A){ // проверяем, вернулись ли мы после срабатывания концевика, если да
        F_KONC_A = 0; // сбрасываем флаг
        dir = true; // выбираем конкретное направление
    }
    else    // если не было концевика, то тут уже туда-сюда обратно
        dir = !dir;
    stepper1.setTarget(dir ? !worksteps : worksteps);
  }
if (!stepper1.tick() && F_KONC_A ==1){ //если флаг поднят
    stepper1.reset();
    stepper1.setTarget(-8000);
    // F_KONC_A = 0;  - эта строка нам не нужна
}
 
}
 

DAER

✩✩✩✩✩✩✩
17 Дек 2021
21
0
@bort707,

- я пробовал обнулять позицию reset(), но это не помогало. Возможно стоит попробовать нечто "если позиция не равна -8000..."

Кстати, уверены ли вы, что правильно понимаете, что у вас происходит в строке 18?
Это очень правильный вопрос. Я понимаю, что создаётся статическая переменная dir? которая меняет свой знак, соответственно меняются и координаты цели.
НО
я не понимаю, как работает цикл. Откуда мотор решил вернуться сначала в 0? Это скрыто в недрах библиотеки? И почему в Loop конструкции IF работают как циклы...

@Lumenjer,

- Вставил ваш код. При одном нажатии на концевик мотор отъезжает на 8000 шагов, делает паузу ...и отъезжает ещё на 8000 шакгов и так далее. Не происходит возврат к stepper1.setTarget(dir ? !worksteps : worksteps);

И вот это непонятно
if (F_KONC_A){ // проверяем, вернулись ли мы после срабатывания концевика, если да

Что значит "вернулись" ?
 

Lumenjer

★★★✩✩✩✩
10 Дек 2020
220
112
@DAER, внимательно посмотрите на 3ю строку и поймёте, почему так происходит)
А ещё, чтобы все работало нормально, то вам придётся блоки местами поменять
 

bort707

★★★★★★✩
21 Сен 2020
2,926
876
Это очень правильный вопрос. Я понимаю, что создаётся статическая переменная dir? которая меняет свой знак, соответственно меняются и координаты цели.
неправильно понимаете.
Почитайте описание оператора "!" - он вовсе не "меняет знак". И если в строке
C++:
dir = !dir;
у вас случайно получилось то. что надо, то в строке
C++:
(dir ? !worksteps : worksteps)
вы используете этот оператор неправильно, результат будет вовсе не от -2000 до 2000, как вы, вероятно, ожидали.

я не понимаю, как работает цикл. Откуда мотор решил вернуться сначала в 0? Это скрыто в недрах библиотеки?
ну какой библиотеки?! - это элементарная логика.Я ж вам написал - координаты, которые вы задаете - АБСОЛЮТНЫЕ! Если вы после смещения мотора на точку -8к просите его дергаться от 0 до 2000 - то СНАЧАЛА МОТОР ДОЛЖЕН ВЕРНУТСЯ к нулю! Что тут может быть непонятно?
 
Изменено:
  • Лойс +1
Реакции: kostyamat, DAER и Lumenjer

DAER

✩✩✩✩✩✩✩
17 Дек 2021
21
0
неправильно понимаете.
Почитайте описание оператора "!" - он вовсе не "меняет знак". И если в строке
C++:
dir = !dir;
у вас случайно получилось то. что надо, то в строке
Это не мой код, это пример из библиотеки. Я - балбес.Правильнее сказать меняет значение ИСТИНА на ЛОЖЬ?

C++:
(dir ? !worksteps : worksteps)
вы используете этот оператор неправильно, результат будет вовсе не от -2000 до 2000, как вы, вероятно, ожидали.
Это тоже из примера. Там
C++:
(dir ? -400 : 400)
Я заменил число переменной worksteps. Она у меня 2000. Теперь я понимаю, что ! тут не годится, но каретка почему-то ездит туда-сюда правильно....
Очень сложно "читать" код... Толком не понимаю, как прочитать
C++:
(dir ? -400 : 400)
. Я знаю, что перед ? стоит условие. Но вот dir=False, как условие, мне понятно. А просто dir... Вероятно то же, что и dir=TRUE?
Нет базовых знаний, а книги написаны теми, кто уже забыл, как новички усваивают информацию.
Как же правильно поменять знак у переменной?
C++:
(dir ? worksteps*-1 : worksteps)
C++:
(dir ? -worksteps : worksteps)
ну какой библиотеки?! - это элементарная логика.Я ж вам написал - координаты, которые вы задаете - АБСОЛЮТНЫЕ! Если вы после смещения мотора на точку -8к просите его дергаться от 0 до 2000 - то СНАЧАЛА МОТОР ДОЛЖЕН ВЕРНУТСЯ к нулю! Что тут может быть непонятно?
:) Извините за тупость. Поищу объяснение где-нибудь.
 

Lumenjer

★★★✩✩✩✩
10 Дек 2020
220
112
@DAER, Представьте график координат, вы находитесь на 0, даете команду пойти на позицию 2000, после того, как пришли на 2000, даете команду прийти на -2000 (относительно 0 вашей точки координат, т.к. вы его не сбрасывали), отсюда вопрос, сколько шагов назад вы сделаете, чтобы прийти к -2000?)
 
  • Лойс +1
Реакции: DAER

bort707

★★★★★★✩
21 Сен 2020
2,926
876
Но вот dir=False, как условие, мне понятно. А просто dir... Вероятно то же, что и dir=TRUE?
да, только не "dir=TRUE", а "dir==TRUE" - это отличие принципиально, "=" - это присваивание, а "==" сравнение

Как же правильно поменять знак у переменной?
правильно - так:
C++:
(dir ? worksteps*-1 : worksteps)
Извините за тупость. Поищу объяснение где-нибудь.
какое обьяснение.... .... неужели так и не поняли еще?

Чтобы было понятнее, сейчас у вас программа написана примерно так -
1. сначала двигаемся +/- 200км вокруг Москвы
2. Потом сдвигаемся на 8000 км к Хабаровску
3. Снова двигаемся на +/- 200км вокруг Москвы

на этом примере вроде очевидно, что для того чтобы перейти от пункта 2 к пункту 3, мотор должен сначала выполнить перемещение на - 8000 км от Хабаровска до Москвы
Если же вам нужно, чтобы в п.3 мотор ездил "+/- 200км вокруг Хабаровска", то надо либо именно так в этом пункте и написать, либо сменить координаты на относительные и указать "+/- 200км вокруг текущей позиции"
 
Изменено:
  • Лойс +1
Реакции: DAER

DAER

✩✩✩✩✩✩✩
17 Дек 2021
21
0
Избыточное цитирование. Отредактируй или сообщение будет удалено
какое обьяснение.... .... неужели так и не поняли еще?
Вы только не обижайтесь, мозг новичка работает совсем не так, как ваш, ему нужны ответы на самые дебильные вопросы :)

@DAER, внимательно посмотрите на 3ю строку и поймёте, почему так происходит)
А ещё, чтобы все работало нормально, то вам придётся блоки местами поменять
C++:
 if (!stepper1.tick() && F_KONC_A ==0)
Её надо понимать: Если мотор НЕ двигается и флаг опущен ?

вот в этом куске

C++:
 if (!stepper1.tick() && F_KONC_A ==0) {
    static bool dir;
    dir = !dir;
    stepper1.setTarget(dir ? !worksteps : worksteps);
  }
мне непонятно, какая команда включает мотор?

да, только не "dir=TRUE", а "dir==TRUE" - это отличие принципиально, "=" - это присваивание, а "==" сравнение


правильно - так:
C++:
(dir ? worksteps*-1 : worksteps)
какое обьяснение.... .... неужели так и не поняли еще?

Чтобы было понятнее, сейчас у вас программа написана примерно так -
1. сначала двигаемся +/- 200км вокруг Москвы
2. Потом сдвигаемся на 8000 км к Хабаровску
3. Снова двигаемся на +/- 200км вокруг Москвы

на этом примере вроде очевидно, что для того чтобы перейти от пункта 2 к пункту 3, мотор должен сначала выполнить перемещение на - 8000 км от Хабаровска до Москвы
Если же вам нужно, чтобы в п.3 мотор ездил "+/- 200км вокруг Хабаровска", то надо либо именно так в этом пункте и написать, либо сменить координаты на относительные и указать "+/- 200км вокруг текущей позиции"
Это СУПЕР обьяснение!
Вот в чём дело:

// установка целевой позиции в шагах и градусах (для режима FOLLOW_POS)
// type - ABSOLUTE или RELATIVE, по умолчанию стоит ABSOLUTE
void setTarget(long pos);
void setTarget(long pos, GS_posType type);

выходит, надо так?
C++:
(dir ? worksteps*-1, RELATIVE : worksteps, RELATIVE)
нет... при таком коде каретка двигается всё время в одну сторону...
 

DAER

✩✩✩✩✩✩✩
17 Дек 2021
21
0
нет, это синтаксически неверно
Правильно:
(dir ? worksteps*-1 : worksteps, RELATIVE)
Так двигается туда-сюда.
Однако и так (без изменения знака)
C++:
stepper1.setTarget(dir ? worksteps, RELATIVE : worksteps);
тоже двигатеся туда-сюда. Срочно нуже пример с Хабаровском :)
 

Lumenjer

★★★✩✩✩✩
10 Дек 2020
220
112
Её надо понимать: Если мотор НЕ двигается и флаг опущен ?
Да, а в примере я не опускал флаг, т.к. он нам нужен для другого теперь

C++:
void loop() {
    static bool dir = true;
    static bool back = false;
    if (!stepper1.tick()) {  //это обычное движение туда-сюда
        if (back){
            stepper1.reset();
            back = false;
        }
        stepper1.setTarget(dir ? worksteps : !worksteps);
        dir = !dir;
    }
    if (F_KONC_A ==1){ //если флаг поднят
        stepper1.reset();
        stepper1.setTarget(-8000);
        back = true;
        dir = true;
        F_KONC_A = 0;
    }

}
мне непонятно, какая команда включает мотор?
Вот этот метод заставляет мотор двигаться stepper1.tick(), внутри происходят расчеты, и если мотор еще должен двигаться, ответ от этого метода будет true, а когда он приехал на точку, ответ будет false
 
Изменено:

bort707

★★★★★★✩
21 Сен 2020
2,926
876
@DAER, внимательно смотрите на код - вы опять порядок параметров перепутали. Второй вариант просто ошибочный, поэтому там может быть что угодно
 
  • Лойс +1
Реакции: DAER

DAER

✩✩✩✩✩✩✩
17 Дек 2021
21
0
Вот этот метод заставляет мотор двигаться stepper1.tick(), внутри происходят расчеты, и если мотор еще должен двигаться, ответ от этого метода будет true, а когда он приехал на точку, ответ будет false
Но ведь когда
C++:
 if (!stepper1.tick())
мы ведь всего лишь проверяем условие..., я думал, чтобы запустить мотор нужно подать команду stepper1.tick(),
Ведь если мы напишем
C++:
void loop() {
    stepper1.setTarget(8000);
}
мотор же не поедет...

Убрал восклицательные знаки

C++:
void loop() {
    static bool dir = true;
    static bool back = false;
    if (!stepper1.tick()) {  //это обычное движение туда-сюда
        if (back){
            stepper1.reset();
            back = false;
        }
        stepper1.setTarget(dir ? worksteps, RELATIVE : worksteps);
        dir = !dir;
    }
    if (F_KONC_A ==1){ //если флаг поднят
        stepper1.reset();
        stepper1.setTarget(-8000, RELATIVE);
        back = true;
        dir = true;
        F_KONC_A = 0;
    }
 
}
Этот код работает. Немного странно. При перезагруке контроллера двигатеся туда-сюда, при нажатии концевика - отъезжает назад на 8000 шагов и двигатеся туда сюда. Всё правильно. НО при выключении и включении питания каретка сначала отъезжает назад на 8000 шагов, а потом начинает двигаться туда-сюда. Может связано как-то с питанием концевика...? Попробую подтянуть пин 2 к земле программно.
 

Lumenjer

★★★✩✩✩✩
10 Дек 2020
220
112
мы ведь всего лишь проверяем условие...
А чтобы проверить условие, какой метод нам нужно запустить, и что в этом методе происходит?)

НО при выключении и включении питания каретка сначала отъезжает назад на 8000 шагов
Вы знаете какое условие должно быть, чтобы каретка отъехала назад, отсюда вопрос, почему у вас F_KONC_A == 1 при вкл?

*** Если использовать RELATIVE, то можно упростить

C++:
void loop() {
    static bool dir = true;
    if (!stepper1.tick()) {  //это обычное движение туда-сюда
        stepper1.setTarget(dir ? worksteps : worksteps*-1, RELATIVE);
        dir = !dir;
    }
    if (F_KONC_A ==1){ //если флаг поднят
        stepper1.setTarget(-8000, RELATIVE);
        F_KONC_A = 0;
    }
}
 
Изменено:
  • Лойс +1
Реакции: DAER