Thursday, December 15, 2011

Шевелите сервами

Сервопривод 
Сервопривод (серва, сервомашинка, рулевая машинка и т.д.) - это электромоторчик с редуктором и управляющим блоком. Главная идея в том, что эта штука может устанавливать вал в определенном положении и удерживать его в этом положении. Если кто-либо или что-либо изменит это угол - сервопривод будет пытаться все равно вернуть его в заданное положение, т.е. будет "сопротивляться". Стоит сразу отметить (об этом никто не пишет, т.к. подразумевают, что это само-собой разумеющееся, однако для меня это было не столь уж очевидно) - сервопривод может вращаться только на определенный угол в каждую сторону, он не может сделать оборот вала в 360 градусов (!). Также не стоит путать сервы и шаговые моторы - это разные вещи, управляются они по разному и сразу скажу - я не знаю как управлять шаговыми моторами. Пока что не знаю 

В конце статьи я покажу как это выглядит на видео.

Дьявол таиться в деталях
Разберемся более конкретно в деталях сервопривода:
Редуктор - просто набор соединенных между собой шестеренок. Отвечает за то, чтобы преобразовать высокую скорость вращения мотора в силу, которую он сможет приложить на выходе. Тут все достаточно просто - электромоторчики вращаются очень быстро, но усилие на валу очень маленькое. Фактически вал запросто можно остановить пальцами (я не про все электромоторы сейчас говорю, а про маленькие и слабые которые используется в игрушках и прочей мелочевке). А редуктор позволяет увеличить эту силу, но вал будет вращаться существенно медленнее.
Управляющий блок - маленькая плата находящаяся в корпусе сервопривода. Занимается обработкой внешнего сигнала, а также сигнала зависящего от потенциометра (переменного резистора) и управляющая моторчиком. 
Логика сервопривода следующая (во всяком случае так её понимаю я):
  1. По проводу сигнала, из вне, приходит импульс определенной продолжительности. Этот импульс может быть отправлен микроконтроллером, например. К примеру, импульс продолжительностью 1000 микросекунд будет соответствовать углу в 0 градусов, а 2000 микросекунд - 180 градусов. Все промежуточные значения - каким-то промежуточный углам.
  2. Микросхема принимает этот сигнал и сравнивает его с сигналом приходящим с потенциометра. Если сигналы не соотстетствует одному и тому же углу, то микросхема подает напряжение на электромоторчик с той полярностью, которая позволит повернуть вал в нужную сторону. 
  3. Как только вал будет установлен в нужное положение, микросхема отключит питание от мотора до тех пор, пока его не надо будет включить снова. 

Такой алгоритм бесконечно повторяется. Если сигнал на линии пропадает - серва "отключается", т.е. она не будет уже сопротивляться изменению положения вала.

Где раздобыть сервоприводы?
Вообще они продаются в магазинах для моделистов. Лично в моем городе и магазинов таких раз два и обчелся, и цены там за сервоприводы кусаются (от 10$ штука). Лично я выбрал как наиболее приемлемый для себя способ добычи серв - это заказ их с известного ebay.com. Там полно китайских поставщиков этого барахла готовых отправить свой товар в любую точку земного шара.
Я взял себе для опытов микро сервы. Они очень маленькие и самые дешевые. Надеяться, что они будут обладать хорошими характеристиками не приходится, но мои меня вполне устраивают. За четыре штуки я отдал 10$, что в принципе не дорого. Доставки ждал около месяца.
Ну, с теорией я надеюсь хоть немного помог разобраться. Давайте уже делом займемся.

Схема
Для сборки схемы я буду использовать:
1. Макетную плату. Заказывал на ebay, с доставкой обошлась мне в 4$.
2. Контактную гребенку. Покупается эта штука в магазине радиотоваров. Вообще она для запайки на плату, но мы её будем использовать несколько другим способом. 
3. Провода. Лично я для целей макетирования использую провода из обычного ethernet кабеля. У меня моток этого провода остался после прокладывания дома сети. Из плюсов: стоит копейки, его удобно запихивать в дырки в макетной плате, достаточно легко снимается изоляция, метр ethernet кабеля в себе будет содержать 8-мь метров одножильных проводков. Понадобится его не так много.
4. Arduino Mega 2560 - про нее я уже писал, повторяться не буду. Будем генерировать с нее те самые управляющие сигналы.
5. Собственно сам сервопривод. 


Собираем
Обеспечим себе удобство. Для этого отломаем от гребенки три штырька, чтобы получилось что-то вроде:
Для чего это делается? Дело в том, что наша макетная плата нашпигована дырками, а сервопривод обладает разъемом типа "мама". Мы будем использовать эту штуку, чтобы закрепить разъем сервопривода на макетной плате, для более удобной работы. 
Есть с этими штырьками одна хитрость - они не симметричны - с одной стороны они выступают чуть больше над пластмассой, чем с другой. Нам это не подходит, так как при таких условиях разъем будет закреплен уж слишком хлипко. Но есть выход, возьмем эту гребенку и воткнем короткой стороной в наш разъем сервопривода. 
Потом этим разъемом слегка "продавим" пластмаску, которая скрепляет штырьки. Таким способом можно сместить её чуть ниже. Надо сделать так, чтобы она оказалась приблизительно по центру. 
Дальше вставляем получившийся разъем в макетную плату. 
Теперь соединим проводками нашу Arduino и наш сервопривод. На данном этапе Arduino должна быть обесточена.
  • GND Arduino подключаем к черному/коричневому проводу нашего сервопривода;
  • +5V Arduino подключаем к красному проводу сервопривода;
  • 9-й контакт Arduino к оставшемуся желтому проводу. 

На картинке не совсем видно что с чем соединено, но я честно все сделал как описал выше. На самом деле - мы уже все сделали. Осталось только загрузить в Arduino программу (прошивку) которая будет что-то делать. Я не буду пытаться изобретать велосипед, а возьму готовую программку из примеров, поставляемых вместе с Arduino IDE. Найти его можно по следующему пути: File - Examples - Servo - Sweep
#include <Servo.h> 
 
Servo myservo;  
                
 
int pos = 0;    
 
void setup() 
{ 
  myservo.attach(9);  
} 
 
 
void loop() 
{ 
  for(pos = 0; pos < 180; pos += 1)  
  {                                 
    myservo.write(pos);             
    delay(15);                      
  } 
  for(pos = 180; pos>=1; pos-=1)     
  {
    myservo.write(pos);
    delay(15);
  } 
} 

Код совсем простенький и в особых разъяснениях, на мой взгляд, не нуждается. Результат вы можете увидеть на видео.