Arduino управление двигателем энкодер



Подключение энкодера к Ардуино. Управление мотором энкодер.

Сегодня познакомимся с энкодером и сделаем так, что он будет управлять мотором.
Энкодер вращения — это электромеханическое устройство, предназначенное для преобразования угла поворота вращающегося объекта в электрический сигнал (цифровой или аналоговый).
В следующих видео я покажу как с помощью энкодера сделать меню управления и систему настройки электронных часов, для установки и изменении даты и времени.

В примере я буду использовать энкодер собранный в виде модуля KY-040. А ещё нам понадобятся электрический моторчик, Транзистор, я взял МОСФЕТ и Ардуино, куда же теперь без неё.
Вот схема подключение, подробнее я расскажу позже.

Для питания моторчика нужен отдельный блок питания.
А также нам понадобятся 2 резистора, зачем, я расскажу чуть позже.

Для сегодняшнего примера управления скоростью мотора я подключил энкодер в виде модуля KY-040 и мотор на 12 вольт. Но я решил не просто плавно регулировать скорость, а сделать дискретное переключение. Я определил приблизительно при каком напряжении у меня начинает вращаться мотор, и присвоил это значение первому переключению энкодера. Все последующие переключения идут с приращиванием значений. И так до шестой скорости. Это можно видеть в мониторе порта. Количество скоростей и шаг вращения может быть любым.
Для первого движения, при сбрасывании в ноль, или при изменении скорости в другую сторону, счётчик меняется через один щелчок.

При вращении по часовой стрелке, значения увеличиваются, а против часовой уменьшаются. Дойдя до нуля, мотор останавливается. Так же он останавливается при превышении значений. Остановить также можно, нажав на кнопку энкодера. При этом все значения сбрасываются. Скрипт легко переделать для паузы мотора вместо сбрасывания.

Что бы заполнить паузу, пока вы будете смотреть как управлять мотором, я расскажу как ещё можно использовать энкодер.
Очень часто его используют для отображения различных меню. В одном из следующих уроков, я обязательно такое сделаю. Как только получу дисплей, а то я все уже использовал.
Другое применение — это использовать его в настройке и установке часов. Это намного удобнее, чем устанавливать кучу кнопок, а потом запоминать для чего нужна каждая из них. Про это тоже будет видео.
При изготовлении различных моделей и роботов. И ещё много где.

Как работает скетч, я объясню чуть позже, а пока посмотрим с схему подключения.
Я подключил к Ардуино НАНО, но без проблем подойдёт любая Ардуино.
Сначала рассмотрим подключение энкодера.

  • Выход clock я подключил к пину D2
  • Data к пину D3,
  • а switch к пину D4.
  • Питание к +5 вольт ардуино.
  • Земля к земле

Так как я взял мотор работающий от 12 вольт, то для его управления нужен транзистор. Я использовал MOSFET, так как он намного лучше обычных биполярных транзисторов.
Меня часто спрашивают, зачем использовать два резистора, если и так всё работает.
Рассказываю.
Резистор на 10 ком нужен для того чтобы при отсутствии сигнала на входе транзистора было хоть какое-то напряжение, которое не даст ему ловить разные наводки и переключаться в разное состояние.
Установив этот резистор вы подаёте низкий уровень на вход, а так как сопротивление резистора большое, то при подаче на вход сигнала с Ардуино, оно никак не повлияет на работу.
А резистор на 100 ом нужен для предотвращения Ардуино от перегрузки по току. Он работает как обычный ограничитель тока. В момент открытия транзистора через него может пойти большой ток.
Ставить их или нет решать вам, но я бы советовал всё же их установить.
Это примерный список транзисторов которые можно подключать. Но их список гораздо больше. В основном они работают с приборами до 30 вольт, но есть и для большего напряжения и силы тока.

Мотор просто устанавливается разрыв между стоком и питанием мотора.
Желательно ещё параллельно включению установить диод и конденсатор, но я обычно это не делаю, и зря.

