• - это CraftDuino - наш вариант полностью Arduino-совместимой платы.
  • CraftDuino - настоящий конструктор, для очень быстрого прототипирования и реализации идей.
  • Любая возможность автоматизировать что-то с лёгкостью реализуется с CraftDuino!
Просто добавьте CraftDuino!
подписаться на RSS-ленту

Программирование Arduino - библиотека Servo.

Servo library – библиотека для работы с сервомашинками

Как мы помним – сервомашинка – это мотор-редуктор, с обратной связью, благодаря которой можно повернуть выходной вал на строго определённый угол.
Стандартные рулевые машинки, вертятся от 0 до 180 градусов (также есть сервы постоянного вращения – т.н. Continuous Rotation Servo, чуть позже покажем, как обычную серву можно переделать до такого состояния).

Примечание:
В Arduino IDE 0017 библиотека Servo поддерживает до 12 серв (до 48 на Mega), а в IDE 0016 и ранее работает только на 9 и 10 пинах!

! Обратите внимание:
На платах, отличных от Mega, использование библиотеки отключает возможность использования analogWrite() (PWM) на пинах 9 и 10 (вне зависимости подключены к этим пинам сервы или нет). На платах Mega, до 12 серв могут использоваться без влияния на функциональность PWM, но использование от 12 до 23 сервомашинок отключит PWM на пинах 11 и 12.

Подключение
Схема включения сервомашики очень простая — у неё есть три провода:

— земля (коричневый/черный),
— питание +5 вольт (красный),
— сигнальный (оранжевый/желтый/белый).
Управляющий сигнал можно подавать напрямую с ноги МК, а вот силовое питание (особенно если задействовано более одной-двух серв) нужно подавать от внешнего источника питания (т.е. не от +5В Arduino). В этом случае – нужно не забыть соединить землю Arduino/CraftDuino с минусом внешнего источника питания.

Рассмотрим функции, которые предоставляет библиотека.

uint8_t attach(int pin);
uint8_t attach(int pin, int min, int max);


Описание:
Указываем пин к которому подключён управляющий провод сервы.

Примечание:
Версии Arduino IDE 0016 и младше позволяют подключение только к 9 и 10 пинам.

Синтаксис:
servo.attach(pin); 
servo.attach(pin, min, max);


Параметры:
(servo – объект класса Servo)
pin – номер порта к которому подключена серва

min (опционально) – ширина импульса в микросекундах устанавливающая положение вала сервы в 0 градусов (по-умолчанию 544)

max (опционально) — ширина импульса в микросекундах устанавливающая положение вала сервы в 180 градусов (по-умолчанию 2400)

Пример:
#include <Servo.h> 

Servo myservo;

void setup() 
{ 
  myservo.attach(9);
} 

void loop() {}


void write(int value);

Описание:
Устанавливаем угол поворота сервы в градусах.
В случае сервы постоянного вращения:
0 – вращение на полной скорости в одну сторону,
180 – вращение на полной скорости в другую сторону,
90 – нет вращения.

Синтаксис:
servo.write(angle);


Параметры:
angle – значение угла для поворота: от 0 до 180

Пример:
#include <Servo.h> 

Servo myservo;

void setup() 
{ 
  myservo.attach(9);
  myservo.write(90);  // поворачиваем серву на 90 градусов
} 

void loop() {}


void writeMicroseconds(int value);

Описание:
Задаёт значение в микросекундах для длительности управляющего импульса. На стандартных сервах это приведёт к повороту вала на определённый угол ( 1000 — положение полностью против часовой стрелки, 2000 — положение полностью по часовой стрелке, и 1500 — в середине).
Примечание:
Знечения могут быть разными на сервах разных производителей. Например, от 700 до 2300. Это можно определить экспериментально – увеличивая значения, пока серва продолжает поворачиваться. Обратите внимание, что попытки управления сервой вне её конечных точек (при этом появляется рычащий звук) приводит к увеличению потребления тока и такого следует избегать.

