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

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
3,103
916
Но вот 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
3,103
916
@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

DAER

✩✩✩✩✩✩✩
17 Дек 2021
21
0
А чтобы проверить условие, какой метод нам нужно запустить, и что в этом методе происходит?)
Если метод stepper1.tick()
то какая строка его ЗАПУСТКАЕТ?

Вы знаете какое условие должно быть, чтобы каретка отъехала назад, отсюда вопрос, почему у вас F_KONC_A == 1 при вкл?
Это какие-то странности с питанием.
У меня Ардуино запитано +5В иплата драйвера + 12В от одного блока питания. Выключатель отсекает оба питания.
НО Ардуино продолжает питаться через USB.
И если отключить USB то выключение-включение выключателем к глюку не приводит. Всё работает правильно.
А если USB остаётся подключен - то вышеописанный глюк. Надо померять мультиметром напряжение на 2м пине.
 

Lumenjer

★★★✩✩✩✩
10 Дек 2020
220
112
Если метод stepper1.tick()
то какая строка его ЗАПУСТКАЕТ?
Возможно вы не поверите, но эта строка и запускает)))
Да, if проверяет условие, но чтобы получить значение, которое нужно проверить, сначала запускается метод, там происходят все операции и уже он возвращает значение, которое и будет проверять if
Иными словами этот кусок кода
C++:
if (!stepper1.tick()) {   // проверяем условие
    // НО НЕ ДЕЛАЕМ ВООБЩЕ НИЧЕГО
}
И этот
C++:
stepper1.tick();
Грубо говоря по функционалу делает одно и тоже
 
  • Лойс +1
Реакции: DAER

DAER

✩✩✩✩✩✩✩
17 Дек 2021
21
0
C++:
void loop() {
    static bool dir = true;
//IF-1

    if (!stepper1.tick()) {  //это обычное движение туда-сюда
        stepper1.setTarget(dir ? worksteps : worksteps*-1, RELATIVE);
        dir = !dir;
    }

//IF-2
    if (F_KONC_A ==1){ //если флаг поднят
        stepper1.setTarget(-8000, RELATIVE);
        F_KONC_A = 0;
    }
}
Это работает. Можно вставить и забыть, но очень хочу разобраться.
Непонятно вот что...
Если сработал концевик - запускается IF-2
устанавливается цель -8000 и опускается флаг.
Далее работает IF-1
Но ведь в IF-1 не -8000, а worksteps : worksteps*-1
Что же заставляет мотор КРУТИТЬСЯ до -8000 ?
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,281
1,306
Москва
У вас есть 3 д принтер ? При старте печати он нащупывает концевики по осям. Что бы взять точку отсчета. у Вас так же должно быть. Запустили - в setup двинулись к концевику пока на него не нажали. Далее может быть смещение от концевика куда то. скажем в точку начала работы.
А потом уже в дергаться от этой точки куда надо. И еще полезно при движении проверять нажатие на концевик, а то вдруг из за пропусков шагов или руками кто то сдвинул мотор.

И еще меня почему то коробит worksteps*-1. Я бы написал - worksteps
 
  • Лойс +1
Реакции: DAER

Lumenjer

★★★✩✩✩✩
10 Дек 2020
220
112
Далее работает IF-1
Далее не работает ничего, т.к. условия ни того, ни другого не подходят.
Первое условие сработает тогда, когда движок придёт к цели -8000 и остановится. Если движок остановился, то tick() возвращает 0, а !0 == 1
 
  • Лойс +1
Реакции: DAER

DAER

✩✩✩✩✩✩✩
17 Дек 2021
21
0
Далее не работает ничего, т.к. условия ни того, ни другого не подходят.
Первое условие сработает тогда, когда движок придёт к цели -8000 и остановится. Если движок остановился, то tick() возвращает 0, а !0 == 1

Но ведь в этом коде IF2

C++:
    if (F_KONC_A ==1){ //если флаг поднят
        stepper1.setTarget(-8000, RELATIVE);
        F_KONC_A = 0;
    }
нет метода tick()

У вас есть 3 д принтер ? При старте печати он нащупывает концевики по осям. Что бы взять точку отсчета. у Вас так же должно быть. Запустили - в setup двинулись к концевику пока на него не нажали. Далее может быть смещение от концевика куда то. скажем в точку начала работы.
А потом уже в дергаться от этой точки куда надо. И еще полезно при движении проверять нажатие на концевик, а то вдруг из за пропусков шагов или руками кто то сдвинул мотор.

И еще меня почему то коробит worksteps*-1. Я бы написал - worksteps
У меня доска для разработки колен. На неё ставлю ноги и доска их возит туда-сюда.
Начало такое и будет - едем к концевику, нажимаем, и возвращаемся на середину.
Привод ременной.
И т.к. это ноги - всегда нога может попасть между или надавить сильнее, или вообще сорвать мотор и съехать до упора. Это "авария". У меня стоит два упора, а рядом с ними концевики. И при аварии надо тожде отработать в центр.
Я думал сделать линейный энкодер, чтобы не привязывался мотор к шагам. Точность мне не нужна. Но не потяну умом.

И так, спасибо большое, что отвечаете и помогаете!

И ещё предстоит добавить таймер, чтобы 10 минут работало, 10 минут отдыхало. Но сначала закончу с концевиком.
 

DAER

✩✩✩✩✩✩✩
17 Дек 2021
21
0
@Старик Похабыч,