Работа скетча.
Для работы с энкодером надо установить вот эту библиотеку. Установить можно из диспетчера библиотек.
Дальше надо указать к каким контактам платы Ардуино вы будете подключать выводы data и clock. Я подключил их к выводам 3 и 2.
Мотор я подключил к контакту 9, но можно было бы подключить к любому контакту который может работать в режиме ШИМ.
Создаём переменную для хранения текущей позиции и присваиваем ей значение ноль.
Кнопку энкодера подключаем к контакту 4 платы, чтобы все провода были в одной кучке.
Дальше создаём переменные для хранения значений отвечающих за скорость вращения. У меня мотор начинает вращаться со значения 50.
Шестую скорость я установил в 120. Хоть это и является всего половиной от возможной скорости. Можно задать до 255. Остальные значения я просто плавно раскидал между оставшихся шагов.
А ещё я создал переменную для полной остановке мотора, со значением 0.
В переменную newpos будут попадать новые шаги при переключении энкодера.

В setup ничего нового.
Объявляем скорость работы серийного порта.
9 пин Ардуино объявляем как выход, а 4 pin, к которому подключеня кнопка сделаем входом, да ещё подключим внутреннюю подтяжку. Так, что при не нажатой кнопке, там всегда будет высокий уровень.
Выводим значение начальной позиции энкодера. Она у нас равна нулю.

В loop постоянно проверяем положение энкодера, а здесь получаем позицию и сохраняем в переменную new pos.
Это условие проверки нажатия кнопки энкодера. Если кнопка нажата, то сбрасываем значение энкодера в ноль. Кстати можно эту строчку закомментировать и мотор остановится, но в ноль не сбросится. Получается как бы пауза и при следующих вращениях энкодера, значения будут продолжаться. Ну и небольшой делейчик. Не помешает.

В этом условии мы проверяем было ли изменение в экодере, тоесть было ли вращение. Ели было изменение, то новая позиция не будет равна старой, и условие будет верно и мы проваливаемся внутрь.
Там мы сразу изменим позицию на новую, и теперь пока не крутанёшь ручку, в это условие не попадёшь.

Чуть расскажу про Оператор множественного выбора switch.
Сначала он получает значение из переменной pos и ищет его среди своих кейсов.
Если значение было найдено, то выполняются все команды находящиеся внутри, до оператора break.
После этого происходит выход.
Если значение не было найдено, то выполняется default и выход из оператора.
Кстати в одном кейсе могут находится несколько, и все они будут выполнены.

Если вам нравятся мои видео, то вы можете помочь в развитии канала став его спонсором. Все ваши вклады пойдут на закупки новых модулей. Вам же за это будут предоставлены дополнительные бонусы, и они довольно интересные.
Вы видите ссылки на видео, которые, я думаю будут вам интересны. Перейдя на любое из этих видео вы узнаете что-то новое, а ещё поможете мне. Ведь любой ваш просмотр — это знак YOUTUBE, что это кому-то интересно и что его надо показывать чаще.
Спасибо.
А пока на этом всё.

Источник

Обработка сигналов энкодеров в Arduino

Методист по олимпиадной робототехнике Университета Иннополис Алексей Овсянников рассказывает, как обрабатывать сигналы энкодеров двигателей робота в Arduino.

Множество команд используют для создания робота широко распространенный набор Lego Mindstorms EV3 или аналогичные (VEX и подобные). Их особенность в использовании датчиков и приводов всего нескольких видов, строго определенных производителем. Контроллеры получают информацию о повороте вала мотора с точностью до градуса, могут определить текущую скорость вращения мотора или синхронизировать их (замедлить любой мотор при замедление другого и т.д.) буквально одной командой.

Олимпиада Innopolis Open in Robotics не ограничивает участников в выборе оборудования (кроме очевидного запрета на использование готовых, фабричной сборки, роботов в некоторых номинациях). Вопрос лишь в том, как использовать всю широту ассортимента китайских магазинов.

Алгоритмы синхронизации моторов хорошо описаны в пособии «Управление моторами тележки с контроллером Трик на JavaScript«. Олег Киселев, автор пособия, описывает алгоритмы, которые можно перенести на любую другую платформу. Но и в этих примерах обращения к датчикам оборотов — энкодерам — происходит через готовые команды el.reset(), er.read() и подобные. Если же использовать в качестве контроллера робота Arduino, ESP- или STM-платы, то подобные команды придется реализовывать самостоятельно.

