В уроке подключим STEP/DIR драйвер TB6560-V2 к плате Ардуино. Научимся управлять им с помощью библиотеки StepDirDriver.
Предыдущий урок Список уроков Следующий урок
TB6560-V2 недорогой драйвер шаговых двигателей поддерживающий все типичные режимы и функции STEP/DIR драйверов.
В уроке будем подключать его к плате Ардуино. Все схемы и программы урока подойдут к любому другому STEP/DIR драйверу.
Подключение драйвера к плате Ардуино.
В статье о модуле TB6560-V2 есть две схемы подключения к микроконтроллеру. Будем использовать эту.
При высоком уровне сигнала (+5 В) через светодиод входного оптрона течет ток, и модуль воспринимает это как активный управляющий уровень. Резисторы 330 Ом ограничивают ток светодиодов. Т.е. драйвером можно управлять сигналами непосредственно с выводов микроконтроллеров.
С учетом этого схема подключения драйвера TB6560-V2 к плате Ардуино выглядит так.
Обратите внимание на плавкий предохранитель. Я настоятельно рекомендую его поставить. В схемах с простыми драйверами при сгорании ключей через двигатель течет рабочий ток, ограниченный либо сопротивлением обмотки, либо дополнительным резистором. В драйверах со стабилизацией тока ток регулируется за счет ШИМ модуляции. Если в подобных устройствах сгорают выходные ключи, то на двигатель может попасть полное напряжение питания. Это приведет к недопустимому току и сгоранию шагового двигателя. Процесс это медленный, поэтому от выхода из строя привода спасет любой предохранитель – плавкий или самовосстанавливающийся.
Параметры драйвера задаются переключателями на плате модуля. Я задал ток фазы 1 А.
Переключателями S3 иS4 выбирается режим коммутации фаз.
Состояние переключателей | Режим | |
S3 | S4 | |
OFF | OFF | шаговый |
ON | OFF | полу шаговый |
ON | ON | микро шаговый 1/8 шага |
OFF | ON | микро шаговый 1/16 шага |
Для начала я задал шаговый режим, потом проверил все остальные. Все режимы описаны в статье о модуле TB6560-V2. Там же показано, как задавать их переключателями модуля.
Собранная схема у меня выглядит так.
Осталось научиться управлять такой системой.
Библиотека StepDirDriver.
Эту библиотеку я разработал для управления STEP/DIR драйверами. Она полностью совместима по функциям с библиотекой StepMotor (урок 29). Только 2 отличия:
- Конструктор имеет другие аргументы. Просто для STEP/DIR драйвера требуются другие сигналы управления и другое количество сигналов.
- В функции установки режима setMode() игнорируется параметр stepMode – режим коммутации. Режим задается переключателями на драйвере.
Загрузить библиотеку StepDirDriver можно по этой ссылке:
Описание класса StepDirDriver.
У класса следующие public методы.
class StepDirDriver {
public:
StepDirDriver(byte pinStep, byte pinDir, byte pinEn); // конструктор
void control(); // управление, функция должна вызываться регулярно с максимальной частотой коммутации фаз
void step(int steps); // инициирует поворот ротора на заданное число шагов
void setMode(byte stepMode, boolean fixStop); // задает режимы коммутации фаз и остановки
void setDivider(int divider); // установка делителя частоты для коммутации фаз
int readSteps(); // чтение оставшихся шагов
} ;
Нетрудно догадаться, о назначении аргументов конструктора:
- pinStep - вывод сигнала STEP;
- pinDir - вывод сигнала DIR;
- pinEn - вывод сигнала ENABLE.
StepDirDriver myMotor1(10, 11, 12); // создаем объект StepDirDriver, задаем выводы для сигналов STEP, DIR, ENABLE
Описание методов библиотеки StepDirDriver.
void control()
Необходимо вызывать метод регулярно в параллельном процессе (прерывании по таймеру). В нем вырабатываются управляющие сигналы, определяющие коммутацию фаз. Частота вызова функции control() вместе с делителем, задаваемым функцией setDivider, определяет скорость вращения двигателя.
// обработчик прерывания 200 мкс
void timerInt () {
myMotor1.control(); // управление двигателем
}
void step(int steps)
Метод инициирует поворот двигателя на заданное число шагов. В микро шаговых режимах речь идет не о физических шагах двигателя, а о микро шагах. Параметр steps с положительным значением инициирует поворот против часовой стрелки, с отрицательным значением – по часовой стрелке.
Запустив вращение функцией step()
myMotor1.step(300); // сделать 300 шагов против часовой стрелки
программа может выполнять другие задачи. Двигатель остановится сам. В любой момент двигатель можно остановить командой
myMotor1.step(0); // остановить привод
Ничего не мешает задать новое число шагов, не дожидаясь остановки двигателя. Для непрерывного вращения можно периодически вызывать функцию step() с большим числом шагов.
myMotor1.step(30000); // постоянное вращение
О том, что двигатель остановился можно узнать с помощью метода readSteps().
void setMode(byte stepMode, boolean fixStop)
Метод задает состояние двигателя при остановке.
- Если fixStop = true, то при остановке на обмотки двигателя подается ток удержания, положение ротора зафиксировано.
- При fixStop = false, напряжение с обмоток двигателя при остановке снимается.
Аргумент stepMode игнорируется. Он добавлен для совместимости с такой же функцией библиотеки StepMotor.
myMotor1.setMode(0, true); // фиксация ротора при остановке
myMotor1.setMode(0, false); // двигатель полностью отключен
void setDivider(int divider)
Функция задает коэффициент деления частоты вызова метода control(), а значит, определяет скорость вращения двигателя. Скорость вращения можно вычислить по следующей формуле:
Rpm = 60 000 / ( divider * Tcontrol * Nдвигателя ) / Nмикрошагов
- Rpm – скорость вращения в оборотах в минуту;
- Tcontrol – период вызова метода control() в мс;
- Nдвигателя – число шагов двигателя на полный оборот;
- Nмикрошагов – число микро шагов двигателя на одну фазу.
Для шагового режима Nмикрошагов = 1, для полу шагового Nмикрошагов = 2 и т.д.
myMotor1.setDivider(5); // делитель частоты 5
int readSteps()
Метод считывает количество шагов, оставшихся до остановки двигателя. Возврат 0 означает, что двигатель остановлен.
if (myMoto1r.readSteps() == 0) {
// двигатель остановлен
}
Примеры использования библиотеки StepDirDriver.
Использование новой библиотеки ничем не отличается от применения функций библиотеки StepMotor из предыдущих уроков.
Всего два отличия:
- Подключение библиотеки #include <StepDirDriver.h> вместо #include <StepMotor.h>.
- Другой формат конструктора StepDirDriver myMotor(10, 11, 12); вместо StepMotor myMotor(10, 11, 12, 13).
В программе меняются всего 2 строки.
Можете загрузить и проверить скетч программы
, которая заставляет сделать двигатель 2 оборота по часовой стрелке со скоростью 1 оборот в секунду, затем пауза 1 секунда, 2 оборота против часовой стрелки, опять пауза на секунду и так в цикле. Он похож на примеры из предыдущих уроков для библиотеки StepMotor. Не забудьте установить библиотеку StepDirDriver:
Проверка драйвера шагового двигателя с AT командами.
Я заменил две строчки программы драйвера с управлением от компьютера из Урока31 и получилось новое устройство для работы с шаговым двигателем. Загрузить новый драйвер с управлением по протоколу AT команд можно по этой ссылке:
Собрал систему по схеме в начале урока и проверил в самых разных режимах. Не буду описывать все подробно. Остановлюсь на микро шаговом режиме.
Задал микро шаговый режим с 16 микро шагами. У меня двигатель имеет 400 физических шагов. В микро шаговом режиме получился двигатель, имеющий целых 6400 шагов на оборот! Попробовал управлять программой верхнего уровня StepMotor (урок 31).
Все работает. Точность установки просто невероятная.
Проверил и работу следящего электропривода из урока 32.
Разрешающая способность положения ротора почти 0,05 °!
Другие варианты библиотеки StepDirDriver.
Библиотека StepDirDriver вырабатывает сигналы управления с высокими активными уровнями. Если STEP/DIR драйвер подключить к плате Ардуино непосредственно, без оптронов, то необходимы управляющие сигналы с низкими активными уровнями. Я сделал такой вариант библиотеки.
Есть еще один вариант библиотеки с типом данных long для свойства step.
Наверное, в последних двух уроках я убедительно показал преимущества STEP/DIR драйверов. Но какой драйвер применять в конкретном случае решать разработчику. Что важнее низкая цена простого драйвера из ключей или функциональность STEP/DIR драйвера.
Бывают очень серьезные разработки с простыми драйверами. Например, практически все шаговые двигатели в фасовочном оборудовании НПП ”РОСТ” работают в униполярном режиме с простыми драйверами-ключами. Из-за этого у двигателей уменьшился крутящий момент, снизилась максимальная скорость вращения, но зато значительно упала цена системы управления. Для устройств с 7-10 шаговыми двигателями это важно.
Надо выбирать оптимальный вариант. В каких-то случаях без STEP/DIR драйвера не обойтись, в других проектах вполне удачно будут работать простые драйверы.
Здравствуйте, спасибо за урок. Не могли бы вы подсказать, как с помощью вашей библиотеки реализовать движение двигателя на один шаг и остановку, подобно кнопке «+1 шаг» в вашей программе? никак не могу разобраться с таймингами. Заранее благодарю.
Здравствуйте!
Сделать функцией step() один шаг. myMotor.step(1); Программа верхнего уровня эту команду и вызывает.
Только, имейте в виду, что если режим без фиксации двигателя, особенно в полу шаговом режиме, то после одного шага двигатель отключится и ротор может вернуться в предыдущее состояние под действием механической нагрузки. Т.е. физического шага он не сделает.
И еще. Арсентий, если хотите подробно обсудить какой-нибудь вопрос — я открыл форум http://mypractic-forum.ru.
Здравствуйте
А как решить задачу управления двумя или тремя шаговыми двигателями одновременно но с разными скоростями?
Здравствуйте. Создать три объекта StepDirDriver и задать для них разные скорости.
Не компилируется sketch_34_5.
GetFileAttributesEx C:\DOCUME~1\Admin\LOCALS~1\Temp\arduino_build_726012: Не удается найти указанный файл.
Ошибка компиляции для платы Arduino/Genuino Uno.
Еще раз проверил. Все компилируется. Может быть библиотеки не подключили. Какую ошибку компилятор пишет?
На работе проверил все компилится.
Скорее всего чтото с компилятором или с компом.
Спосибо за ответ.
Уроки Класс.
Спасибо за урок.
А как использовать данную библиотеку, если у драйвера общая не земля а +5 вольт?
Здравствуйте!
Библиотека рассчитана на управляющие импульсы высокого уровня. Но в принципе полярность не сложно изменить.
Доброго. Помогите чайнику, подключил драйвер к ардуино и ШД правильно как у вас (все минуси на драйвере в кучу и к GND ардуино, степ-10, дир-11, енабл-12), теперь не могу разобратса с кодом, если вам несложно пропишите мне простой код, лево/раво/пауза.
Я раньше только с компа по лпт работал, а для совсем простих задач пробую через ардуино.
Зарание благодарен.
Скопировал ваш скетч, пишет ошибку,
Arduino: 1.6.7 (Windows 7), Плата:»Arduino/Genuino Uno»
C:\Users\ADMIN\Documents\Arduino\sketch_jun12c\sketch_jun12c.ino:7:22: fatal error: TimerOne.h: No such file or directory
#include
^
compilation terminated.
Несколько библиотек найдено для «StepDirDriver.h»
Используется: C:\Users\ADMIN\Documents\Arduino\libraries\StepDirDriver
Не используется: C:\Program Files (x86)\Arduino\libraries\StepDirDriver
exit status 1
Ошибка компиляции.
Это сообщение будет содержать больше информации чем
«Отображать вывод во время компиляции»
включено в Файл > Настройки
Помогите чайнику пожалуйста
с первой вроде разобрался, вот новая(
Arduino: 1.6.7 (Windows 7), Плата:»Arduino/Genuino Uno»
C:\Users\ADMIN\Documents\Arduino\sketch_jun12c\sketch_jun12c.ino:8:22: fatal error: TimerOne.h: No such file or directory
#include
^
compilation terminated.
exit status 1
Ошибка компиляции.
Это сообщение будет содержать больше информации чем
«Отображать вывод во время компиляции»
включено в Файл > Настройки
Здравствуйте!
А вы библиотеку TimerOne.h установили?
Да уже получилось, извените за мою тупость
Получилось скомпилировать, даже на драйвере лампочка моргает видно есть сигнал, возможно проблема с моим драйвером YKA2608MC эму нужна фиксация при остановке, у него чуток другие команды на енабл, помогите разобратса пожалуйста
Возможно нужна интерфейсная плата? я такой драйвер подключал через нее, можно обойтись без интерфейсной платы сразу с ардуино на драйвер?
Здравствуйте!
Какая интерфейсная плата? Если драйвер с интерфейсом STEP/DIR, то подключается непосредственно к плате Ардуино.
Заработало! Спасибо, моя ошибка в том что я не подключил средние обмотки шаговика, нужно все 6 проводов подключать Оо, а нельзя както на 4 как всегда было? может возможно с ардуино в cw/ccw интерфейс драйвера подавать команды?
Здравствуйте!
Если не составит труда, можете написать пример чтобы поставить шаговик в ноль и датчик края рабочей зоны?
Заранее Благодарен.
Здравствуйте!
Конкретная реализация зависит от структуры программы. Принцип такой. Создаете объект Button (урок 9) для датчика-концевика. В цикле вызываете функцию step(1000). Указываете заведомо большое число шагов, я задал 1000. Анализируете концевик. Как только он становится активным (нажатым), останавливаете двигатель функцией step(0).
Лучше откройте тему на форуме сайта http://mypractic-forum.ru/ и более конкретно опишите задачу. Как вы хотите реализовать ее в прерывании или цикле loop().
Подключил униполярный шагавикчерез ключи, работает. Но когда стоит, греется движок, жаль, нет функции удерживания. И как выше сказано про управление по step dir. Как бы нибыло за программу пять.
Зато очень простой драйвер и программа требует минимальных ресурсов.
подскажите пжта: использую двигатель 17HS2408 Nema17. в даташите двигателя сказано, что rated current=0,6 A. значит я должен выставить на TB6560-V2 0,5 или 0,8 А ?
и можно ли подключить к TB6560-V2 два двигателя (одинаковых), как в этом случае выставлять ток ?
Здравствуйте!
Если режим работы длительный, тогда лучше 0,5 А.
Два двигателя к одному драйверу со стабилизацией тока фазы подключать нельзя. Токи равномерно между обмотками не распределятся. Разница в сопротивлении, индуктивности, механической нагрузке…
спасибо за оперативный ответ.
т.е. в принципе можно подключить два драйвера к arduino на свободные ноги. в скетче просто продублировать блоки ?
и вопрос с питанием. подключил блок питания на 24 V 1 А. двигатель 17HS2408 еле работает. возможно, надо взять 2А ? у вас какой блок питания на картинке ?
Здравствуйте!
Можно два драйвера подключить к одним и тем жен выводам платы.
У меня блок питания 12 В, 6 А. Но с вашим все должно работать. Может быть вы слишком высокую скорость задали? От блока питания драйвер должен потреблять ток примерно 0,5 А * 0,5 А * 8 Ом / 24 В * 2 обмотки = 170 мА
при скорости делителя в программе Stepmotor выше 60-ти перестает вращаться, только стучит.
не работает программе шаговый режим — все время крутит в одну и ту же сторону, как при положительном,так и отрицательном значении шагов(может проблема в коде ?). если нажимать на стрелки, то крутит в правильном направлении. кстати, с AT командами в шаговом режиме тоже крутит в одну и ту же сторону.
в чем может быть проблема ? все же блок питания ?
Здравствуйте!
Проверьте с помощью простых программ из урока. Может вы неправильно подключили. Какой драйвер?
драйвер все тот же — (я выше писал) TB6560-V2.
если бы подключение было неверным AT команды не работали бы. а они работают на скорости 20.
заказал блок питания 12В 5А для драйвера.
Больше похоже на то, когда у меня обмотки были неправильно подключены. Драйвер как-то через силу заставлял движок вращаться, но со скрипом, скрежетом и в непредсказуему чаще одну сторону. Потом два провода местами поменял — всё заработало
Здравствуйте!
Скажите пожалуйста, насколько сложно написать скетч для режима обучения при управлении, например, пятью шаговыми моторами?
Здравствуйте!
Трудно сказать. Зависит от конкретной задачи.
А ВЫ не могли бы указать хоть примерное направление, как организовать такой режим, чтобы с панели управления запускать последовательно несколько (5 шт.) шаговых двигателей, задавая определенные углы поворота и последовательность их включения и это все автоматически запоминалось с возможностью корректировки углов поворота программно. Вообще, возможно ли это? Задача такая ставится для управления станком 3d гибки проволоки.
Здравствуйте!
Надо создать в программе 5 объектов — двигателей. Проверить каждый отдельно. Затем сделать программные таймеры, запускаемые в нужной последовательности. Добавить управление параметрами таймеров и двигателей. Нельзя сказать, что очень сложная, но достаточно объемная задача.
Большое спасибо.
С интересом прочитал ваш блог.
Все статьи написаны доходчиво и понятно.
Спасибо Вам.
По теме.
Не думали как организовать перемещение на большое количество шагов. Допустим мне нужно 40000 — пока это будет непрерывное вращение.
Здравствуйте!
Спасибо за добрые слова.
У меня есть библиотека StepDirDriverL — аналог библиотеки StepDirDriver с аргументом для шагов в формате long. В ближайшее время выложу ее на сайте.
Добрый день, Эдуард!
Спасибо за Ваш труд, Все понятно и доходчиво. Ваш блог подтолкнул меня на изучение Ардуино. Ваша библиотека StepDirDriver мне очень понравилась, и я решил использовать ее для своего небольшого проекта.
Необходимо плавно регулировать скорость вращения двигателя от 2RPM до 35RPM. (двигатель подключен в режиме микро шага 1/16) Но вот тут у меня и возникла проблема,
если от 2RPM до 10, регулировка проходит относительно плавно, то дальше обороты регулируются скачками 12,15,18, 25,37. Как я понимаю, это из за того что функция void setDivider(int divider), может принимать только целые значения, а например для 16rpm ее значение должно быть 4,68, для 17 =4,41, для 18 =4,68…
Может можно что-то изменить в Вашей библиотеке, чтобы divider можно было задавать десятичной дробью?
Простите если что то не так написал, мой опыт работы с Ардуино всего пара недель.
Здравствуйте! Спасибо за добрые слова.
На счет дискретности частоты вращения. Прежде всего почитайте в уроке 29 есть абзац посвященный этой теме.
Единственный путь — увеличение частоты вызова функции control(). Библиотека StepDirDriver работает параллельным процессом, позволяя одновременно выполнять и другие задачи. Чем будет выше частота вызова control(), тем меньше останется времени на остальные задачи. Например, у библиотеки Stepper время переключения фаз отсчитывается постоянным вызовом функции micros() и сравнением значений времени этой функции. На все остальное уже ресурсов микроконтроллера не хватает. И эта библиотека полностью подвешивает работу программы.
Добрый вечер, Эдуард. Спасибо, что ткнули меня в 29й урок. Слона то я и не заметил. А ведь в тексте есть ссылка на него! И у меня получилось 20мкс. И все заработало. Правда вылезли новые косяки в моем «проекте»,но к Вашей библиотеке они не имеют отношения, и мне кажется что я знаю куда копать.
Ещё раз Спасибо!
Эдуард, спасибо за проделанную и опубликованную работу! Недавно начал изучать программирование ардуино, в том числе по вашим урокам. При попытке скачать резидентную программу открывается страница в браузере с кракозябрами вместо русского текста. windows xp, браузеры разные. так и должно быть?
Здравствуйте!
Нажмите в середину страницы с кракозябрами правой кнопкой мыши и выберите Сохранить как. Сохранится исходный файл, который будет нормально отображаться в редакторе и в Arduino iDE.
Спасибо, все получилось! Еще вопрос: если шаговый по Х намечается для перемещения винтом каретки весом несколько кг (фрезер с шаговым по Z) не будет ли недостатком отсутствие ускорения и замедления в библиотеке?
Здравствуйте!
Надо проверять на практике. Можете попробовать сделать несколько шагов на низкой скорости, потом скорость повысить.
Спасибо, понятный и простой способ.
Здравствуйте, Эдуард.
А сможет ли Ардуино управлять серводвигателем 90ST M02430 ?
Купил на Али в комплекте с серводрайвером, а у него 10000 импульсов на оборот, и надо до 3000 об/мин крутить. Это значит контроллер нужен чтобы 500 кгц выдавал?
Здравствуйте!
Я никогда не работал с этим двигателем. Не знаю интерфейс связи, но думаю, никаких проблем с управлением от Ардуино быть не должно.
Спасибо
Добрый день .
Помогите дополнить ваш скетч внедрением кода для запуска шаговика по сигналу от магнитного керкона (модуль magswitch для адуино ).
Логика такова ,при геркон замкнут ,то пуск шаговика на определенное к-во шагов ,дальше стоп и так в цикле
Здравствуйте!
Может вы сможете модернизировать программу из это темы http://mypractic-forum.ru/viewtopic.php?t=62.
Если не получается, то откройте новую тему на форуме сайта, я помогу.
Добрый вечер . Спасибо за ответ .Результаты есть ) Есть еще вопросы , их озвучу в теме на форуме
Марк
Здравствуйте Эдуард!
Большое спасибо за Ваши уроки, изложено просто отлично!
Вопрос1:
Подключил ШД через драйвер TB6560-V2, используя Вашу библиотеку StepDirDriver, всё заработало. Смотрел сигналы обмена осцилографом, уровень сигнала EN при вращении ШД =0. Попробовал отключить вход EN от 12pin, на работу это не повлияло. Это случайность?
Вопрос 2.
Каким образом Ардуино сообщает драйверу TB6560-V2 о необходимости держать или нет двигатель под током при остановке ШД командой «myMotor1.setMode(0, true);», с помощью каких сигналов обмена? То, что функция работает, я убедился.
Здравствуйте!
Почитайте статью на сайте о драйвере TB6560-V2 в разделе электронные компоненты. Там есть объяснения на ваши вопросы.
Сигнал Enable имеет активный низкий уровень, т.е. когда он не подключен, то драйвер работает.
В драйвере TB6560-V2 снижает ток фаз при остановке автоматически. На плате установлен ждущий мультивибратор. Когда фазные импульсы перестают переключаться он снижает фазные токи.
Здравствуйте Эдуард!
Большое спасибо за оперативный ответ.
А еще не подскажите, можно ли сохранить в оперативной памяти РС данные, которые выводятся на монитор порта из Ардуино?
Здравствуйте!
Конечно. На компьютере можно все. В уроках про датчики температуры (уроки 24-27) данные сохраняются в памяти и выводятся в виде диаграмм.
Эдуард, приветствую!
Выложите, пожалуйста, библиотеку StepDirDriverL.
Мне нужны большие числа в шагах.
Спасибо!
Здравствуйте! Выложил.
Не пойму как с плмощью этой библиотеки заставить вращаться на заданные скажем энкодером обороты и после выполнения этой задачи остановится? Как не пробовал задавать условия, мотор доходит до 0 и вновь начинает вращаться!?!?!
Здравствуйте!
Один раз вызвать функцию с числом шагов. Должен остановиться.
myMotor1.step(100);
Эдуард, спасибо за оперативный ответ! Все получилось
Здравствуйте Эдуард! Благодарю Вас за ведение этого прекрасного блога и великолепное предоставление информации! Если возможно, замените, пожалуйста, в примере скетча комментарии, а то символы искажены (Ваша ссылка http://mypractic.ru/downloads/arduino/sketch_34_4.ino).
Здравствуйте! Спасибо за отзыв.
Нажмите на ссылку, откроется окно с искаженными комментариями.
Нажмите правой кнопкой мыши и выберите «Сохранить как».
Не знаю, как лучше файлы ino представлять. В zip формате или непосредственно. Некоторые браузеры показывают без искажений.
Эдуард, подскажите пожалуйста, как при использовании вашей библиотеки реализовать плавный разгон ШД при старте, чтобы скорость в течении пары секунд росла от 0 до заданной? У меня при старте мотора получается ощутимый рывок, иногда происходит обрыв провода (намоточный станок)
Здравствуйте!
На форуме сайта (http://mypractic-forum.ru/viewtopic.php?t=133) есть доработанная библиотека StepDirDriverLA с плавным разгоном. Но я ее не проверял.
Эдуард, добрый день! Залил Ваш скетч из данного урока. Вращение с прерыванием только в одну сторону. Не пойму почему. Подскажите, пожалуйста, в чем может быть проблема.
Здравствуйте!
Наверняка, аппаратная ошибка. Проверяйте соединения. Посмотрите уровень вывода PIN 11. Он должен меняться в зависимости от направления вращения.
Моя ошибка — не подключил Землю на Ардуино! Теперь все супер, спасибо!!!
Здравствуйте Эдуард. Возникли трудности с подключением второго ШД. Из ответа на похожий вопрос «Создать три объекта StepDirDriver и задать для них разные скорости» ничего не понял.
StepDirDriver должны иметь вид StepDirDriver1, StepDirDriver2 и т.д.? Нужны ли ещё какие дополнения? Заранее благодарю за советы.
Здравствуйте!
Например, в этом проекте http://mypractic-forum.ru/viewtopic.php?t=131 используется 2 шаговых двигателя. Посмотрите. Непонятно — спрашивайте.
Здравствуйте Эдуард. Большое спасибо за то, что направили по нужному пути. Благодаря Вашим урокам многое становится понятным. Успехов Вам и новых разработок.
Спасибо.
Добрый вечер уважаемый Эдуард. Решился опять просить у Вас совета. Возникла необходимость попробовать пример 34_4 на плате с Mega8, но компиляция не идёт, ругается на библиотеку TimerOne. Для Mega168 и 328 нормально. Помогите пожалуйста!
Здравствуйте!
Надо искать библиотеку таймера для Mega8. Может использовать другой таймер.
Большое спасибо за такой оперативный ответ. Всего Вам хорошего!
Очень полезная библиотека, очень понятно все разъяснили. Благодарю!
У вас кодировка в скетчах слетела. Комментарии нечитаемы. Как исправить?
Здравствуйте!
Открываете скетч в новом окне, нажимаете правой кнопкой мыши, выбираете «Сохранить как», и сохраняете файл на диске.
Скетч 34_4 не работает.
Ругается на строку
// Timer1.attachInterrupt(timerInterrupt, 250); // задаем обработчик прерываний
Библиотеку TimerOne поставил.
У меня драйвер А4988. Двигатель НЕМА 17. Ардуино нано на 328р.
На timerInterrupt в скобках ругается. Пробовал другие библиотеки. Вашу MsTimer2. Тот же эффект. Главное, в других скетчах прерывания работают. В этом нет. Конфликт библиотек? Как с этим бороться?
В скетче 34_5 то же самое.
Здравствуйте!
Убедитесь, что в пути к файлам Ардуино нет папок с именами на кириллице.
Спасибо за помощь! Но возникла еще одна проблема с плавной регулировкой скорости шагового двигателя. Скорость меняется неравномерно, мотор вибрирует во время работы, а то и вовсе выходит из синхронизма. Период прерывания по таймеру не менял.
Нашел причину. Невнимательность. Увеличил количество шагов в функции myMotor.step(). Все заработало как надо. Однако, при прошивке и при открытии сериал-порта мотор начинает дергаться. Как этого избежать?
Привет,Эдуард! Сколько шагов в секунду может выдать эта библиотека?
Здравствуйте!
Зависит от частоты вызова функции control(). Но главный вопрос, какую скорость коммутации фаз допускает драйвер и двигатель.
Привет, Эдуард! Я выяснил максимальную скорость этой библиотеки для Ардуино Нано и скетча » 2 оборота по часовой-2 оборота против», получилось, примерно, 35 кГц. Это при периоде прерываний 25 мкс, делителе=1. Вопрос на другую тему: Как независимо задавать направление вращения для разных двигателей, работающих одновременно?
Достаточно ли задать отрицательное количество шагов, или обязательно задавать md (как в примере)?
разобрался. вопрос снимается!
Привет, Эдуард! Есть ли возможность определять шаговик двумя пинами, без Enable?
Здравствуйте!
Да, конечно. Если драйвер с оптовходами, то достаточно бросить сигнал ENABLE в воздухе. Если используете драйвер с логическими входами, то надо установить сигнал в разрешающее состояние.
Привет, Эдуард! Я имел в виду возможность освобождения пинов под другие цели, например пина 12 в этом примере StepDirDriverL stepperA(10, 11, 12);
Здравствуйте!
Тогда, нет. Библиотека занимает все 3 вывода.
Здравствуйте. Подскажите пожалуйста каким образом реализовать контроль шагов? Чтобы можно было подключить например к счетчику и видеть положение ШД
Здравствуйте!
В библиотеке есть функция чтения оставшихся шагов. Разность между заданным и оставшимся числом шагов и есть сделанное число шагов.
Спасибо!!! Все получилось
Вопрос к уважаемому автору библиотеки: у меня первый таймер уже используется для энкодера, возможно ли задействовать другой таймер?
Здравствуйте!
Да, конечно. Только библиотека для таймера 2 MsTimer2 позволяет задавать минимальное время прерывания 1 мс. Иногда этого недостаточно.
Спасибо, попробовал на таймере 2 все работает!
Здравствуйте! Подскажите как создать переменную с помощью которой можно было бы менять скорость вращения шагового двигателя по интерфейсу? Эти уроки изучил досконально (полагаю ,что нужно два (TimerOne.h) ) ! Буду очень признателен за помощь!
Здравствуйте!
А по какому интерфейсу? И от какого устройства управлять?
Интерфейс 485! Главное устройство -панель оператора Wintek MT 8071 ie или аналогичное!
На данный момент по 485 панель подключена по уроку 61. Теперь хочу добавить туда управление шаговым (с помощью библиотеки StepDirDriver).
Здравствуйте!
Так в чем проблемы. Берете программу из урока 61. Создаете объект StepDirDriver. В обработчик прерывания вставляете
myMotor.control(); // управление двигателем.
Теперь можете менять параметры, запускать двигатель функцией step().
Здравствуйте! Проблема для меня в том, что обработчик прерываний (TimerOne.h) необходим и для управления двигателем и для интерфейса. А он в ARDUINO один! И так понимаю для двигателя он ещё должен быть переменной?
Используйте прерывание от таймера 2, которое применяется в уроке 61. Мои библиотеки будут работать от одного таймера. Единственная неприятность, что у Mstimer2 дискретность 1 мс.
Да , скорость и так не велика! А для интерфейса Mstimer2 не годен?
В принципе можно использовать, только правильно выставить тайм-аут. И еще надо учесть, что поплывут временные параметры между пакетами. Но может для вашего устройства это не так важно.
Можно использовать таймер 2 без библиотеки MStimer2. Тогда можно выставить время прерывания меньше 1 мс.
Полагаю второе мне подходит больше! Не научите как?
Посмотрите в уроке 74 я подключил обработчик таймера 1 по переполнению.
// прерывание по переполнению таймера 1
ISR (TIMER1_OVF_vect) {
}
Также вы можете поступить с таймером 2. Только вам не нужен режим захвата, не нужно прерывание по нему. И частоту тактирования надо изменить в регистре TCCR2B. Без включенного делителя будет период 16 мкс. Можно другой режим таймера включить, тогда выставляется любой период. Смотрите про регистры таймера в документации на ATmega328.
Спасибо! Буду пробовать!
Добрый день, Эдуарад!
Пытаюсь воспользоваться Вашей библиотекой для двигателя JK42HM34-1334 с драйвером TB6600. В целом всё как-то работает, но в шаговом режиме при скоростях вращения приблизительно 33-50 об/мин (значения делителя 13-18) двигатель начинает клинить и хаотично вращаться на небольшой угол туда сюда на некоторое количество шагов. При увеличении периода вызова функции control, например до 1000 мкс проблема появляется при тех же скоростях (соответственно делитель в 4 раза меньше). То же самое наблюдается и для полушагового режима, но для в 2 раза меньших скоростей. С уменьшением размера микрошага проблема вроде пропадает, но это не точно. В целом при любом вращении двигатель довольно сильно вибрирует. Возможно так и должно быть? Пробовал поменять полярность подключения обмоток к драйверу, но не помогло. Это вообще важно? Подскажите, что это может быть?
Спасибо!
Здравствуйте!
Может, при больших скоростях двигатель выходит из синхронизма. А при малых скоростях двигатель вибрирует?
Наоборот, при больших скоростях крутится более или менее гладко. При совсем маленьких ~6 об/мин — как будто чувствуется каждый «тик», но крутится равномерно. А вот на средних скоростях — вибрирует, скрежещет и кстати легко пропускает шаги, достаточно небольшого усилия.
Может вы неправильно двигатель подключили. Поменяйте полярность одной фазы.
Пробовал менять одну фазу, потом вторую, потом обе. Эффекта никакого. Кстати двигатель при этом крутится абсолютно так же. Полярность играет роль?
Я бы подумал, что сжёг что-то в процессе экспериментов, но в режиме 1/4 шага и меньше негативные эффекты пропадают, кроме лёгкой вибрации. Но она наверное характерна для шаговых двигателей.
PS. У двигателя 4 провода, т.е. конфигурация без средних выводов с обмоток. Это к вопросу о фазах.
Как показатель правильности работы двигателя его реакция на механическую нагрузку. Мощность двигателя нормальная? Не пропускает шаги при нагрузке?
В продолжение предыдущих комментариев. Почему-то не могу больше отвечать в той ветке.
На малых (75 об/мин) скоростях шаги не пропускает. В среднем диапазоне вообще толком не крутится, а дёргается. Но похоже всё-таки пропускает, если держать пальцами. Вообще по результатам последних тестов прямо сейчас ведёт себя очень странно. Под нагрузкой начинает крутится более равномерно, а не просто дёргаться.
Причём похоже пока я только что экспериментировал, проблемный диапазон расширился. Уже при 15 об/мин двигатель ведёт себя неадекватно. Может косячит драйвер и не выдаёт нужный ток при определённых частотах? Наверное если бы сгорели или пробились обмотки, двигатель косячил при любых скоростях?
Есть осциллограф, но не соображу что померить….
Прошу прощения, что отнимаю столько времени
Посмотрите форму импульсов на фазах. Они должны быть одинаковы.
Попытался сегодня поработать осциллографом. Контроллер выдаёт идеальные короткие импульсы на вход Pul+ (CLK+), постоянный 0 или +5 на DIR в зависимости от направления и постоянный 0 и +5 на EN в зависимости от необходимости удержания.
А вот на фазах творится что-то странное. Без нагрузки, т.е. без подключения двигателя на всех выходах идеальные прямоугольные импульсы. На A+ и A- противоположной полярности (В+ и В- соответственно тоже) и А сдвинуто относительно В. При подключении двигателя ровные прямоугольники начинают плясать, как будто у них меняется скважность. Возможно так и должно быть? Драйвер ведь подстраивает ток. Померять нормально это у меня никак не получается, не хватает навыков работы с осциллографом видимо. Но визуально картинка для проблемной и непроблемной скорости вращения никак не отличается.
Эдуард здравствуйте!
Большое спасибо за ваши труды!
Помогите пожалуйста.
Приспособил библиотеку StepDirDriver, для вращения шагового двигателя от нажатия на кнопки до концевика.
Теперь стоит задача синхронизировать с одним каналом энкодера, один импульс — один шаг (возможно с определённым коэффициэнтом). Мозгов не хватает). Примерно подскажите как это реализовать, если это возможно реализовать на данной библиотеке.
Здравствуйте!
Например, к последней программе из урока 55 добавляете библиотеку StepDirDriver. И заставляете двигатель делать шаг при каждом изменении положения энкодера.
void loop() {
if(encoder.timeRight != 0) {
myMotor.step(1); // шаг против часовой стрелки
encoder.timeRight= 0;
}
if(encoder.timeLeft != 0) {
myMotor.step(-1); // шаг по часовой стрелке
encoder.timeLeft= 0;
}
}
Большое спасибо! Буду пробовать.
Добрый день.
Требуется сделать следящий привод. Т.е. мне необходимо двигать каретку по сигналу ОС. Естественно при больших рассогласованиях скорость подачи требуется большая, при подходе к «нулевой точке» скорость уменьшаем.
Вопрос — как можно менять скорость ШД? Просто менять аргумент в myMotor.setDivider() ?
Здравствуйте!
Да. Скорость будет изменяться оперативно.
Здравствуйте, прошу подсказать как подключить этот драйвер TB6560 V2.0 непосредственно к порту LPT для программного управления ШД с помощью соотв. софта.
Спасибо.
Здравствуйте!
Выбираете сигналы LPT и подключаете их к сигналам STEP, DIR, EN. В зависимости от полярности вторые выводы оптопар подключаете к сигналу 5 В или к земле. Схемы есть в уроке.
Здравствуйте! Загрузил в Ардуино sketch_34_5, установил библиотеки TimerOne-r11.zip и StepDirDriver.zip, убедился, что они появились в списке установленных библиотек. При Скетч/Проверить-Компилировать выдаются ошибки:
==============
Arduino: 1.8.9 (Windows 7), Плата:»Digispark (Default — 16.5mhz)»
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp: In member function ‘void TimerOne::initialize(long int)’:
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:51:3: error: ‘TCCR1A’ was not declared in this scope
TCCR1A = 0; // clear control register A
^
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:52:3: error: ‘TCCR1B’ was not declared in this scope
TCCR1B = _BV(WGM13); // set mode 8: phase and frequency correct pwm, stop the timer
^
In file included from c:\users\knn\appdata\local\arduino15\packages\arduino\tools\avr-gcc\4.8.1-arduino5\avr\include\avr\io.h:99:0,
from C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.h:39,
from C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:39:
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:52:16: error: ‘WGM13’ was not declared in this scope
TCCR1B = _BV(WGM13); // set mode 8: phase and frequency correct pwm, stop the timer
^
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp: In member function ‘void TimerOne::setPeriod(long int)’:
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:70:3: error: ‘ICR1’ was not declared in this scope
ICR1 = pwmPeriod = cycles; // ICR1 is TOP in p & f correct pwm mode
^
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:73:3: error: ‘TCCR1B’ was not declared in this scope
TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
^
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp: In member function ‘void TimerOne::pwm(char, int, long int)’:
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:96:5: error: ‘TCCR1A’ was not declared in this scope
TCCR1A |= _BV(COM1A1); // activates the output pin
^
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:100:5: error: ‘TCCR1A’ was not declared in this scope
TCCR1A |= _BV(COM1B1);
^
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp: In member function ‘void TimerOne::disablePwm(char)’:
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:109:34: error: ‘TCCR1A’ was not declared in this scope
if(pin == 1 || pin == 9) TCCR1A &= ~_BV(COM1A1); // clear the bit that enables pwm on PB1
^
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:110:34: error: ‘TCCR1A’ was not declared in this scope
else if(pin == 2 || pin == 10) TCCR1A &= ~_BV(COM1B1); // clear the bit that enables pwm on PB2
^
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp: In member function ‘void TimerOne::attachInterrupt(void (*)(), long int)’:
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:117:3: error: ‘TIMSK1’ was not declared in this scope
TIMSK1 = _BV(TOIE1); // sets the timer overflow interrupt enable bit
^
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp: In member function ‘void TimerOne::detachInterrupt()’:
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:125:3: error: ‘TIMSK1’ was not declared in this scope
TIMSK1 &= ~_BV(TOIE1); // clears the timer overflow interrupt enable bit
^
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp: In member function ‘void TimerOne::resume()’:
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:131:3: error: ‘TCCR1B’ was not declared in this scope
TCCR1B |= clockSelectBits;
^
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp: In member function ‘void TimerOne::start()’:
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:143:3: error: ‘TIMSK1’ was not declared in this scope
TIMSK1 &= ~_BV(TOIE1); // AR added
^
In file included from c:\users\knn\appdata\local\arduino15\packages\arduino\tools\avr-gcc\4.8.1-arduino5\avr\include\avr\io.h:99:0,
from C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.h:39,
from C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:39:
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:144:16: error: ‘PSRSYNC’ was not declared in this scope
GTCCR |= _BV(PSRSYNC); // AR added — reset prescaler (NB: shared with all 16 bit timers);
^
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp: In member function ‘void TimerOne::stop()’:
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:164:3: error: ‘TCCR1B’ was not declared in this scope
TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12)); // clears all clock selects bits
^
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp: In member function ‘long unsigned int TimerOne::read()’:
C:\Users\KNN\AppData\Local\Arduino15\libraries\TimerOne\TimerOne.cpp:205:40: error: ‘ICR1’ was not declared in this scope
tmp = ( (tcnt1>tmp) ? (tmp) : (long)(ICR1-tcnt1)+(long)ICR1 ); // AR amended to add casts and reuse previous TCNT1
^
exit status 1
Ошибка компиляции для платы Digispark (Default — 16.5mhz).
======================
Здравствуйте!
В вашей плате используется микроконтроллер, в котором нет таймера 1 или он по-другому называется. Надо использовать для отсчета времени другую библиотеку.
Спасибо.
Здравствуйте, при попытке скачать sketch_34_5 получаются иероглифы. почему? пытаюсь запустить мотор через драйвер STEP/DIR M545D. при подаче напряжения питания 12 в при неподключенных клеммах step, dir, enab — мотор блокируется. при подаче на вход enab положительного потенциала — его можно вращать рукой. это нормальная работа или он погрел? перключатели выставлены на 2 А, двигатель на 1,8 а. раньше его я запускал, по одной из программ, сейчас не получается
Здравствуйте!
На окно с иероглифами нажимаете правой кнопкой мыши. Дальше «Сохранить как» и сохраняете в исходном формате.
Я не использовал этот драйвер. Если у сигнала EN активный уровень низкий, то он может блокировать двигатель при неподключенных сигналах.
странно, но с утра оба драйвера при включении не блокируются. вчера при первом включении питания замененный драйвер не блокировался, повторно выключил/включил питание 12 в и больше не смог с ним работать. так же как и с первым. сегодня оба норм. как будто какой то заряд на выводах остался и не давал работать.
по иероглифам подскажите таки, что делать. не получается ввести скечи.
ой, спасибо за ответ печатал без интернета. попробую
Добрый день. Использую библиотеку StepDirDriver.h
в программе управление скоростью вращения реализовано:
myMotor.setDivider(velocity);
myMotor.step(80000);
по сути, как я понимаю, переменная velocity меняет настройку делителя частоты драйвера ШД. В результате чего ШД «поет» на разные лады.
Есть возможность не меняя настройку делителя менять CLK для изменения частоты вращения?
Здравствуйте!
А каким способом, кроме как деление частоты, можно изменить частоту сигнала CLK, а значит и скорость ШД?
Можно изменить частоту вызовов функции control. Но это равносильно делению частоты CLK.
Здравствуйте! У меня драйвер TB6600 и у него выходы EN-, CW-, CLK- и +5V. Как все таки подключить его к контроллеру? Что изменится при подключении, в коде что-то менять или как?
Здравствуйте!
Судя по всему, у вашего драйвера низкие активные уровни сигналов. Тогда надо использовать библиотеку StepDirDriverN. Ссылка на нее есть в конце урока.
А может кто-нибудь Loop расписать человеческим языком? Я его совершенно не понимаю.
if (md == 0) {
// 2 оборота по часовой стрелке
if (myMotor.readSteps() == 0) { md=1; timeCounter=0; }
}
Если md==0, то значит двигатель должен крутить, однако далее идет дополнение к условию и если двигатель остановлен, то md присвоить «1». А единица это пауза. Т.е. если двигатель должен вращаться против часовой стрелки и если он при этом остановлен, то поставить паузу. Галиматья какая-то получается….
Здравствуйте!
Почему галиматья! Все просто и логично.
Цикл loop всегда проходит до конца, нигде не зависает. По какому пути он идет, определяет переменная md.
В начале md=0, и цикл проходит по первому программному блоку «управление вращением двигателя». В нем он ждет, когда результат вызова функции myMotor.readSteps() будет равен 0. Это означает, что двигатель отсчитал нужное число шагов и остановился.
Тогда переменной md присваивается значение 1, и цикл loop начинает проходить через следующий программный блок. В нем ожидается, пока счетчик времени достигнет заданного значения timeCounter >= 1000, запускается двигатель myMotor.step(-800) и md присваивается 2.
Теперь программа проходит следующий программный блок, где ждет остановки двигателя. И т.д.
Или loop нужно понимать так:
if (md == 0) {
// 2 оборота по часовой стрелке
if (myMotor.readSteps() == 0) { md=1; timeCounter=0; }
}
Если md==0 , а этот параметр по исходным условиям равен нулю, значит выполняем операторы этого условия первым из которых следует опять условие, что если двигатель не
вращается (а он и не вращается), то выполняем условие этого оператора, т.е. md==1 и счетчик устанавливаем в ноль. Правильно?
Далее
else if (md == 1) {
// пауза 1 сек
if (timeCounter >= 1000) { md=2; myMotor.step(-800); }
}
иначе если md==1 ( а он как раз стал равен единице из предыдущих действий), то выполняем следующие операторы:
если счетчик больше или равен 1000, то …. Но у нас счетчик равен нулю, значит пропускаем это условие.
Далее
else if (md == 2) {
// 2 оборота против часовой стрелки
if (myMotor.readSteps() == 0) { md=3; timeCounter=0; }
}
Если md==2 условие не выполняется, т.к. у нас md==1, значит пропускаем это условие
Далее
else {
// пауза 1 сек
if (timeCounter >= 1000) { md=0; myMotor.step(800); }
}
}
Иначе, если счетчик больше или равен 1000, но у нас счетчик равен нулю, пропускаем и это условие.
И затем увеличиваем счетчик на единицу
timeCounter++; // счетчик времени
И далее возвращаемся к началу цикла loop, пропускаем у этого цикла все условия, т.к. либо md не соответствует, либо счетчик меньше 1000. И так 1000 раз, пока не выполнится условие:
else if (md == 1) {
// пауза 1 сек
if (timeCounter >= 1000) { md=2; myMotor.step(-800); }
}
Как только счетчик станет равен 1000, выполняем условие этого оператора, т.е. md==2 и выполняем команду вращения двигателя
myMotor.step(-800)
Все верно?