Шаговый двигатель NEMA 17HS4401. Драйвер шагового двигателя TMC2209 . Деление шага 1/64. Управление джамперами через плату расширения.

C++:
void loop() {
    static bool dir = true; //объявили переменнную dir и присвоили ей TRUE
    if (!stepper1.tick()) {  //если мотор остановлен...
        stepper1.setTarget(dir ? worksteps : worksteps*-1, RELATIVE);//...а dir сейчас TRUE, устанавливаем  координату "worksteps" ОТНОСИТЕЛЬНУЮ
        dir = !dir; //инвертируем dir в FALSE и переходим к шагу...?
    }
а к какому шагу мы переходим?
Если к 2, то что, опять присваиваем dir - TRUE?
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,281
1,306
Москва
Не уверен что нужно такое дробление. И я бы брал мотор мощнее, 23-ий немо и еще драйвер после сменить на какой то промышленный. Ну типа https://compacttool.ru/drajver-shagovogo-dvigatelya-dm556 (для примера исключительно).

А тесты уже были сделаны с нагрузкой ?
 
  • Лойс +1
Реакции: DAER

DAER

✩✩✩✩✩✩✩
17 Дек 2021
21
0
@Старик Похабыч,
Одно из условий - тишина.
Когда жужжит целый день - крыша едет.
Тесты делал. Всё собрано уже. Ремень 6мм шкив 16 зубьев. Вес двух ног около 15 кг. Усилие на сдвиг требуется меньше 1 кг.
Так вот, если встать очень аккуратно, то доска таскает меня, когда я на ней стою. А это 80 кг. :)
Но ели дёргнуть резко, то гораздо меньше требуется усилие, чтобы сорвать мотор.

Я буду пробовать разное дробление.
Сделал так, чтобы было удобно менять.

C++:
//****НАСТРАИВАЕМ РАБОТУ
int dist = 5; //рабочий ход мм
int cycles = 20; //количество циклов в минуту


long stp = 64; //деление шага
int shkiv = 32; //мм за один оборот мотора
long roundstps = stp*200; //чилсо шагов на оборот в полном шаге
long worksteps= (dist*roundstps)/shkiv; //шагов в рабочем ходе в одну сторону
long spd; //скорость движение шаг/с
long maxspd =(dist*2*cycles*roundstps)/60/shkiv; //мкс скорость движение шаг/с
long accel =maxspd*2; //ускорение движение шаг/с*с
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,281
1,306
Москва
Доска по каким направляющим двигается ? Рельсы ?
Если не сложно и не секретно сделайте фото общего вида, оч. любопытно посмотреть.
 
  • Лойс +1
Реакции: DAER

DAER

✩✩✩✩✩✩✩
17 Дек 2021
21
0
Направляющие мебельные, пришлось переделать (чтобы шариков было на всю длину). Нужна минимальная высота от пола.
изображение_viber_2021-12-18_16-54-31-504.jpg
 

DAER

✩✩✩✩✩✩✩
17 Дек 2021
21
0
В общем пока так:

C++:
void loop() {

if (!stepper1.tick() && F_START==0){ //сделал флаг F_START и установил его в ноль. Проверка флага.
   stepper1.setTarget(centersteps*2, RELATIVE); //если флаг ноль - едем в сторону концевика на какое-то ужасно большое расстояние (ЧТО МНЕ НЕ НРАВИТСЯ, потому, что тупо!)
      }
static bool dir = true;
    if (!stepper1.tick()) {  //это обычное движение туда-сюда
        stepper1.setTarget(dir ? worksteps : worksteps*-1, RELATIVE);
        dir = !dir;
    }
    if (F_KONC_A ==1){ //Концевик нажат (флаг F_START тоже стал 1)
        stepper1.setTarget(-centersteps, RELATIVE); //отъезжаем назад на вычисленное число шагов до центра. Флаг F_START не тррогаем, так и будет 1 до перезагрузки.
        F_KONC_A = 0;
    }
}
осталось примастырить второй концевик.
 

Lumenjer

★★★✩✩✩✩
10 Дек 2020
220
112
нет метода tick()
И что? Оно есть в условии, которое выше, а оно будет проверяться с каждым проходом loop, значит шаговик будет работать (если у него есть цель)
Когда сработает концевик, то со следующим заходом в loop движок поедет обратно и будет ехать до тех пор, пока не приедет на точку.
if (!stepper1.tick()) - эта часть выполняется всегда, она должна выполняться, чтобы проверить условие

{ //это обычное движение туда-сюда
stepper1.setTarget(dir ? worksteps : worksteps*-1, RELATIVE);
dir = !dir;
}
- а эта, только если сработало условие (!tick() вернул 1)
 
  • Лойс +1
Реакции: DAER

DAER

✩✩✩✩✩✩✩
17 Дек 2021
21
0
И что? Оно есть в условии, которое выше, а оно будет проверяться с каждым проходом loop, значит шаговик будет работать (если у него есть цель)
Когда сработает концевик, то со следующим заходом в loop движок поедет обратно и будет ехать до тех пор, пока не приедет на точку.
if (!stepper1.tick()) - эта часть выполняется всегда, она должна выполняться, чтобы проверить условие

{ //это обычное движение туда-сюда
stepper1.setTarget(dir ? worksteps : worksteps*-1, RELATIVE);
dir = !dir;
}
- а эта, только если сработало условие (!tick() вернул 1)
тут начинает проясняться

а вот тут ещё непонятно...