Очевидно, что для решения задач с точными проездами и поворотами (или перемещениями звеньев робота), необходимо использовать моторы с датчиком оборотов — энкодером. Он даст обратную связь, покажет, достаточно или недостаточно повернулся вал мотора. Такие датчики имеют различную точность показаний и могут устанавливаться по-разному.

Рассмотрим принцип действия энкодера. Чаще всего в простых дешевых системах используются квадратурные инкрементные энкодеры. Эти страшные слова означают, что они выдают прямоугольные импульсы (резко, а не плавно, возникающий и пропадающий сигнал) и, посчитав эти импульсы, можно понять, насколько провернулся мотор. Какого-то определенного начального положения, начала отсчета, у энкодера нет. Подсчет потребуется реализовывать в программе контроллера. Проще всего объяснить работу оптического энкодера, который содержит диск-крыльчатку с прозрачными и непрозрачными областями (реже — с отражающими и не отражающими областями), источник и приемники оптического излучения.

Оптический сигнал проходит через «окна» в диске и попадает на фотоприемники, которые выдают сигнал. Если свет не проходит, то сигнала нет. Чем быстрее вращается диск, тем короче становятся импульсы. Таким образом измеряется скорость вращения. А как определить направление? Для этого ставят два приемника, таким образом, чтобы один из них открывался в тот момент, когда второй «видит» как раз середину окна (показывает середину импульса).

Обратите внимание, что при вращении диска по часовой стрелке сперва «открывается» приемник А — импульс на нем появляется раньше, чем на приемнике В. При вращении против часовой стрелки сигнал появляется сперва на приемнике B, потом на А. Отслеживание и сравнение сигналов позволяет понять направление вращения диска и вала, к которому он закреплен.

Стоит отметить, что энкодер может быть не только оптическим, широко распространены датчики на основе эффекта Холла, улавливающие поле вращающихся на валу мотора магнитов.

Еще раз присмотримся к сигналам, приходящим с приемников A и В: за полный период (цикл, который повторяется при отслеживании одного «окна» на диске) есть четыре состояния выходов. Можно отслеживать их все и увеличить точность измерений или отслеживать только один выход (А или В), а по второму определять направление. Какого только колхоза в программах, отслеживающих энкодеры, я ни встречал. Кто-то пытается ловить код единицами и нулями, которые обозначены на рисунке, кто-то делает пятиэтажные опросы. Но об этом поговорим позже, возможно даже, не в этой статье.

Возьмем для примера два распространенных мотора: Pololu 25mm metal gearmotor и TETRIX MAX DC Motor. Оба они являются мотор-редукторами, что означает совмещение электромотора и редуктора в одном устройстве. Электромотор вращается очень быстро, но слабо, а редуктор увеличивает усилие, снижая скорость вращения. В итоге на выходном валу мотор-редуктора мы получаем меньшую частоту вращения, но большее усилие. Pololu позволяет выбрать один из нескольких вариантов с разными редукторами. То есть, сам мотор может оставаться тем же самым, а меняя редуктор, мы можем получить разные характеристики на выходном валу.

Пока что лучше перейдем к энкодеру TETRIX DC Motor:

Он устанавливается на выходном валу мотор-редуктора. На вал крепится диск с рисками (отражающими и не отражающими областями). Таких рисок аж 1440 на диске, то есть за один оборот вала энкодер может насчитать 1440 импульсов на одном выходе или в четыре раза больше состояний. Точность измерений 0,25 градуса (4 импульса на 1 градус) или 0,0625 градуса (16 состояний на 1 градус). Внушительно!

Скорее всего Вы уже догадались, что изготовить детали с подобной точностью достаточно сложно и стоят они дорого. Взятый для примера энкодер стоит около 10 тысяч рублей.

Теперь посмотрим на мотор-редуктор Pololu с энкодером:

На рисунке я выдели цветами:

Красный — выходной вал мотор-редуктора

В случае мотора Pololu и распространенных моделей 25GA-370 энкодер вешается с обратной стороны электромотора на выходящий вал. Энкодер считает обороты не самого мотор-редуктора, а только мотора. Зная передаточное число редуктора можно рассчитать угол поворота выходного вала относительно показаний энкодера.

