Как работает сервопривод и подключение к Arduino
Когда дело доходит до выбора подходящего двигателя для проекта, вариантов может быть множество — шаговые двигатели, двигатели постоянного тока, бесщёточные двигатели и многие другие. У каждого типа свои преимущества. Но если вам нужно точное управление движением, есть один очевидный выбор: сервопривод. Укажите сервоприводу, куда повернуться, и он повернётся именно туда! Всё просто!
Сервоприводы впервые стали популярными в мире радиоуправления (RC), где они использовались для управления рулевым механизмом RC-автомобилей или закрылками RC-самолётов. Со временем они нашли применение в робототехнике, автоматизации и, конечно же, в мире Arduino.
В этом руководстве вы узнаете, как работает сервопривод, как подключить его к Arduino и как управлять его положением с помощью простого кода Arduino. Независимо от того, собираете ли вы роботизированную руку, автоматическую дверь или просто экспериментируете с управлением движением, это руководство поможет вам начать.
Давайте приступим и заставим сервопривод двигаться!
Что такое сервопривод и что делает его точным?
Внутри типичного хобби-сервопривода вы найдёте пять основных компонентов, работающих вместе: двигатель постоянного тока, редуктор, качалку сервопривода, потенциометр и блок управления.
Двигатель постоянного тока: Это основной компонент, обеспечивающий вращающее усилие. Он похож на моторчики, которые можно найти в игрушках, но вся разница в том, как им управляют. Двигатель постоянного тока соединён с выходным валом через серию шестерён.
Редуктор: Редуктор (система шестерён) играет ключевую роль в увеличении крутящего момента двигателя и повышении точности его движений. Он снижает скорость двигателя, но увеличивает его силу.
Качалка сервопривода: Это пластиковый рычаг (или колесо), прикреплённый к выходному валу (части, которая фактически вращается). Качалка позволяет прикрепить к сервоприводу то, что вы хотите двигать — например, руку робота или руль модели самолёта.
Потенциометр: Это переменный резистор, выступающий в роли датчика положения. Он соединён непосредственно с выходным валом. При вращении выходного вала сопротивление потенциометра изменяется. Это сообщает блоку управления точное положение двигателя.
Блок управления: Это «мозг» сервопривода. Он получает сигналы от внешнего контроллера (например, Arduino), проверяет положение потенциометра и управляет двигателем постоянного тока.
Как эти компоненты работают вместе:
Сервопривод работает с использованием так называемой «системы обратной связи с замкнутым контуром».
Когда вы отправляете сервоприводу сигнал с указанием переместиться в определённое положение, блок управления получает эту команду.
Потенциометр физически соединён с выходным валом, поэтому он всегда знает текущее положение сервопривода. Когда двигатель вращается, выходной вал поворачивается, а вместе с ним и потенциометр. Это вращение изменяет сопротивление потенциометра, создавая напряжение, которое напрямую соответствует текущему положению выходного вала (и, следовательно, двигателя). Это напряжение служит обратной связью для блока управления.
Блок управления постоянно сравнивает это напряжение обратной связи (представляющее текущее положение двигателя) с сигналом желаемого положения от микроконтроллера.
Если есть разница (сигнал «ошибки») между желаемым и текущим положением, блок управления регулирует мощность и направление двигателя постоянного тока для устранения этой разницы.
По мере движения двигателя напряжение обратной связи потенциометра изменяется, непрерывно обновляя информацию о текущем положении двигателя для блока управления.
Как только двигатель достигает желаемого положения, сигнал ошибки становится нулевым, и блок управления останавливает двигатель.
Весь этот процесс происходит очень быстро и многократно. Сервопривод постоянно проверяет своё положение и вносит мельчайшие корректировки, чтобы оставаться именно там, где должен. Именно поэтому сервоприводы так хорошо удерживают своё положение даже при воздействии внешних сил.
Вся эта система называется «сервомеханизмом» или просто «серво». Она работает как система управления с замкнутым контуром, используя отрицательную обратную связь для точного управления скоростью и направлением двигателя, позволяя ему достигать и удерживать определённое положение.
Как работают сервоприводы?
Хобби-сервоприводы управляются с помощью метода, называемого широтно-импульсной модуляцией (ШИМ, PWM).
ШИМ работает путём отправки серии электрических импульсов на сервопривод через регулярные интервалы. Для большинства хобби-сервоприводов импульсы отправляются примерно 50 раз в секунду (50 Гц). Это означает, что новый импульс приходит каждые 20 мс (1/50 секунды).
Для управления положением сервопривода важна не частота отправки импульсов, а длительность каждого импульса. Эта длительность называется «шириной импульса» (или «коэффициентом заполнения» ШИМ-сигнала, если предпочитаете технический термин).
Короткий импульс около 1 мс или менее указывает сервоприводу переместиться на 0 градусов (полностью в одну сторону)
Средний импульс около 1,5 мс устанавливает сервопривод на 90 градусов (точно посередине)
Более длинный импульс около 2 мс перемещает сервопривод на 180 градусов (полностью в другую сторону)
Для промежуточных положений используются значения ширины импульса между этими значениями. Например, для положения 45 градусов (на полпути между 0 и 90 градусами) используется импульс длительностью около 1,25 мс.
Это означает, что мы можем точно управлять положением сервопривода, тщательно контролируя длительность каждого импульса. Блок управления сервопривода получает эти импульсы, измеряет их ширину и перемещает двигатель в соответствующее положение.
Анимация ниже поможет визуализировать, как изменения ширины импульса соответствуют различным положениям сервопривода.
Не все сервоприводы одинаковы
Важно отметить, что точный диапазон ширины импульса может немного различаться у разных моделей сервоприводов. Некоторые сервоприводы могут использовать диапазон, например, 0,5 мс для 0 градусов и 2,5 мс для 180 градусов.
Поэтому всегда полезно проверить техническое описание, прилагаемое к вашему конкретному сервоприводу. Техническое описание точно укажет, какие значения ширины импульса использовать для различных положений вашего конкретного сервопривода.
Распиновка сервопривода
Почти все хобби-сервоприводы поставляются со стандартным трёхконтактным разъёмом с шагом 0,1 дюйма. Хотя цветовая маркировка проводов может различаться у разных производителей, выводы обычно расположены в одном порядке.
Вот описание распиновки:
GND — это вывод заземления.
Вывод 5V обеспечивает питание сервопривода. Большинству хобби-сервоприводов для правильной работы требуется напряжение от 4,8 до 6 В. Подача правильного напряжения важна — слишком мало, и у сервопривода не хватит силы, слишком много, и вы можете его повредить.
Вывод Control (управление) принимает ШИМ-сигнал (широтно-импульсная модуляция) от микроконтроллера, который определяет положение сервопривода.
Цветовая маркировка проводов может различаться у разных производителей, но провод питания почти всегда красный, что позволяет легко его идентифицировать. Провод заземления обычно чёрный или коричневый, а провод управления — оранжевый, жёлтый или белый.
Подключение сервопривода к Arduino UNO
Отлично! Давайте подключим сервопривод к Arduino UNO и посмотрим, как он работает.
Для этого эксперимента мы будем использовать микро-сервопривод SG90. Этот маленький, но мощный двигатель работает от 5 В (может работать при напряжении от 4,8 до 6 В постоянного тока) и может вращаться до 180 градусов — по 90 градусов в каждом направлении.
Важно отметить, что в состоянии покоя сервопривод потребляет всего около 10 мА тока. Но при движении ему требуется гораздо больше — от 100 до 250 мА. Это означает, что для большинства простых проектов мы можем питать сервопривод непосредственно от вывода 5V Arduino. Но если вашему сервоприводу требуется более 250 мА, следует использовать отдельный источник питания, чтобы не повредить Arduino.
Для подключения сервопривода SG90 к Arduino:
Подключите красный провод к выводу 5V Arduino.
Подключите чёрный или коричневый провод к выводу GND.
Подключите оранжевый или жёлтый провод к выводу #9 Arduino. Этот вывод поддерживает ШИМ, что означает, что он может отправлять сигнал широтно-импульсной модуляции, необходимый для управления движением сервопривода.
Вот краткая таблица подключений:
| Servo Motor | Arduino | |
| 5V | 5V | |
| GND | GND | |
| Control | 9 |
Пожалуйста, обратитесь к изображению ниже для правильной схемы подключения.
Когда всё подключено, вы готовы управлять сервоприводом с помощью кода Arduino!
Пример Arduino 1 — Sweep (развёртка)
Давайте начнём с одного из встроенных примеров Arduino IDE. Откройте меню примеров, перейдите в раздел Servo и выберите скетч Sweep.
После загрузки кода загрузите его на плату Arduino. Если всё настроено правильно, вы увидите, как вал сервопривода плавно движется вперёд-назад на 180 градусов.
#include <Servo.h>
int servoPin = 9;
Servo servo;
int angle = 0; // servo position in degrees
void setup() {
servo.attach(servoPin);
}
void loop() {
// scan from 0 to 180 degrees
for (angle = 0; angle < 180; angle++) {
servo.write(angle);
delay(15);
}
// now scan back from 180 to 0 degrees
for (angle = 180; angle > 0; angle--) {
servo.write(angle);
delay(15);
}
}
Объяснение кода:
Управление сервоприводом на самом деле довольно просто благодаря библиотеке Servo, которая поставляется с Arduino. Эта библиотека предоставляет простые команды, чтобы указать сервоприводу, куда именно мы хотим его переместить.
Первое, что мы делаем в скетче — подключаем эту библиотеку Servo.
#include <Servo.h>
Далее нам нужно указать Arduino, к какому выводу подключён наш сервопривод.
int servoPin = 9;
Затем мы создаём объект servo, который будем использовать для управления двигателем.
Servo servo;
Вы можете управлять до восьми сервоприводов таким способом. Если бы у вас было два сервопривода, вы бы написали:
Servo servo1;
Servo servo2;
Нам также нужна переменная angle для отслеживания текущего положения сервопривода.
int angle = 0;
В функции setup() мы подключаем объект servo к выбранному ранее выводу. Это указывает Arduino, какой вывод должен отправлять сигналы сервоприводу.
servo.attach(servoPin);
Теперь в функции loop() мы сначала перемещаем сервопривод от 0 до 180 градусов. Мы используем цикл for, который увеличивает угол на один градус за раз. При каждой итерации цикла команда servo.write(angle); перемещает сервопривод в новое положение. Для плавности мы добавляем небольшую паузу в 15 миллисекунд после каждого перемещения.
// scan from 0 to 180 degrees
for (angle = 0; angle < 180; angle++) {
servo.write(angle);
delay(15);
}
Когда сервопривод достигает 180 градусов, мы заставляем его вернуться к 0 градусам. Мы делаем это с помощью другого цикла for, который уменьшает угол на один градус до возврата к 0.
// now scan back from 180 to 0 degrees
for (angle = 180; angle > 0; angle--) {
servo.write(angle);
delay(15);
}
После достижения 0 градусов весь процесс начинается заново. Это заставляет сервопривод непрерывно качаться между 0 и 180 градусами.
Этот пример — отличный способ увидеть, как можно управлять сервоприводом простыми командами. Освоив его, вы сможете изменять код, чтобы заставить сервопривод делать разные вещи, например, останавливаться на определённых углах или двигаться с разной скоростью.
Пример Arduino 2 — Управление сервоприводом с помощью потенциометра
Теперь, когда мы увидели, как заставить сервопривод автоматически двигаться туда-сюда, давайте пойдём дальше, добавив потенциометр. Это позволит нам вручную управлять положением сервопривода, просто поворачивая ручку. Такая конфигурация полезна во многих реальных применениях, например, для регулировки направления датчика или управления движением роботизированной руки.
Схема подключения
Мы сохраняем большинство подключений из предыдущего примера, но теперь добавляем потенциометр на 10 кОм. Потенциометр имеет три вывода. Один вывод подключается к GND (земле), другой — к 5V, а средний вывод (также называемый движком) — к аналоговому входу A0 Arduino. Эта конфигурация позволяет Arduino считывать степень поворота ручки и соответствующим образом регулировать сервопривод.
Код Arduino
Этот код на самом деле проще, чем пример Sweep, над которым мы работали ранее.
#include <Servo.h>
int potPin = 0;
int servoPin = 9;
Servo servo;
void setup() {
servo.attach(servoPin);
}
void loop() {
int reading = analogRead(potPin);
int angle = map(reading, 0, 1023, 0, 180);
servo.write(angle);
}
Объяснение кода
Сначала мы создаём новую переменную potPin, которая представляет аналоговый вывод (A0), к которому подключён потенциометр. Это позволяет нам считывать положение ручки.
int potPin = 0;
Теперь внутри функции loop() первое, что мы делаем — считываем текущее положение потенциометра с помощью функции analogRead(). Эта функция возвращает значение от 0 до 1023, в зависимости от степени поворота потенциометра. Когда ручка повёрнута полностью влево, значение будет 0. Когда полностью вправо — 1023.
int reading = analogRead(potPin);
Поскольку наш сервопривод может двигаться только от 0 до 180 градусов, нам нужно преобразовать показание потенциометра в соответствующий угол сервопривода. Здесь пригодится функция map(). Функция map() берёт число из одного диапазона и преобразует его в другой. В данном случае мы преобразуем диапазон 0-1023 в 0-180, чтобы сервопривод двигался по всему диапазону при повороте потенциометра.
int angle = map(reading, 0, 1023, 0, 180);
После преобразования значения мы используем функцию servo.write(), чтобы указать сервоприводу переместиться на вычисленный угол. Это означает, что при повороте потенциометра сервопривод будет следовать за ним, плавно поворачиваясь в соответствии с положением ручки.
servo.write(angle);
Устранение неполадок
Вы когда-нибудь замечали, что ваш сервопривод ведёт себя странно при подключении к Arduino? Иногда он может дёргаться, двигаться неправильно или даже вызывать перезагрузку Arduino. Не волнуйтесь! Это на самом деле очень распространённая проблема, с которой сталкиваются многие, и есть простые способы её решения.
Основная причина в том, что сервоприводы потребляют много энергии. Когда сервопривод начинает двигаться, ему может внезапно потребоваться до 800 мА тока. Это очень много — намного больше, чем Arduino может обеспечить сразу. Когда сервопривод пытается потребить столько энергии, это может вызвать временное падение напряжения, из-за чего всё начинает работать странно.
Есть два хороших способа решить эту проблему.
Решение 1: Добавить развязывающий конденсатор
Первое решение — добавить «развязывающий конденсатор» в вашу схему. Вам понадобится электролитический конденсатор ёмкостью от 470 мкФ до 1000 мкФ. При подключении убедитесь, что длинная ножка подключена к питанию 5V, а короткая — к GND.
Конденсатор работает, накапливая дополнительную электроэнергию, когда она не нужна, и быстро отдавая её, когда сервопривод внезапно требует больше мощности. Представьте его как маленький резервный аккумулятор, который помогает в те моменты, когда сервоприводу нужен дополнительный заряд энергии. Это помогает предотвратить падения напряжения, вызывающие проблемы.
Решение 2: Использовать отдельный источник питания
Если добавление конденсатора не полностью решает проблему, вы можете попробовать второе решение — использовать отдельный источник питания специально для сервопривода. Это особенно полезно, если сервопривод требует больше мощности, чем может обеспечить Arduino, или если вы используете несколько сервоприводов одновременно.
Для отдельного источника питания можно использовать блок из 4 батареек AA, стабилизированный сетевой адаптер 5V или даже USB-повербанк с выходом 5V. Важно, чтобы этот источник питания мог обеспечить высокие потребности сервопривода в мощности.
Для правильного подключения подключите красный провод сервопривода (питание) к положительному выводу внешнего источника питания. Затем подключите чёрный или коричневый провод (земля) к отрицательному или заземляющему выводу источника питания. Жёлтый или оранжевый провод сервопривода (сигнальный) должен по-прежнему быть подключён к одному из цифровых ШИМ-выводов Arduino, например выводу 9, потому что Arduino должен отправлять управляющие сигналы сервоприводу.
Есть один очень важный шаг, который нельзя забывать: вы должны соединить землю (GND) внешнего источника питания с землёй (GND) Arduino. Это создаёт «общую точку отсчёта» между двумя цепями, что необходимо для правильной совместной работы.
При такой конфигурации Arduino по-прежнему управляет сервоприводом, отправляя сигналы через сигнальный вывод, но больше не должен обеспечивать питание для движения сервопривода. Внешний источник питания берёт на себя все высокие потребности в мощности, позволяя сервоприводу работать плавно без проблем для Arduino.
Дальнейшее развитие
Иногда для проекта требуется подключить несколько сервоприводов к Arduino. Однако прямое подключение множества сервоприводов к Arduino имеет свои ограничения. Во-первых, у вас быстро закончатся доступные ШИМ-выводы на Arduino, особенно если ваш проект включает другие компоненты, также требующие ШИМ-управления. Во-вторых, генерация точных ШИМ-сигналов для сервоприводов может потреблять часть вычислительных ресурсов Arduino. Лучшее решение — использовать отдельную плату драйвера сервоприводов, например модуль PCA9685. Специальное руководство по PCA9685 вы найдёте ниже.