Синтаксис:
servo.writeMicroseconds(uS);


Параметры:
uS – значение ширины импульса в микросекундах (int)

Пример:
#include <Servo.h> 

Servo myservo;

void setup() 
{ 
  myservo.attach(9);
  myservo.writeMicroseconds(1500);  // в среднее положение
} 

void loop() {}


int read();

Описание:
Считывает «текущий» угол поворота сервомашинки (значение, переданное в последнем вызове write()).

Синтаксис:
servo.read();


Возвращаемое значение:
Возвращает значение типа int — угол от 0 до 180 градусов.

Примечание:
Аналогично есть функция readMicroseconds();

bool attached();

Описание:
Определяем – есть ли привязка к серве через pin.

Синтаксис:
servo.attached();


Возвращаемое значение:
Возвращает true если есть привязка к pin-у и false – в противном случае.

void detach();

Описание:
Отключение пина от библиотеки Servo. Если все переменные Servo отключены – пины 9 и 10 можно использовать для PWM-вывода через analogWrite().

Синтаксис:
servo.detach();


Возвращаемое значение:
нет.

Рассмотрим пример работы библиотеки на примере Sweep, который поворачивает серву от 0 до 180 градусов и обратно (как-бы подметает).
File – Examples — Servo — Sweep
// Sweep
// by BARRAGAN <http://barraganstudio.com> 

#include <Servo.h> 
 
Servo myservo;  // создаём объект для контроля сервы 

int pos = 0;    // переменная для хранения позиции сервы 
 
void setup() 
{ 
  myservo.attach(9);  // серва подключена к 9-му пину
} 
 
 
void loop() 
{ 
  for(pos = 0; pos < 180; pos += 1)  // от 0 до 180 градусов
  {                                  // с шагом в 1 градус 
    myservo.write(pos);              // 
    delay(15);                       // ждём 15ms пока серва займёт новое положение
  } 
  for(pos = 180; pos>=1; pos-=1)     // от 180 до 0 градусов
  {                                
    myservo.write(pos);               
    delay(15);                       
  } 
}


Существуют и другие библиотеки:
SoftwareServo — www.arduino.cc/playground/ComponentLib/Servo — удобна одинаковым названием функций с системной библиотекой Servo
— она не ограничивает количество серв 8-ю, но требует для работы вызова метода
SoftwareServo::refresh()

Пример:
#include <SoftwareServo.h> 

SoftwareServo myservo; // объект сервы

int potpin = 0;  // пин для подключения потенциометра
int val;    	// переменная для хранения значения с аналогового входа

void setup() 
{ 
  myservo.attach(2);  // серва подключена ко 2-му пину
} 

void loop() 
{ 
  val = analogRead(potpin);            // считываем значение с потенциометра (величина от 0 до 1023) 
  val = map(val, 0, 1023, 0, 179);     // переводим в значение от 0 до 180) 
  myservo.write(val);                  // устанавливаем угол сервы 
  delay(15);                           // ждём поворота 

  SoftwareServo::refresh();
}

MegaServo — www.arduino.cc/playground/Code/MegaServo
— библиотека для более ранних версий IDE (в 0017 не подгрузится, т.к. она уже входит в состав IDE под именем Servo :) — позволяет контролировать до 12 серв

Читать про сервы:
Сервы
Сервы 2. Взгляд под корпус.
Подключение сервомашинок к Arduino

Cсылки:
arduino.cc/en/Reference/Servo
  • 0
  • 29 мая 2010, 12:49
  • admin

Комментарии (10)

RSS свернуть / развернуть
+
+1
Спасибо, как раз кстати…
У меня тут пара проектов с Arduino а толковой информации моло. :)
avatar

Dan_ex

  • 2 июня 2010, 16:46
+
0
«Continuous Rotation Servo» — да, да! Очень интересно! Особенно если можно сделать скорость вращения 1 оборот в 20 — 40 секунд!
avatar

