View Categories

Сервопривод

Сервопривод, он же сервомашинка, он же просто серво – простейший "модельный" актуатор, использовался в радиоуправляемых моделях ещё до появления Ардуино. Сервопривод поворачивает свой выходной вал в диапазоне ~180 градусов и обладает вполне приличным моментом: может поворачивать части механизмов (руль высоты самолёта, колёса машинки, подвес камеры), нажимать кнопки и так далее.

В наборе GyverKIT START IOT EXTRA
Серво

В маленьком корпусе располагаются:

  • Коллекторный моторчик
  • Редуктор (пластиковый или металлический)
  • Потенциометр обратной связи
  • Контроллер (драйвер мотора, обратная связь, управление по интерфейсу PWM)
  • Серво комплектуется набором "качалок" и винтами для крепления

Характеристики 9-граммового сервопривода:

  • Напряжение питания: 3.. 7.2V
  • Крутящий момент:
    • 1.2кг/см при 4.8V
    • 1.6кг/см при 6.0V
  • Рабочий угол: 160.. 180 градусов
  • Скорость (без нагрузки): 180 градусов за 0.3с
  • Интерфейс: PWM

Подключение к Arduino #

Провода:

  • Коричневый: GND
  • Красный: VCC
  • Жёлтый: любой цифровой пин

Сервопривод потребляет довольно приличный ток (стартовый до 1А), поэтому рекомендуется питать его от внешнего источника. При питании от компьютера напряжение может просесть и МК перезагрузится, при высокой нагрузке (с 2 и больше приводов) может выгореть защитный диод на плате Arduino!

Программирование #

Сервопривод управляется ШИМ сигналом, точнее длиной импульса: минимальная (0 градусов) и максимальная (~180 градусов) длина импульса колеблется в зависимости от модели и производителя сервопривода - обычно что то в районе 500 мкс минимум и 2500 мкс максимум. Импульсы подаются с частотой около 50 Гц:

По сути для управления серво достаточно подавать на пин сигнал с нужными интервалами, например рассмотрим вот такую схему с серво на пине D3 и потенциометром на A0:

И напишем программу, которая будет поворачивать серво вслед за потенциометром:

#define SERVO_PIN 3
#define POT_PIN 0

void setup() {
    pinMode(SERVO_PIN, OUTPUT);
}

void loop() {
    int pulse = map(analogRead(POT_PIN), 0, 1023, 500, 2500);

    digitalWrite(SERVO_PIN, HIGH);
    delayMicroseconds(pulse);
    digitalWrite(SERVO_PIN, LOW);

    delay(20);  // 50 Hz
}

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

Библиотеки #

  • Servo.h - стандартная библиотека (встроена в Arduino IDE). Работает полностью асинхронно на прерываниях и поддерживает до 12 приводов
  • SoftServo - моя библиотека, работает на миллисе. Может пригодиться, если не хочется терять Timer 1 у Arduino NANO

Servo.h #

На Arduino NANO эта библиотека использует первый таймер (Timer 1) , т.е. ШИМ на пинах 9 и 10 использовать с ней нельзя!

Подключаем и создаём объект сервопривода:

#include <Servo.h>
Servo myservo;

Библиотека имеет следующие методы:

uint8_t attach(int pin);           // "подключить" с указанием пина
uint8_t attach(int pin, int min, int max); // "подключить" с указанием пина и мин. макс. сигнала
void detach();                     // отключить
void write(int value);             // повернуть на угол в градусах
void writeMicroseconds(int value); // повернуть на длину импульса

При "подключении" серво через attach(pin) диапазон длины импульса устанавливается стандартный: 544.. 2400 мкс (задан в библиотеке). Если есть желание настроить серво идеально, чтобы она работала на весь диапазон – нужно попробовать покрутить её через writeMicroseconds(): в крайних значениях диапазона и найти минимум и максимум, при которых серво упирается.

Крутим туда сюда быстро
#include <Servo.h>
Servo myservo;

void setup() {
  myservo.attach(3);  // подключаем на пин 3
}

void loop() {
  myservo.write(0);   // поворот на 0 градусов
  delay(1000);

  myservo.write(180); // поворот на 180 градусов
  delay(1000);
}
Крутим туда сюда плавно
#include <Servo.h>
Servo myservo;

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

void loop() {
  for (int i = 0; i <= 180; i++) {
    myservo.write(i);
    delay(15);
  }
  for (int i = 180; i > 0; i--) {
    myservo.write(i);
    delay(15);
  }
}
Крутим туда сюда плавно асинхронно
#include <Servo.h>
Servo myservo;

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

uint32_t tmr;   // переменная таймера
int val = 0;    // переменная яркости
int dir = 2;    // скорость и направление яркости

void loop() {
  // асинхронный таймер на миллис
  if (millis() - tmr >= 20) {
    tmr = millis();
    val += dir;                             // прибавляем скорость
    if (val >= 180 || val <= 0) dir = -dir; // разворачиваем
    myservo.write(val);                     // применяем
  }
}

Полезные страницы #

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Прокрутить вверх