Перемещение каретки на станке шаговым двигателем. Прошу консультации.
- Войдите на сайт для отправки комментариев
Добрый день всем!
Ввязался помочь в построении станка. На станине закреплены штанги, по которым перемещается каретка с исполнительными механизмами. Каретка приводится в движение винтом ШВП. Винт крутится шаговым двигателем из Китая формата NEMA23 (HANPOSE 23HS7628), который управляется драйвером STEP/DIR TB6560-v.20B (питается источником 24 В). Всем этим делом предполагается рулить ардуинкой Мега.
Алгоритм по части шаговика:
1) нажимаем кнопку
2) включаются реле питания исполнительных механизмов, запускается мотор (каретка поехала, исполнительные механизмы начинают исполнять исполнительные действия)
3) каретка дошла до концевика -> останавливается мотор, выключаются реле.
4) запускается мотор в обратную сторону до следующего концевика.
Всё. Просто и примитивно. Двигатель имеет угол 1,8 гр. (штатно 200 шагов на оборот). Но вот вся проблема в том, что я не могу его заставить крутиться быстро, ни скорость регулировать, ни разогнать. Пытался играться с библиотекой Accselstepper.h, по ней вообще никаким параметрам регулировки двигатель не поддаётся и крутится ооооочень медленно.
Начал с небольшого: отключил всё, пытаюсь двигать рамой исключительно мотором. Удалось добиться более менее адекватной работы мотора (без пропусков шага, визгов, вибраций, свистов и прочего). Микрошаг 1/8, время задержки между сигналами 70 микросекунд, работа ровная, скорость навскидку что-то около 8-10 оборотов в секунду, что очень мало. Нужно раза в 3 быстрее.
Вот код для тестовых режимов. Самый примитив.
// задаём пины EN, DIR, STP void setup() { // задаём пины EN, DIR, STP digitalWrite(EN, LOW); //при этом уровне подаётся напряжение на обмотки } void loop() { digitalWrite(DIR, HIGH); //направление втуда digitalWrite(STP, HIGH); delayMicroseconds(70); digitalWrite(STP, LOW); delayMicroseconds(70); }
Вот наилучший результат. Прочитал кучу мануалов, уроков, библиотек, но ни по одному примеру не могу адекватно заставить работать мотор. Как повысить обороты? И как прикрутить регулировку скорости (если возможно)? Вроде ответ, где-то на поверхности, но сообразить не могу.... Складывается ощущение, что это максимум, что можно выжать из мотора (чтобы без пропусков и без перегрузок работал). Какой алгоритм управления следует приладить, хочу голый код сделать без библиотек, задача вроде самая простая...
Теперь по библиотекам:
#include <AccelStepper.h> //подключаем библиотеку управления мотором AccelStepper RAMA(1, 7, 6); // pin 7 = step, pin 6 = direction const int SB3 = 8; //кнопка запуска рамы и включения исполнительных мех-в const int SB4 = 9; //концевой выключатель мех-в и включение обратного хода рамы const int SB5 = 10; //концевой выключатель остановки обратного хода рамы int PUSK; //переменная считывания кнопки SB3 int WORK = 0; //переменная состояния работы мех-в рамы (0 - не работает, 1 - работает и не реагирует на управление пока не отработает цикл (запустили машину кнопкой SB3)) int FORWARD = 0; //переменная движения рамы вперёд int BACK = 0; //переменная движения рамы назад const int RELAY1 = A1; //реле 1 мех-ма const int RELAY2 = A2; //реле 2 мех-ма void setup() { Serial.begin(9600); //открываем порт для отладки delay(500); pinMode(SB3, INPUT); //задаём пины кнопок как входы pinMode(SB4, INPUT); pinMode(SB5, INPUT); pinMode(RELAY1, OUTPUT); //задаём пины реле как выходы и переводим их в выключенное состояние digitalWrite(RELAY1, LOW); pinMode(RELAY2, OUTPUT); digitalWrite(RELAY2, LOW); } void loop() { PUSK = digitalRead(SB3); //опрашиваем нажатие кнопки SB3 (включение машины) if (PUSK == 1 && WORK == 0) //если машина не в рабочем цикле и было нажатие кнопки SB3 { WORK = 1; //переводим машину в рабочий цикл PUSK = 1; //фиксируем срабатывание кнопки SB3 delay(250); //ждём четверть секунды } while (PUSK) //пока зафиксировано срабатывание кнопки SB3 { Serial.println(PUSK); digitalWrite(RELAY1, HIGH); //включаем реле питания мех-в digitalWrite(RELAY2, HIGH); RAMA.setMaxSpeed (3000); //устанавливаем максимальную скорость мотора RAMA.setAcceleration(1000); //устанавливаем ускорение RAMA.setSpeed(500); //устанавливаем скорость мотора в прямом направлении FORWARD = digitalRead(SB4); //считываем срабатывание концевика SB4 RAMA.runSpeed(); //запускаем мотор по условиям выше if (FORWARD == 1) //как только зафиксировано срабатывание концевика SB4 { digitalWrite(RELAY1, LOW); //выключаем реле питания мех-в digitalWrite(RELAY2, LOW); delay(1500); //ждём 1,5 секунды break; //останавливаем мотор } } while (WORK) //пока машина находится в рабочем цикле { RAMA.setMaxSpeed (-3000); //устанавливаем параметры движения мотора в обратном направлении (аналогично прямому направлению) RAMA.setAcceleration(13000); RAMA.setSpeed(-1500); BACK = digitalRead(SB5); RAMA.runSpeed(); //запускаем мотор if (BACK == 1) //как только сработал концевик SB5 { WORK = 0; //выводим машину из рабочего цикла delay(1500); //ждём полсекунды и останавливаем мотор break; } } //далее возвращаемся в начало к опрашиванию состояния кнопки пуска SB3 }
Вот по этому алгоритму всё работает как надо, но мотор крутится оооооочень медленно.... Регулировка по примерам из библиотек не работают. Где-то я туплю и не могу подружить всё это дело с железом....
!!!!! И теперь самое главное)) Хотелось бы, чтобы люди, которые имеют опыт построения подобных механизмов и собаку съели на шаговиках во всех видах и вариантах ткнули меня носом, в чём я не прав и как НАДО алгоритм строить. Поправлю сам, но мозг уже за несколько дней беспрерывной возни с этой задачей уже окукливаться начал))) Прошу не оскорблять, на форуме впервые пишу.
Посмотрите внимательно на примеры к аксельстепперу - акселерация, скорости выставляются не каждый раз перед вызовом runSpeed().
Максимально беспроблемная частота в аксельстеппере - 1000имп/сек. В первом примере строка 11 избыточна. Достаточно 5мкс или меньше (зависит от драйвера), а DIR необязательно в лупе выставлять. Газануть сразу на высокой частоте может и не выйти, нужен плавный разгон.
По скоростям: с увеличением фактора микрошага момент будет падать. Поиск золотой середины между плавностью хода и мощой бесконечен и сопровождается заменой драйверов в направлении увеличения их стоимости.
Для понимания возможностей конкретно Вашего движка необходимо найти на него документацию, в которой приличные производители приводят графики зависимости частоты (PPS) и момента (Torque). Обратите внимание, что информация относится к полному шагу. Например: https://www.mitsumi.co.jp/latest/Catalog/pdf/motor_m42sp_5_e.pdf
Pull-in отражает возможность двигателя "дёрнуть с места". В приведённом выше PDF видно, что с >700PPS M42SP-5 стартовать не сможет даже без нагрузки.
Pull-out показывает способность держать момент в уже разогнанном состоянии. При 1100 pulses per second он сорвётся и перестанет крутится.
Где-то в этом промежутке Вам нужно манипулировать частотой, подаваемой на STEP.
Так. Прошу прощения. Писал по памяти, мысли уже в кучу))
1) DIR, конечно же не в "лупе", а в цикле настроек в начале, это я при написании здесь тупанул. Ну не суть, это тестовая прога.
2) По 11 строке согласен, просто её все лепят во всех уроках и тест-моделях по шаговикам, тут не подумал, признаю.
3) 5 мкс - это ничтожно мало... У меня ниже 50 мкс задержки мотор уже визжит, как хрюша, и не запускается. Как это люди умудряются прописывать в скобочках даже до 1 мкс...? Ни в доках по драйверу, ни в доках по мотору инфы такой не нашёл.
Пробовал два драйвера, на втором китайском TB6600 - ещё хуже, там джамперами нельзя настроить сглаживание импульсов, например, (сейчас поставил 50%) и уровень тока удержания. Поведение мотора на команды в принципе аналогично. Значит делаю вывод - проблема в моей "сырой" программе.
4) В коде акселерацию и скорость писал в каждом цикле для того, чтобы иметь возможность изменить скорость обратного хода (сделать её повыше, т.к. исполнительные мехи уже не работают). Предполагалось, что это будет работать...
5) "В аксельстеппере частота 1000 имп/сек" (с). Маловато же... это меньше оборота в секунду получается... А мне же разогнать надо. В примерах у людей так легко и просто всё - выкручивают циферы и у них полетело))) Все прям молятся на аксельстеппер, а я с ней даж запуститься не могу по-человечески.
6) по поводу газануть. Допустим, что газануть может не выйти. В библиотеке об ускорении только команды на прописывание этого самого ускорения числом. Есть какая-то формула его вычисления в зависимости от значения имп/сек?
"Pull-in отражает возможность двигателя "дёрнуть с места". В приведённом выше PDF видно, что с >700PPS M42SP-5 стартовать не сможет даже без нагрузки.
Pull-out показывает способность держать момент в уже разогнанном состоянии. При 1100 pulses per second он сорвётся и перестанет крутится."
Ну вот по сути я это и получил методом экспериментов. По факту в мастерской стоит станок (лазер), там моторы поменьше, крутятся шустро, при тех же габаритах скорость перемещения лазера по координатному столу заметно выше. Но там ремённые передачи с моторов стоят на шкивы, по сути с большого шкива мотора на малый шкив исполнительного винта (считай мультипликатор).
Вот и прихожу к выводу, что самое правильное - дальше мотор не мучать, пусть он в этом номинале с нормальным моментом работает и скоростью около 600 оборотов в мин. Ппередачу на винт сделать ремённую через повышайку...
Впервые работаю с шаговиком, не думал, что столько мороки с ними... Нюансы, нюансы))))
sadman41 ...а вот интересно почему от следящих ушли к шаговикам? простота?
От следящих чего?
Ну, и я никуда не уходил, решений об уходе не принимал, то есть моё мнение будет лишь гипотезой.
sadman41, благодарю за адекватные ответы. Разрешилась часть моих сомнений, поиграю с частотой ещё. Но передачу всё же поставим. Махина здоровая, даже в целях аварийного режима, это целесообразнее.
Ещё тут подумал, шустро крутят обычно мелкие моторчики, крупные (читай моментные - ибо в этом смысл их размера) менее скоростные. Вот эта идеология и принята сейчас мною за некий компромисс. На днях пойду налаживать оборудование дальше, продолжу эксперименты, спасибо за участие на данном этапе.
Посмотрите статью
я там привел кусок кода для управления осью с разгоном и торможением. Компилироваться оно не будет, тк нет переменных в тч масок для управления портами, и потом там многое на глобальных переменных. Код завороченный ибо писался сначала под одновременное перемещение по XY
однако, если будут вопросы подскажу.
аксельстеппер долго крутил, но в итоге решил писать сам
кстати. А в начале работы какая то калибровка по нулевой точке предусмотрена!
на делении шага сильно проседает момент и драйвер начинает дико греться. Если есть возможность применить шаговик с редуктором то хорошо.
От следящих чего?
Ну, и я никуда не уходил, решений об уходе не принимал, то есть моё мнение будет лишь гипотезой.
я обслуживал станки где в качестве приводных моторов были "следящие электроприводы станков ЧПУ" -книжка так же называлась, где они описывались, мотор с энкодером, раньше повсеместно их применяли, теперь шаговики, вот он уход )))
И сейчас применяют в настоящих станках, а не китайских граверах за 100000.
в качестве приводных моторов были "следящие электроприводы станков ЧПУ" -книжка так же называлась, где они описывались, мотор с энкодером, раньше повсеместно их применяли, теперь шаговики, вот он уход )))
что-то до боли напиминает серву без ограничения угла... это не одно и тоже?
Посмотрите статью
я там привел кусок кода ...
...однако, если будут вопросы подскажу.
аксельстеппер долго крутил, но в итоге решил писать сам
кстати. А в начале работы какая то калибровка по нулевой точке предусмотрена!
на делении шага сильно проседает момент и драйвер начинает дико греться. Если есть возможность применить шаговик с редуктором то хорошо.
Если вопрос по калиброке задавался мне, то отвечу, что не предусмотрена. А зачем? У меня не координатный станок. Точность не нужна. Шаговик по сути ребята воткнули только для того, чтобы реверс проще организовать. У оператора станка всего одна кнопка для автоматики (пуск) и всё. Дальше хоть занажимайся)) Понажимал подготовительные операции, потом запустил и так всю смену по кругу...
Я бы вообще оставил штатное значение 200 шагов на оборот, но мотор неадекватно дёргается и вибрирует. Хотя я поиграюсь ещё с настройками. Суть такая, что при смене микрошага, частоты испульсов при всех делениях шага получается некий режим, когда мотор работает плавно, тихо и моментно. Вся настройка к этому у меня и сводилась в итоге. И вот это я назову, скажем, "номинальным" режимом. Вот во всех делениях шага при "номинальном" режиме скорость-то получается плюс-минус одинаковая... Однако при делении 1/8 он работает заметно ровнее, нежели на 1/1. Разумеется, я оставлю 1/8. Опять же, некая усреднённая настройка.
Разница в падении момента непринципиальна для ШВП (считай, как у червячной передачи) - для того она и придумана. Так что мне в коде лишнее не нужно.
я обслуживал станки где в качестве приводных моторов были "следящие электроприводы станков ЧПУ" -книжка так же называлась, где они описывались, мотор с энкодером, раньше повсеместно их применяли, теперь шаговики, вот он уход )))
Полагаю, что точное позиционирование в каких-то задачах стало дешевле получить на цифровом шаговике, а не аналоговом сервоприводе.
Итак. Промежуточно свежей головой побегал по интернетам. Эта запись скорее как черновик, чтобы собрать всё в одном месте))
1) Мотор 200 шагов на оборот, делитель 1/8, значит 1600 шагов на оборот.
2) Драйвер может 7,7 мкс минимальный фронт импульса. Частота 15 кГц, то есть 15000 импульсов в секунду предел.
3) Имеем: сейчас в железе 70 мкс (фронт шага) + 70 мкс (задержка шага), итого 140 мкс на цикл шага, значит примерно 7143 шага в секунду. Делим на обороты, получаем 4,46 об/сек или около 268 об/мин. Вот такая скорость сейчас плюс минус.
4) Максимум, что позволит драйвер: 7,7 мкс (фронт шага) + 70 мкс (задержка шага - оставим пока без изменений), итого 77,7 мкс на цикл шага, значит примерно 12870 шагов в секунду. Делим на обороты, получаем 8 об/сек или около 480 об/мин. Вот такую скорость теоретически можно "выжать".
При следующих испытаниях в тестовом коде меняем 11 строчку на 8 мкс и поиграемся с 13 строчкой. Обыскался графиков по мотору, но не нашёл у китайцев. Поэтому глянул графики с кривыми по аналогу NEMA 23. Исходя из них примерно 500 об/мин дают нам стабильный момент примерно в 80-85 процентов мощности, это примерно 10-11 кг*см, что сильно неплохо. Это я выше и назвал"номинальным" режимом. Правда графики даны для шага 1/2, других не нашёл, но можно попробовать переключить делитель на 1/2.
Ременной "мультипликатор" даст дополнительный коэффициент х2-3, что с учётом всех влияющих нюансов и неучтённых моментов увеличит скорость раза в три, что и требуется сейчас заказчику.
Итого: задача теперь попытаться при следующих испытаниях приблизиться к п.4 максимально, превратив теорию в практику))))
Всем спасибо за полезные идеи и наводки. Будем посмотреть.
inspiritus, вашу статью посмотрю обязательно подробнее, вопросы позадаю наверняка)))
Может быть от того что строки 43-47 и 58-62 у вас в циклах находятся?
А нафига тогда вообще шаговик? Мотор-редуктор тоже реверсируется.
А нафига тогда вообще шаговик? Мотор-редуктор тоже реверсируется.
да уж, жёстко, по нашему, вчерновую не по фрезеруешь на них )))
Такс, провели полевые испытания. Моя теория подтвердилась отчасти. Удалось разогнать мотор не на 80 мкс на цикл шага, а на 100 мкс. Всё равно это лучше предыдущих 140 мкс. Ремонтёры немного накосячили со шкивами, в результате страшное биение привело к срыву обоих шкивов с посадочных мест. Подумали-подумали и решили делать, как на здоровенном лазерном станке ременную передачу. Вся эпопея с ШВП отправляется на полку.
Теперь по мотору. Импульс шага по факту ему потребовался 15-20 мкс, иначе отказывался запускаться (200 шагов на оборот в 1:1). Решил снова побаловаться с библиотекой. Задал скорость порядка 1500 шагов в секунду (это почти полный оборот при микрошаге 1/8). Вниз регулируется, вверх вообще никак. Пробовал с разными ускорениями от 20 до 1000 - результат один и тот же. Медленне крутиться может, но быстрее оборота в секунду не разгоняется. Хотя максимум при прямых командах тестовой программы 7 оборотов в секунду выжать можно. Что же не так с этой библиотекой?))) Код зашивал самый простой: в setup задаём скорость и ускорение, в loop команду runSpeed(). Всё.
Я выше писал, почему было принято такое решение до меня. Для организации простого управления. Под мотор-редуктором вы скорее понимаете постоянник. Перекидывание полярностей, реле и прочая лабутень... К тому же 24 В постоянник (а имеено такое питание предусмотрено) будет иметь момент ниже раза в 3, плюс редуктор (что опять усложняет всё). Целесообразно ли? Палка о двух концах. Хотя я вот в примере глянул, там, по-моему, вообще у них промышленный асинхронник стоит... Ну что закуплено по документации, с тем и придётся работать на текущий момент.
Такс, провели полевые испытания. Моя теория подтвердилась отчасти. Удалось разогнать мотор не на 80 мкс на цикл шага, а на 100 мкс. Всё равно это лучше предыдущих 140 мкс.
Про ограничение скорости в библиотеке забылось вчера совсем))).
100 мкс с места и уверенно. Если вал заблочить (скажем, случайно), может и не запуститься. А в драйвере написано по документации, что ширина импульса минимальная 7,7 мкс (но это скорее для маломощных моторов - предельный режим), тут пробовал с места с 10, с 15, с 20 мкс... С 15 нестабильно, с 20 получше... Предложенный вами китаец стоял изначально и с ним не удалось подружиться. Хотя на тот момент я так глубоко и не копал в рассчётах, надо попробовать ещё раз с ним.
Если по правильному разгонять, то наверное, можно ещё скорость увеличить (не с места газануть, а после небольшого разгона).
Скажем, по-топорному это будет выглядеть как портянка одних и тех же команд последовательно:
......сначала задержка STEP DECAY 200 мс
......сначала задержка STEP DECAY 150 мс
......сначала задержка STEP DECAY 100 мс
......сначала задержка STEP DECAY 70 мс
Хоть это и выглядит как "дерьмовый" код, но работать, вероятно, будет так, как нужно. Но как это всё организовать в цикле запуска мотора в общей команде? Если следовать моей программе, то после получения сигнала с кнопки запуска мы вставляем алгоритм разгона (скажем 10-20 строчек), далее переходим в цикл, где уже четыре строчки кода с максимально возможной скоростью +строчки на считывание сигнала с кнопки концевика циклятся до срабатывания концевика.... Верно?
Идея кажется одновременно и рабочей, и тупой до безобразия.
В конечном счёте - все алгоритмы акселерации сводятся к изменению частоты импульсов (step delay).
Все дорогие работы - это правильное их вычисление в соответствии с заданной разгонной кривой (ramping) и поиск этой самой кривой.