Подобный подход имеет важный минус, кроме очевидной необходимости проводить дополнительные расчеты, а именно — наличие погрешности измерений из-за зазоров и упругих деформациях в редукторе. Выходной вал может повернуться на долю градуса при неподвижном вале мотора. Но в большинстве случае подобные погрешности не превышают одного градуса, а проявляются при резких сменах направления вращения. А простота изготовления диска всего с 10-20 оптическими окнами или магнитными областями значительно удешевляет конструкцию. Моторы серии 25GA-370 стоят по 900 рублей вместе с энкодерами, фирменный мотор Pololu с энкодером обойдется примерно в 3000 рублей.

Посчитаем, какая точность измерений у энкодеров, расположенных на валу мотора, а не выходном валу мотор-редуктора. Для этого обратимся к сравнительной таблице моторов Pololu. Ограничимся какой-нибудь одной серией, например, 12В medium power:

Мотор-редуктор с передаточным отношением 75:1 вращает выходным валом со скоростью 100 оборотов в минуту, а при передаточном отношении 172:1 выходной вал делает 43 оборота за минуту. Просматривая страницы каждого мотора можно заметить, что реально передаточные отношения немного отличаются (74,83 и 171,79 для указанных ранее).

Посчитаем, сколько импульсов энкодер выдает за один оборот выходного вала. За один оборот магнитного диска (то есть, вала мотора) энкодер Pololu выдает по 12 импульсов на каждом выходе, энкодер моторов серии 25GA-370 по 11 импульсов. За один оборот выходного вала вал мотора делает количество оборотов, равное передаточному отношению редуктора. Для моторов Pololu выбранной серии — от 1 до 227. Для моторов серии 25GA-370 — от 4,4 до 500. Получим следующие значения (в таблицу подставлены точные значения передаточных отношений мотор-редукторов Pololu):

Чем меньше скорость вращения выходного вала, тем точнее измерения энкодера. Для наиболее ходовых и применимых в мобильных платформах моделях на 70-170 об/мин (выделены зеленым) даже простой подсчет импульсов на одном выходе энкодера дает точность менее 1 градуса. Меньше, чем 1440 импульсов и 5760 состояний энкодера TETRIX, но сопоставимо с моторами Lego.

Итоговые формулу, связывающие сигналы энкодера с градусами поворота выходного вала будут следующие:

φ — угол поворота выходного вала (в градусах);

n — «тики», сигналы энкодера;

i — передаточное отношение редуктора;

IPR — (impulse per rotation) кол-во импульсов энкодера на 1 оборот диска (может быть как 12 импульсов, так и 48 состояний, в зависимости от того, что отслеживается в программе).

Теперь посчитаем, как часто приходят сигналы с датчика. Умножив частоту вращения выходного вала на передаточное отношение можно получить скорость вращения электромотора. Для всех моторов Pololu она составляет примерно 7500-7800 оборотов в минуту. Фирма Pololu указывает частоту вращения холостого хода (мотора без нагрузки), но сам редуктор может выступать некоторой нагрузкой, поэтому частота вращения и отличается. Так как самая быстрая частота вращения как раз на холостом ходу, а под нагрузкой мотор будет замедляться, то как максимально возможную принимаем именно ее.

Для популярной серии моторов 25GA, взяв за основу таблицу с сайта DVRobot.ru, можно вычислить скорость вращения мотора примерно как 5950-6000 оборотов в минуту.

Округлим скорости вращения в большую сторону и возьмем 7800 об/мин для Pololu 12V medium power и 6000 об/мин для 25GA-370. Обе серии широко распространены и подходят для подключения через драйвера на основе L298P или L298N.

Итак, диск энкодера делает по 7800 или 6000 оборотов за минуту (обозначим частоту вращения символом ω). Энкодер двигателей Pololu выдает по 12 импульсов (IPR=12) на каждом выходе за один оборот. Итого:

Если отслеживать все четыре варианта сигналов на энкодере, то получим 374 400 состояний за одну минуту.

Энкодер моторов 25GA-370 выдает по 11 импульсов на каждый выход за один оборот. Для него получаем

Или 264 000 состояний за минуту.

