Gyver Stepper, вопросы по библиотеке

Forgetweb

★✩✩✩✩✩✩
8 Май 2022
61
20
@KovAlex, Подскажите по двигателю - сколько там шагов на оборот? Описание на Али об этом умолчало. Редукцию написали, а шаги нет. И еще - какой у него крутящий момент? И что за 4 провода? На картинке подписаны иероглифами, я с китайским не дружу.
 

vortigont

★★★★★✩✩
24 Апр 2020
915
491
Saint-Petersburg, Russia
Увы.. Одноядрёная Arduino Nano...
не нужен 2х ядерный процессор, нужно учиться разбивать задачи на мелкие неблокирующие кусочки.
Вам даже таймер не нужен с прерываниями, ибо вот так делать нельзя!

C++:
ISR(TIMER1_COMPA_vect) {
  if (stat_hal != digitalRead(AZ_HAL_PIN)) flag_hal = true; // проверка на то, что двигатель действительно крутится (датчик холла)
  check = a_stepper.getCurrent() - start_pos;

  if (abs(check)>41 && flag_hal == false) {  // если мотор не крутится, делаем стоп и записываем текущую позицию в EEPROM
  }
 
  if (a_stepper.ready() || flag_break == true)
  {
    a_stepper.disable();
    digitalWrite(LED_PIN , LOW);
    WriteBackup();  // запись текущей позиции в EEPROM
  }
}
все эти чтения пинов и записи в еепром в обработчике прерываний делать НЕЛЬЗЯ! Дабы потом не задаваться вопросом "а что будет если прилетит новое прерывание пока я все еще туплю и пытаюсь что-то там доделать в предыдущем".

Вот пример как можно управлять пятью моторами, читать датчики, обмениваться по радио и пр в рамках одного планировщика, работающего в основной петле, без использования прерываний по таймеру - проект, код, планировщик
 

KovAlex

✩✩✩✩✩✩✩
9 Фев 2022
25
0
Вот пример как можно управлять пятью моторами
Проект интересный, но он имеет одно существенное отличие - в нём используются серво-двигатели. В моём - шаговые...
Почти на 100% уверен, что если не использовать таймер, а крутить всё (моторы, дисплей, клавиатуру, энкодер и опрос датчиков) в одном loop,
то моторы будут банально дёргаться.
Т.е. ни о каком плавном разгоне/останове, да и собственно ровном движении речи быть не может.

Поправьте меня, если ошибаюсь.

P.S. Да, я согласен, что нагружать прерывания всяческими "допами" - плохое решение, но по-другому пока не получается..
Кстати, сейчас как раз обкатываю этот вариант (с "монструозным" обработчиком прерывания). Пока серьёзных замечаний нет..
Но всё же буду потихоньку пытаться выбрасывать оттуда всё, что не связано с работой таймера.
К сожалению, я довольно слабый программист, поэтому приходится тратить много времени на правку несуразностей.
Да и правильное решение найти мне не всегда по силам.. :(
 
Изменено:

vortigont

★★★★★✩✩
24 Апр 2020
915
491
Saint-Petersburg, Russia
нагружать прерывания "допами" - плохое решение, но по-другому пока не получается. Кстати, сейчас как раз обкатываю этот вариант (с "монструозным" обработчиком прерывания).
Ну если устраивает заведомо ущербный подход - дерзайте, что можно тут сказать. Таймер и прерывания это не "серебрянная пуля".
С какой частотой у вас идут импульсы на моторы на максимальной скорости и на какую частоту настроен таймер? Судя по описанию на али моторчики тянут около 3 кГц, что не так уж и много. Но с плавным стартом я не знаю как вы выкручиваетесь. Вы так "допишетесь" до того что у вас обработчик прерываний от таймера иногда будет не успевать за тиками этого таймера и вы будете либо пропускать "шаги" либо у вас будет лагать остальная периферия. Хотя с таким понижающим редуктором 1:144 это врядли будет заметно, что через луп делать, что через пропущенные прерывания. Хороший код будет и с лупом нормально работать, плохому никакие прерывания не помогут. А потом из этого возникают безумные идеи про "одно ядро процессора на каждый мотор".
Шаги мотора вы всё равно не считаете, точность вам не нужна у вас редуктор - используйте ШИМ и не придется писать ненужности в обработчике прерываний от таймера. Управляйте только положеним и оборотами от сенсоров, для этого вполне будет достаточно ленивого опроса пинов.
Для еще более нормального управления несколькими шаговыми моторами с плавными разгонами и прочим нужно взять нормальный контроллер, у которого есть выделенный ШИМ движёк, который умеет сам менять скважность/частоту.
 

KovAlex

✩✩✩✩✩✩✩
9 Фев 2022
25
0
С какой частотой у вас идут импульсы на моторы на максимальной скорости и на какую частоту настроен таймер?
Если честно, понятия не имею. Этим занимается Gyver Stepper.
Но с плавным стартом я не знаю как вы выкручиваетесь.
Аналогично
Вы так "допишетесь" до того что у вас обработчик прерываний от таймера
Сейчас там собственно ничего и не осталось
Код:
ISR(TIMER1_COMPA_vect) {
  if (a_stepper.tickManual()) 
  { 
    setPeriod(a_stepper.getPeriod());
  }
  else if (e_stepper.tickManual()) 
  {
    setPeriod(e_stepper.getPeriod());
  }
  else 
  {
    stopTimer();
  } 
}
Одновременно два старта не передаю. Если один из движков занят, второй ожидает в очереди. Вообщем - кто первый, того и тапки. :)
Шаги мотора вы всё равно не считаете,
Их считает библиотека.
А я их забираю в виде градусов и сохраняю в EEPROM по каждому достижению нужной позиции.
точность вам не нужна
Нууу.. Смотря что подразумевать под этим.
Конечно, доли градуса и даже 1-2 градуса на выходном валу, в моём случае, погоды не сделают. Но 5 градусов всё же надо.
Управляйте только положеним и оборотами от сенсоров
Нет сенсоров! Только датчик Холла в моторчике. По нему позицию не особо вычислишь..
Его я использую в качестве "контроллёра" движения двигателя. Если импульсов нет, зачит что-то пошло не так.
Останавливаю движение, возвращаю в stepper позицию, на которой импульсы пропали и пишу в EEPROM.
Как-то так вкратце.
 

