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

Программирование 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

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

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
+
0
Здравствуйте. Помогите понять почему в новой версии arduino-1.0 при компиляции выдаётся вот такая ошибка:
In file included from Proverka_pde.cpp:1:
D:\Program Files\arduino-1.0-windows\arduino-1.0\libraries\SoftwareServo
/SoftwareServo.h:4:22: error: WProgram.h: No such file or directory.


Компилировал скетч который в этой статье в последнем примере. Также выдаются такие же ошибки в скетчах, где есть обращение в сторонние библиотеки. Делаю тоже самое в arduino-0022 — всё в порядке… В чём дело? помогите пожалуйста понять.
avatar

conysSM

  • 16 марта 2012, 08:01
+
0
В Arduino IDE версии 1.0, разработчики переименовали файл WProgram.h в Arduino.h

см. Как адаптировать библиотеки для Arduino 1.0
avatar

admin

  • 16 марта 2012, 09:09
+
0
О, спасибо огромное, особенно за оперативность :)А то думал опять неделю ждать придётся, как год назад :)
avatar

conysSM

  • 16 марта 2012, 13:15
+
0
Всем привет, переделал серву для вращения по кругу (360 градусов) подредактировал скетч но она вертится не останавливаясь. если подключая непеределаную серву она поворачивается на каждые 90 градусов. Но мне нужно все 360 а не 180. подскажите что не так.
вот скетч
#include <Servo.h>
Servo myservo;

void setup()
{
// устанавливаем пин как вывод управления сервой
myservo.attach(10);
}

void loop()
{
// устанавливаем угол 0°
myservo.write(0);
delay(3000);
// устанавливаем угол 90°
myservo.write(90);
delay(3000);
// устанавливаем угол 180°
myservo.write(180);
delay(3000);
// устанавливаем угол 270°
myservo.write(270);
delay(3000);
}
avatar

aleksasm

  • 20 ноября 2015, 11:53
+
0
ИМХО всё именно так как должно быть.
Серву, простыми средствами, не заставить поворачиваться более чем на 180.
Про устройство — тут.
только если потенциометр обратной связи менять на многооборотный но тогда точность станет невысокой.
Не могу знать как переделывали именно вы, но обычно сервы переделывают не столько на «360», сколько на «постоянное вращение» — см подробности.
avatar

Zoltberg

  • 20 ноября 2015, 12:10
+
0
Я убрал фиксатор, вместо потенциометра подпаял 2 резистора по 3,3к. значит невозможно сделать чтобы она останавливалась через каждые 90?
avatar

aleksasm

  • 20 ноября 2015, 12:25
+
0
Так невозможно — вы же вытащили потенциометр серва теперь ничего не знает о своём текущем положении.
Таки почитайте.
avatar

Zoltberg

  • 22 ноября 2015, 11:28
+
0
Спасибо, будем довольствоваться поворотом на 180. Попробую шаговый движок прикрутить для своих нужд.
avatar

aleksasm

  • 23 ноября 2015, 16:03

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