LXF155:Крутить моторчик
|
|
|
Arduino Управляем сервопориводами и шаговыми двигателями
Arduino: Моторы и движение
Пора двигаться дальше – Ник Вейч заставляет колеса крутиться.
Когда LXF только появился, его держали на плаву исключительно скрипты Bash от Ника Вейча. Потом их заменили «люди», и это, по мнению Ника, стало шагом назад...
С тех самых пор, как Майкл Фарадей начал экспериментировать с проводниками в чашках со ртутью, в электронике, пожалуй, ничем не доставить большего и мгновенного удовлетворения, как привести что-то в движение.
Схемы Arduino обычно используются для управления роботами, но роботы не могут побежать, прежде чем сделают первый неуверенный шаг, поэтому здесь мы рассмотрим основы двигателей и сервоприводов.
Говоря о сервоприводе, обычно имеют в виду устройство, чаще всего встречающееся в радиоуправляемом оборудовании, где оно применяется для управления рулем или другими движущимися частями.
Этот тип сервопривода – обычно сочетание нескольких элементов: двигателя, который дает энергию; шестерней, соединяющих двигатель с его приводным рычагом (который может иметь различную форму и размеры); и устройства обратной связи, обычно потенциометра, с помощью которого сервопривод может точно определить положение рычага.
Для схем с сервоприводом вам понадобится обычный RC-сервопривод, ничего больше. Для шаговых двигателей нужен сам двигатель (см. врезку «Закупаемся шаговыми двигателями»), набор транзисторов и диодов или микросхема H-Bridge, типа L239D.
Сервопривод имеет три провода: по красному и черному обычно подается напряжение питания, по третьему, как правило, желтому или оранжевому – управляющий сигнал. Сервоприводы работают от аналоговых управляющих сигналов, использующих токовый импульс. Ширина импульса определяет положение рычага.
По соглашению, импульс длительностью 1,5 мс перемещает сервопривод в нейтральное положение, среднюю точку – между начальной и конечной точками, а весь диапазон возможных положений покрывает ширина импульсов от 1 до 2 мс.
Для питания одного небольшого RC-сервопривода достаточно линии питания Arduino +5 В, но если их больше, подключите более подходящий источник питания. К счастью, RC-сервоприводы обычно прекрасно работают от напряжения 5 или 6 В, поэтому Arduino и все сервоприводы можно подключить к одному внешнему источнику.
Для формирования импульса не нужен высокий ток, и для их питания не нужны дополнительные реле или транзисторы, что тоже хорошо, поскольку на коротких интервалах времени, с которыми мы работаем, с ними могут возникнуть трудности.
На самом деле, эти временные интервалы могут помешать эффективному управлению сервоприводом из кода Arduino. К счастью, существует стандартная библиотека, с редкой креативностью названная Servo. Если вы подключите свой сервопривод в соответствии с рис. 1, то сможете поэкспериментировать с ним и обнаружить его пределы.
Стандартный пример кода для нашей ситуации – шаблон под названием “Sweep”, который можно найти в примерах, поставляемых с Arduino. В нем для постепенного изменения положения сервопривода от 0 до 180 градусов используются функции позиционирования. Однако, если вы не уверены в предельных значениях для своего устройства, сначала можно попробовать что-нибудь попроще.
- include <Servo.h>
Servo servo1; // create servo object
void setup()
{
servo1.attach(9);
}
void loop()
{
servo1.writeMilliseconds(1500);
delay(200);
servo1.writeMilliseconds(700);
delay(200);
servo1.writeMilliseconds(2200);
delay(200);
}
Метод .writeMilliseconds() не содержит код, преобразующий угол в ширину импульса, и просто формирует импульс заданной длительности. Эти значения можно уменьшать и увеличивать до тех пор, пока привод не перестанет двигаться, а затем использовать их в качестве предельных при инициализации устройства:
servo1.attach(9,650,2350);
Параметры этой функции – номер вывода, минимальная ширина импульса и максимальная ширина импульса. Здесь мы используем для сервопривода вывод 9 – именно этот вывод используется чаще всего. В старых версиях кода Arduino библиотека работала только с выводами 9 и 10, и даже сейчас на всех платах, кроме Mega, вызов библиотеки сервопривода приведет к тому, что на этих выводах перестанет работать ШИМ (широтно-импульсная модуляция), поэтому можете воспользоваться и ими.
Если вы хотите или вам нужно записывать данные в сервопривод вручную, воспользуйтесь встроенной функцией map:
value = map(value,0,179,650,2350);
которая промасштабирует входное значение между первой парой чисел в соответствующее значение между второй парой чисел.
Основа шагового двигателя – статор, соединенный непосредственно с осью двигателя. Статор окружен постоянными магнитами с чередующимися полюсами, направленными наружу.
Статор окружает набор металлических сердечников, обмотанных проводниками. Между проводниками и статором есть небольшой зазор, чтобы двигатель мог вращаться. Когда через эти проводники пропускают ток, сердечник намагничивается северным или южным магнитным полюсом в зависимости от направления тока.
Намагниченные сердечники отталкивают или притягивают постоянные магниты статора, вызывая его поворот. Последовательная подача тока на проводники позволяет вращать двигатель в любом направлении или моментально его остановить.
Число сердечников и магнитов в статоре определяет угловое разрешение двигателя. Это значение существенно различается и в распространенных двигателях составляет от 1,8 градуса (200 шагов на полный оборот) до 30 градусов (12 шагов). Двухполюсные двигатели позволяют обеспечить большую плотность использования сердечников, и поэтому с ними обычно легче получить больший вращающий момент при небольших габаритах.
Сервоприводы полезны для управления всеми видами робототехники, а также для радиоуправляемых самолетов. Пожалуй, самое простое, что можно сделать с их помощью – измерить физический угол. Кроме сервопривода, понадобится только микропереключатель, подключенный к «плечу» или движущемуся рычагу сервопривода. Затем можно подвесить это к цифровому входу и проверять его в каждом цикле (или вместо этого употребить прерывания – см. предыдущую статью) чтобы увидеть, коснулся ли рычаг чего-либо, см. Схему 1.
- include <Servo.h>
Servo servo1;
int switchpin = 2;
int sensorValue = 0;
int pos = 0;
void setup()
{
servo1.attach(9,540,2350);
pinMode(switchpin, INPUT);
Serial.begin(9600);
}
void loop()
{
digitalWrite(switchpin, HIGH);
for(pos = 0; pos < 180; pos += 1)
{
servo1.write(pos);
sensorValue = digitalRead(2);
if (sensorValue == LOW ){
Serial.println(servo1.read(), DEC);
servo1.write(0);
delay(1000);
break;
}
delay(10);
}
}
Мы подключили переключатель между «землей» и выводом 2 Arduino (выводы 0 и 1 лучше не трогать: они используются для USB-интерфейса, и иногда в шаблонах, где они применяются, загрузка может происходить некорректно).
В основном цикле мы проходим по значениям угла и обновляем положение сервопривода. При каждом продвижении рычага мы проверяем, что переключатель нажат; это означает, что рычаг коснулся чего-то. Тогда мы возвращаем рычаг в нулевое положение и выходим из цикла, перед этим отправив значение угла в последовательный порт. Можно было просто вывести значение переменной pos, но чтобы немного порисоваться, мы воспользовались методом .read() объекта сервопривода.
Почему мы считываем значение цифровых переключателей при его снижении, а не повышении? Ага, вы пропустили несколько статей! Вкратце – это позволяет нам не пользоваться дополнительным резистором.
Этот метод на самом деле не определяет положение сервопривода по волшебству, а опрашивает текущее состояние сигнала, который мы отправляем, и преобразует его в угол. Существуют датчики постоянного вращения, которые по существу больше похожи на шаговые двигатели. В этих случаях ширина импульса определяет скорость их вращения.
Шаговый двигатель – удивительная вещь. Если обычный двигатель можно включить, выключить и, возможно, изменить направление, шаговый двигатель позволяет управлять своей работой во впечатляющих объемах.
|С этими большими возможностями приходит не большая ответственность, а лишь немного лишнего беспокойства. Во врезке описан один из популярных типов шагового двигателя и показан принцип его работы, но, хотя знать, как он работает, полезно, если вы не хотите углубляться в детали, то суть в следующем: двигателем управляют возбуждаемые электромагниты внутри него, которые заставляют ротор двигаться. Затем электромагниты можно возбудить в противоположном направлении, чтобы ротор продвинулся еще немного. Поэтому движение производится шагами, и в каждом шаге вы или контроллер должны управлять энергией, протекающей через электромагниты.
Для работы электромагнитных сердечников требуется несколько большая мощность, чем может предоставить плата Arduino, а зачастую и большее напряжение питания, поэтому напрямую к выводам Arduino подключать их нельзя. Когда нам нужна большая мощность, мы обращаемся к нашим кремниевым друзьям, транзисторам.
Шаговые двигатели несложно купить. Стоят они от 14 фунтов до цифр в три- четыре раза больше, это зависит от мощности, размера и типа. Но они попадаются не только в магазинах. Каждый день на помойку выбрасываются тысячи прекрасно работающих двигателей, и если вы спасете их от бесславной судьбы в виде попадания на свалку или в металлолом, эксперименты с ними доставят вам немало приятных минут.
Большинство шаговых двигателей в моей коллекции были взяты из принтеров (раньше их источником были флоппи-дисководы, но сейчас их почему-то встретишь не часто). Их также можно найти в сканерах, игрушках, старых ленточных магнитофонах и, наверное, во многих других местах, но принтеры – это идеальный источник: их часто выбрасывают или по крайней мере продают за небольшие деньги. Я видел их в благотворительных магазинах [магазины, которые торгуют подержанными товарами, а выручку отдают на благотворительные цели, – прим. пер.] и на церковных базарах по цене 1 фунт, и внутри вы найдете (по меньшей мере) один прекрасный шаговый двигатель. Двигатели обычно переживают остальные компоненты принтера – и, конечно, внутри принтера немало и других полезных электронных штучек.
Чтобы запросто отличить двигатель одного типа от другого, можно воспользоваться следующим правилом: если у двигателя четыре провода, то он двухполюсный; у однополюсных двигателей пять или шесть проводов. Но обычно можно просто проверить цепи питания или сердечников мультиметром.
Мощный транзистор легко может предоставить ток и напряжение, достаточные для питания сердечников, и на рис. 1 показана простая схема с транзистором. Диод нужен только для защиты от обратной ЭДС – двигатель может не только потреблять энергию, но и генерировать ее, а скачки тока, отправляющиеся обратно в нашу цепь, нам не нужны. Для однополюсного двигателя эту схему достаточно умножить на четыре (обычное количество схем сердечников в двигателе). Ой, а я сказал о том, что существуют различные типы двигателей? Основных типов три:
1 Относительно нераспространенный и дорогой универсальный шаговый двигатель
2 Удобный в использовании однополюсный шаговый двигатель
3 Повсеместно распостраненный и ненадежный двухполюсный шаговый двигатель.
Чем же они различаются? Все дело в проводах. В однополюсном двигателе две цепи сердечников аккуратно соединяются в центре, а значит, можно подать питание на центр и включать или выключать сердечники на каждой стороне, заземляя их.
В двухполюсном двигателе цепи сердечников отдельные, но для их питания нужно подавать напряжение в различной полярности в зависимости от шага.
Схема для управлениям ими сложнее, но в двигателе легко разместить больше сердечников, поэтому двухполюсные двигатели вероятнее всего найти в старом офисном оборудовании.
В универсальном шаговом двигателе есть провода для любых типов вигателей, и его можно подключить как однополюсный или двухполюсный двигатель. Мы сосредоточимся на двухполюсном двигателе потому, что с ним у вас с наибольшей вероятностью могут возникнуть трудности, а также потому, что скорее всего вам попадется именно такой.
Нам нужно подавать напряжение на сердечники точно также, как раньше (см. рис. 1), но как изменять его полярность? Ответ – с помощью мостовой конструкции на диодах. Если вам знакомы схемы мостовых выпрямителей в источниках питания, наша схема может показаться немного похожей, и во многом это так, не считая того, что решает она почти противоположную задачу. На рис. 2 показана распространенная схема H-моста.
Диоды гарантируют, что ток течет только туда, куда нам нужно, и защищает схему от «отдачи» двигателя, а переключение выполняется двумя транзисторами. На схеме вы видите, что входные сигналы сначала проходят через элементы «исключающее или» (XOR). Они нужны для того, чтобы обе сигнальные линии не содержали высокого уровня в один момент времени, так как это вызовет короткое замыкание и не очень понравится вашему источнику питания. Эта схема подразумевает, что для двигателя используется отдельный источник питания, и мы настоятельно рекомендуем вам сделать именно так.
Может показаться, что для работы двигателя нужно приложить слишком много дополнительных усилий, особенно когда вы понимаете, что вам на самом деле нужны две этих схемы, по одной для каждого сердечника. К счастью, мир коммерческих интегральных схем снова спасает всех нас, и на рынке можно найти множество вариантов микросхем двойного H-моста по доступным ценам.
Какая микросхема вам понадобится, зависит от типа двигателя, но популярная микросхема L293D подойдет для большинства шаговых двигателей, которые могут вам встретиться. Типичный вариант подключения приведен на схеме 2. В ней, благодаря тому факту, что несколько пар проводов одновременно находятся в состоянии «единица» или «ноль», число управляющих выводов удается сократить до двух (с помощью нескольких дополнительных транзисторов).
Что касается управления двигателем – ну, для этого опять же есть стандартная библиотека:
- include <Stepper.h>
Stepper myStepper(100, 9,10);
void setup() {
myStepper.setSpeed(10);
}
void loop() {
myStepper.step(100);
delay(500);
myStepper.step(-100);
delay(500);
}
Stepper – еще одна стандартная библиотека Arduino, которая заботится о генерации управляющих сигналов и даже умеет работать с двумя или четырьмя выводами. Число выводов задается при инициализации объекта Stepper: первый параметр – количество шагов в полном обороте, за ним идут два или четыре используемых вывода.
В методе setup задается скорость двигателя (в оборотах в минуту). Управление скоростью осуществляется отдельно от работы двигателя, но нужно об этом помнить, потому что это может привести к блокировке Arduino (то есть исполнение кода будет задержано до тех пор, пока двигатель не провернется на определенное количество шагов). Таким образом, лучше перемещаться небольшими шагами и часто, вместо того, чтобы сразу рвануть на большое количество шагов.
Метод .step() вызывает поворот ротора двигателя на заданное количество шагов вперед (или, если аргумент отрицателен, назад) с текущей скоростью. Таким образом, 100 шагов на 100-шаговом двигателе, работающем с частотой 10 оборотов в минуту, займут 6 секунд.
Вот и все, что нужно для управления двигателем. Далее в этой серии мы рассмотрим управление двумя двигателями для создания рельсовой тележки.