KovAlex

✩✩✩✩✩✩✩
9 Фев 2022
25
0
Возник ещё такой вопрос - возможно ли назначить одни и те же пины (STEP, DIR и ENABLE) для управления двумя драйверами (А4988) моторов?
Т.е. вот так -
Код:
GStepper2<STEPPER2WIRE> a_stepper(5760, 11, 10, 12);
GStepper2<STEPPER2WIRE> e_stepper(5760, 11, 10, 12);
Конфликта в GStepper2 не получится?
А собственно драйверы подключить через мультиплексор. Например, CD4053. (Schematic_Step-motor-rotator1)
Естественно, моторы одновременно работать НЕ будут.

Или ещё вариант - пины step и dir на драйверах запараллелить, а управлять только сигналом enable? (Schematic_Step-motor-rotator_2)
Вот так -
Код:
GStepper2<STEPPER2WIRE> a_stepper(5760, 5, 8, 9);
GStepper2<STEPPER2WIRE> e_stepper(5760, 5, 8, 10);
Schematic_Step-motor-rotator1.pngSchematic_Step-motor-rotator_2.png

Код:
GStepper2<STEPPER2WIRE> a_stepper(5760, 5, 8, 9);
GStepper2<STEPPER2WIRE> e_stepper(5760, 5, 8, 10);
Предыдущая "копия" GStepper держит "свой" DIR.
И получается так, что если предыдущее направление было "по часовой", а текущее "против", текущий поворот выполняется в ложном направлении..
Никак не могу одолеть.. :(
Пробовал играться stepper.dir, но похоже, он только для чтения.
Пробовал читать пин DIR и если там "0", записывать "1". Предположил, что активный драйвер(gstepper) не может "преодолеть 0", но увы - тоже не прокатило..
Пробовал играться stepper.reverse(false/true), но так и не понял, что эта функция делает. Результат тоже нулевой..

Реально ли как-то преодолеть этот момент? Или без правки gstepper не получится?
 
Изменено:

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

★★★★★★★
14 Авг 2019
4,197
1,282
Москва
После того как переключили EN попробуйте уже с нужной копией GStepper 2 раза дернуть DIR , это должно вернуть последнее нужное направление.
 

KovAlex

✩✩✩✩✩✩✩
9 Фев 2022
25
0
попробуйте уже с нужной копией GStepper 2 раза дернуть DIR
Не понял.. Как дёрнуть DIR? Так что ли?
void stepper_turn(int st) {
if (st == 0 && a_stepper.getStatus() == 0 && TruAzim != ComAzim)
{
a_stepper.enable();
a_stepper.dir = a_stepper.dir;
a_stepper.dir = a_stepper.dir;

a_flag_hal = false;
a_stepper.setTargetDeg(ComAzim*-1,ABSOLUTE);
az_cur_pos = a_stepper.getCurrent();
az_start_pos = az_cur_pos;
az_stat_hal = digitalRead(AZ_HAL_PIN);
setPeriod(a_stepper.getPeriod());
startTimer();
}
 

KovAlex

✩✩✩✩✩✩✩
9 Фев 2022
25
0
a_stepper.dir =~a_stepper.dir;
Не прокатило.. :( Всё также "сшибается", если на одном из моторов меняется "направление" (уменьшить/увеличить).
Видимо, в библиотеке dir "приколочен" к пину и в моём случае он получается "общий" для всех "клонов".
 
Изменено:

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

★★★★★★★
14 Авг 2019
4,197
1,282
Москва
Библиотека может считывать состояние пина перед изменением, но это было странно. Тогда можно попробовать сохранить состояние направления для каждого мотора и потом его восстановить.
 

KovAlex

✩✩✩✩✩✩✩
9 Фев 2022
25
0
сохранить состояние направления для каждого мотора и потом его восстановить.
Пробовал - не прокатило.. Почему так, не понял. Может библиотека, действительно, читает пин перед стартом?
Или DIR в ней ReadOnly и операция его изменения игнорируется.

Похоже, придётся забить на эту "параллельную затею", не судьба сэкономить пины..
Попробую ещё оставить STEP впараллель на драйверах, может хоть с этим прокатит. Пинов как раз хватит для проекта. :)
Не знаю только, как "понравится" stepper-у пин D13 ардуины - светодиод к нему подключён.
В принципе, мешать он не должен, но.. На крайний случай, выпаяю его.
 

poty

★★★★★★✩
19 Фев 2020
2,994
895
@KovAlex, по мне - так проблема сильно переусложнена. Зачем Вам две конкурирующие "сущности" GStepper2? Управляйте одной, а моторы переключайте с помощью Enable.
 

KovAlex

✩✩✩✩✩✩✩
9 Фев 2022
25
0
Управляйте одной, а моторы переключайте с помощью Enable.
Гм.. А этот вариант я почему-то и не рассматривал... Попробую..
Я правильно вас понял, что "электрическая часть" (параллельные STEP и DIR и два отдельных EN) остаётся без изменений, только stepper будет один?
И в его конфигурации будет отсутствовать параметр EN, которым я буду манипулировать из своего кода, поднимая/опуская соотв. пины.
Код:
GStepper2<STEPPER2WIRE> stepper(шаговНаОборот, step, dir);
Интересно, а команды stepper.enable/disable оставлять, или они уже не потребуются?
 

poty

★★★★★★✩
19 Фев 2020
2,994
895
@KovAlex, да, с конфигурацией именно так (электрически всё параллельно, кроме enable). Так как шинами enable Вы будете управлять сами, вне библиотеки, то эти методы Вам в самой библиотеке не нужны.
 

KovAlex

✩✩✩✩✩✩✩
9 Фев 2022
25
0
Так как шинами enable Вы будете управлять сами, вне библиотеки, то эти методы Вам в самой библиотеке не нужны.
А как же тогда насчёт этого -
void disable(); // отключить питание и EN
void enable(); // включить питание и EN
Что здесь вообще означает, "питание"? На драйвер (А4988) всего три сигнала приходят: STEP, DIR и ENABLE.
Или это имеет смысл для других драйверов?
 

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

★★★★★★★
14 Авг 2019
4,197
1,282
Москва
EN управляет подачей питания на обмотки, если мотор не крутиться, но EN включен, то мотор находиться в режиме удержания положения - вал будет крутиться с трудом, при этом мотор будет сильно греться, Если отключен, то вал легко поворачивается .
Если использовать драйвера типа TMC2208, то таки драйверов есть автоматическое снижение тока при удержании положения, мотор не греется так сильно как с 4988. И теоретически EN можно не трогать.
 

KovAlex

✩✩✩✩✩✩✩
9 Фев 2022
25
0
EN управляет подачей питания на обмотки, ...
Это мне известно.
А вот это -
И теоретически EN можно не трогать.
я вообще не понял.. Как я смогу (в обсуждаемом варианте) НЕ трогать EN???
Да и вообще - вопрос был про
отключить/включить питание и EN
В комментарии присутствует "И", что подразумевает "и то и это". Т.е., как я понимаю, это "разные люди".
И если с "EN" всё понятно, то вот с "питанием" - нет.
 

poty

★★★★★★✩
19 Фев 2020
2,994
895
@KovAlex, Вам проще попробовать, чем пытаться интерпретировать описание.
 

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

★★★★★★★
14 Авг 2019
4,197
1,282
Москва
Не трогать EN можно только для одного мотора на набор пинов.

EN включено и питание мотора включено
EN выключено и питание мотора выключено
Работают только в паре.

При включенном EN на обмотки мотора подается ток. При импульсе на STEP полярность обмоток меняется (если грубо) и мотор делает шаг. Т.е. ток будет на обмотках всегда. Но если не дергать STEP мотор не крутиться, а удерживает положение вала, получается такой тормоз.

Что не понятно я "не понятно"
 

KovAlex

✩✩✩✩✩✩✩
9 Фев 2022
25
0
Что не понятно я "не понятно"
Не понятно, к чему это всё для моего случая.
Ну да ладно..
Вариант с одним GStepper и двумя драйверами/моторами с запараллеленными STEP/DIR и собственным управлением EN, вроде как прокатил.
"Вроде" - потому-что не всё гладко в авто-режиме (когда данные азимут/элевация прилетают с компьютера).
Что собственно и ожидалось.
Пока ищу, где накосячил..

В процессе поиска появился такой вопрос - многократный вызов stepper.ready() и stepper.getStatus(), не сбрасывает, случаем, эти флаги?