Делим эти огромные числа на 60 и получаем кол-во импульсов и состояний за секунду. Вычисляем период одного импульса и состояния (время, за которое они сменяются).

У моторов Pololu на холостом ходу каждый новый импульс приходит раз в 641 микросекунду, у 25GA-370 раз в 909 микросекунд. Необходимо, чтобы наш управляющий контроллер успевал фиксировать эти импульсы. Стандартная плата Arduino UNO работает на частоте 16 МГц, то есть, делает 16 млн тактов в секунду. Один такт занимает 0,0625 мкс. Контроллеры на базе STM или ESP работают на больших частотах, их такты гораздо меньше. Желтым в таблице обозначены количества тактов, которые успевает сделать Arduino UNO за время смены одного состояния или прихода одного импульса. Может показаться, что даже 2564 тактов на считывание состояния энкодера Pololu будет более чем достаточно, но вот тут и начинает проявляться «колхоз» в программной обработке показаний датчиков. К сожалению, та же плата Arduino UNO не умеет выполнять действия в параллельных потоках, только в основном цикле. Достаточно нагрузить его сложными вычислениями дробных чисел или считыванием аналоговых датчиков (одни из самых долгих операций; паузы командой delay и работу с интерфейсом UART-Serial оставляем за скобками, они вне конкуренции) и каждая его итерации начнет занимать по несколько тысяч тактов. Считывание показаний в этом датчике неизбежно приведет к пропуску тактов. Выход из этой сложной ситуации кроется в использовании прерываний. Это специальные подпрограммы, которые выполняются при наступлении определенных событий. Например, их можно настроить на появление сигнала на пине. То есть, когда приходит импульс от энкодера, Arduino прерывает основной цикл программы, выполняет небольшой кусочек кода и возвращается в основной цикл в то же самое место, где прервалось выполнение. С точки зрения основной программы, ничего и не произошло. Важно понимать, что вызываемая по прерыванию подпрограмма должна быть как можно меньше и выполняться как можно быстрее, чтобы надолго не прерывать основную программу. Иначе можно получить ситуацию накопления прерываний — пока обрабатывается одно прерывание, происходит следующее событие и основная программа просто не успевает выполняться.

У платы Arduino UNO внешние прерывания можно повесить только на два пина: 2 и 3. Так как управлять хочется двумя моторами, получаем всего по одному прерыванию на мотор. Следовательно, будем отслеживать появление сигналов на одном выходе энкодера, а второй выход покажет направление вращения. Работа с прерываниями сводится к следующим шагам:

1. Необходимо написать подпрограммы, которые будут вызываться. Они обязательно должны быть void (не возвращать никаких значений и без параметров):

Попав в подпрограмму я узнаю, какой сигнал на втором выходе энкодера и, в зависимости от результата, увеличиваю или уменьшаю счетчик encA / encB. Обратите внимание, что эти счетчики должны быть самого вместительного типа, у меня это long, так как обычный int заполнится за минуту-две непрерывного движения.

Присоединить прерывание, то есть включить его. Делается это командой attachInterrupt() со следующими параметрами:

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode)

pin — пин, к которому привязывается прерывание (для Arduino UNO это пины 2 и 3, для других плат смотрите описание команды),

ISR — имя вызываемой подпрограммы,

mode — режим срабатывания, бывает LOW (срабатывает пока 0 на пине), CHANGE (срабатывает при любом изменении цифрового сигнала на пине), RISING (срабатывает при изменении сигнала с 0 на 1 на пине), FALLING (срабатывает при изменении сигнала с 1 на 0 на пине). В нашем случае логичнее использовать RISING.

Итоговая программа у меня получилась такой:

Неважно, что команды Serial.print() в основном цикле выполняются очень медленно, при поступлении сигналов от энкодеров они будут прерываться. Пока что программа просто выводит текущие показания энкодеров по UART’у, но используя формулы из статьи можно вычислять и угол поворота выходного вала. Попробуйте сами написать эти вычисления с учетом параметров своего мотор-редуктора и датчика.

В следующих статьях я расскажу о подключении подобных моторов и энкодеров к Arduino и другим видам контроллеров, об эффективном управлении ими.

Источник

Adblock
detector