aryeh

  • 16 июня 2010, 01:41
+
0
Стандартные рулевые машинки, вертятся от 0 до 180 градусов (также есть сервы постоянного вращения – т.н. Continuous Rotation Servo, чуть позже покажем, как обычную серву можно переделать до такого состояния
Очень нужно чтоб сервушка крутилась на 360гр. Порылся по моему у вас везде где можно, но не нашёл как это сделать. Подобное в сети очень много но не где не описывается как потом управлять такой переделанной сервой, и тем более с помощью CraftDuino. Если эта статья есть у вас уже на сайте подскажите где её искать. Заранее благодарен.
avatar

conysSM

  • 31 января 2011, 10:52
+
0
Тут кто-то обещал написать про Сервы постоянного вращения / Continuous Rotation Servo. ;)
avatar

lfway

  • 24 мая 2011, 11:45
+
0
avatar

lfway

  • 24 мая 2011, 11:51
+
0
собираю многоножку на tower pro 946, у нее граничными значениями оказались 800 и 2200 мс, угол поворота — 60 градусов
avatar

xtile

  • 8 июня 2011, 22:49
+
0
Как подключить к arduino UNO 3 сервы? Обязательно покупать motor shield или что-то подобное? Нельзя ли напрямую?
avatar

nes

  • 11 октября 2011, 14:15
+
+1
разумеется, можно — Подключение сервомашинок к Arduino:
если сервы мощные, то стабилизатор питания контроллера будет очень сильно греться и может сгореть.
Выход — использовать для питания сервомашинки отдельный регулятор напряжения (L7805, КР142ЕН5А и т.п.)
avatar

noonv

  • 11 октября 2011, 14:37
+
0
Вроде бы понял, поправьте меня, если неправильно.

То есть, теоретически, к Uno можно подключить 14 (маломощных) серво, создать для них объекты:
Servo servo0;
Servo servo1;
...
Servo servo13;

потом назначить им порты:
servo0.attach(0);
servo1.attach(1);
...
servo13.attach(13);

и управлять ими с помощью:
servo0.write(foo);
servo1.write(foo);
...
servo13.write(foo);
avatar

nes

  • 11 октября 2011, 14:58
+
0
Вроде бы понял, поправьте меня, если неправильно.

То есть, теоретически, к Uno можно подключить 14 (маломощных) серво, создать для них объекты:
в UNO установлен контроллер ATmega8U2(ATmega328), а в библиотеке Servo имеется код:
// Say which 16 bit timers can be used and in what order
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define _useTimer5
#define _useTimer1 
#define _useTimer3
#define _useTimer4 
typedef enum { _timer5, _timer1, _timer3, _timer4, _Nbr_16timers } timer16_Sequence_t ;

#elif defined(__AVR_ATmega32U4__)  
#define _useTimer3
#define _useTimer1 
typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t ;

#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
#define _useTimer3
#define _useTimer1
typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t ;

#elif defined(__AVR_ATmega128__) ||defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__)
#define _useTimer3
#define _useTimer1
typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t ;

#else  // everything else
#define _useTimer1
typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t ;                  
#endif

Согласно которому распределяется порядок подключения и количество таймеров в зависимости от модели контроллера, в списке IF-ов нет используемого в UNO контроллера, следовательно применяется ELSE, согласно которому будет задействован 1 таймер — №1. Далее по коду можно обнаружить следующий код:
#define SERVOS_PER_TIMER       12     // the maximum number of servos controlled by one timer 
#define MAX_SERVOS   (_Nbr_16timers  * SERVOS_PER_TIMER)

говорящий что максимальное количество сервов определяется как произведения количества возможный таймеров на константу определяющую максимальное число сервоприводов на один таймер, равную 12 по всей видимости, стантартными приемами используя UNO и библиотеку servo можно включить 12 сервоприводов.
avatar

execom

  • 10 декабря 2011, 21:49

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.