Компонент · Драйвер

Драйвер сервоприводов PCA9685

PCA9685 управляет 16 сервоприводами или выходами PWM по I²C через два вывода — решение для роботизированной руки без нагрузки на таймеры.

Что это такое

PCA9685 — расширитель PWM для сервоприводов. У микроконтроллера лишь несколько аппаратных каналов PWM, поэтому управление шестью сервоприводами роботизированной руки, не говоря о восемнадцати сервоприводах гексапода, быстро исчерпывает выводы и таймеры. Эта небольшая плата берёт задачу на себя: она формирует 16 независимых сигналов PWM аппаратно, а всеми ими управляет по двум проводам I²C. За ней стоит большинство роботов с несколькими сервоприводами.

Подписанная схема 16-канальной платы драйвера PWM/сервоприводов PCA9685: сверху в чёрном корпусе расположен ряд из шестнадцати трёхвыводных разъёмов для сервоприводов (PWM, V+, GND), в центре микросхема PCA9685 и пассивные элементы, слева пятивыводный разъём управления I²C (OE, SCL, SDA, GND, VCC), перемычки выбора адреса и справа винтовая клемма V+ для питания сервоприводов.
Шестнадцать аппаратных каналов PWM под управлением по двум выводам I²C; ток сервоприводов поступает через отдельную клемму V+, а не от микроконтроллера. Скачать SVG

Как это работает

С PCA9685 общаются по I²C — те же два вывода SCL/SDA могут одновременно обслуживать другие датчики. Для всей микросхемы задаётся одна частота PWM (50 Hz для хобби-сервоприводов), затем каждому каналу назначается ширина импульса для позиционирования сервопривода. Поскольку микросхема хранит все 16 сигналов аппаратно, микроконтроллер лишь отправляет «канал 3 → 1.5 ms» и продолжает работу; ему не требуется формивать временные интервалы программно. Поэтому каждый сервопривод движется плавно даже при движении всех 16. Идея преобразования ширины импульса в угол та же, что описана на странице сервопривода SG90.

Когда его следует использовать

Выбирайте PCA9685, когда у робота сервоприводов больше, чем выводов PWM у микроконтроллера, или когда требуется исключительно стабильное движение сервоприводов:

  • Роботизированные руки — несколько сервоприводов суставов, движущихся одновременно; используйте вместе с обратной кинематикой.
  • Гексаподы / квадроподы — двенадцать или более сервоприводов на все лапы.
  • Поворотные конструкции и крепления камер — освобождают таймеры микроконтроллера для других задач.

Для одного сканирующего сервопривода, например ультразвукового сканера на роботе для объезда препятствий, плата не нужна: микроконтроллер может управлять им напрямую.

Подключение и важные нюансы

  • Две силовые шины. Логика VCC питается от микроконтроллера, а сервоприводы — от клеммы V+. Никогда не пропускайте ток 16 сервоприводов через вывод 5 V Arduino.
  • Рассчитывайте V+ по останову, а не по простою. Шестнадцать сервоприводов вместе могут потреблять несколько ампер; слабый источник просядет, и вся плата начнёт дрожать.
  • При каскадировании задавайте уникальные адреса перемычками.
  • Добавьте конденсатор параллельно V+, чтобы поглощать всплески тока при запуске сервоприводов.

Расположение выводов

Существуют три группы подключений: разъём управления к микроконтроллеру, шестнадцать разъёмов сервоприводов и силовая клемма, которую нельзя путать с первой.

Группа Вывод Назначение
Управление VCC Только логическое питание, 3.3 V или 5 V от микроконтроллера. Не питание сервоприводов
Управление GND Земля — должна быть общей с микроконтроллером и источником сервоприводов
Управление SCL Тактовый сигнал I²C
Управление SDA Данные I²C
Управление OE Разрешение выходов, активный низкий уровень. Если его оставить неподключённым, плата удерживает его на низком уровне, поэтому выходы включены
Питание V+ (винтовая клемма) Ток сервоприводов. До 6 V на распространённой плате расширения
Выходы 0–15 По три вывода: сигнал PWM, V+, GND — стандартный порядок сервопривода
Адрес A0–A5 (площадки) Шесть перемычек задают адрес I²C, по умолчанию 0x40

Самый важный факт об этой плате: VCC и V+ — разные шины. VCC питает микросхему, V+ — сервоприводы. Их соединение пропускает ток останова сервоприводов через регулятор микроконтроллера, что быстро вызывает просадку Arduino.

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

PCA9685 Arduino Uno ESP32 Примечание
VCC 5 V 3.3 V Несколько миллиампер — только логика
GND GND GND Также общая земля с источником сервоприводов
SDA A4 GPIO 21 На плате установлены подтяжки 10 kΩ
SCL A5 GPIO 22 То же
V+ не Arduino не ESP32 Отдельный источник 5–6 V, рассчитанный на ток останова
OE Оставить неподключённым Оставить неподключённым Либо управлять с вывода, одновременно отключая все выходы

OE полезнее, чем кажется. Высокий уровень аппаратно и мгновенно отключает все шестнадцать выходов без обмена по I²C. На руке, способной упасть под действием тяжести, это настоящая аварийная остановка, работающая даже при зависшем коде.

Выбор источника питания сервоприводов

Здесь большинство проектов PCA9685 ошибается, хотя расчёт несложен.

Хобби-сервопривод потребляет примерно:

Сервопривод Простой Движение без нагрузки Останов
SG90 (9 g) ~10 mA ~150–250 mA ~650 mA
MG90S (металлические шестерни) ~10 mA ~250–400 mA ~800 mA
MG996R (стандартный) ~10 mA ~500–900 mA ~2.5 A

Четыре SG90 на небольшой руке при одновременном движении потребляют около 1 A, а при одновременном останове достигают 2.6 A — именно это происходит, когда рума упирается в собственную раму. Зарядное устройство для телефона на 1 A не подходит. Рассчитывайте на одновременный останов всех сервоприводов или как минимум на движение всех и останов одного.

Симптом слабого источника характерен, но сбивает с толку: сервоприводы дрожат, плата может перезагружаться, и всё выглядит как проблема I²C или кода. Это не она. Приложите мультиметр к V+ во время движения руки и посмотрите на просадку.

Добавьте конденсатор параллельно V+. Подойдёт значение 470–1000 µF рядом с клеммой. Он не выдержит длительный останов — конденсатор 1000 µF при токе 1 A снижает напряжение на один вольт каждую миллисекунду, — но поглощает резкий всплеск тока в момент запуска сервопривода, который наводится на логическую шину.

Как на самом деле формируется PWM

Понимание двух чисел упрощает диагностику любой проблемы драйвера сервоприводов.

Микросхема работает от внутреннего генератора 25 MHz и делит его с помощью предделителя:

prescale = round(25000000 / (4096 x frequency)) - 1

Для нужных хобби-сервоприводам 50 Hz получается round(25000000 / 204800) - 1 = 121.

Затем каждый период делится на 4096 шагов (12 бит). При 50 Hz период равен 20 ms, поэтому один шаг составляет 20 ms / 4096 = 4.88 µs. Это преобразует нужные ширины импульса сервоприводов в записываемые отсчёты:

Ширина импульса Что означает Отсчёты при 50 Hz
1.0 ms Один край диапазона 205
1.5 ms Середина 307
2.0 ms Другой край 410

Сразу следуют два следствия. Во-первых, на весь диапазон 180° сервопривода приходится около 205 отсчётов, то есть чуть меньше одного отсчёта на градус: 12-разрядное разрешение PCA9685 не является ограничивающим фактором; важнее мёртвая зона самого сервопривода. Во-вторых, предделитель можно записывать только когда микросхема находится в спящем режиме, поэтому каждая библиотека переключает MODE1 при изменении частоты.

Генератор не равен ровно 25 MHz

Реальные платы отклоняются на несколько процентов, причём одинаково на всей плате. Если сервоприводы систематически не достигают заданного угла у обоих краёв, не следует подстраивать ширину импульса: измерьте и скорректируйте частоту генератора.

pwm.begin();
pwm.setOscillatorFrequency(26075000);  // measured, not the 25 MHz nominal
pwm.setPWMFreq(50);

Задайте 50 Hz, подключите осциллограф или логический анализатор к любому выходу и измерьте истинный период. Масштабируйте номинальные 25 MHz отношением заданной и измеренной частот. Выполните это один раз для каждой платы и запишите число в комментарии.

Минимальный рабочий код

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);

// Per-servo calibration. These are NOT universal — measure your own.
const int SERVO_MIN = 150;   // counts at one end stop
const int SERVO_MAX = 600;   // counts at the other

int countsFor(int degrees) {
  return map(constrain(degrees, 0, 180), 0, 180, SERVO_MIN, SERVO_MAX);
}

void setup() {
  pwm.begin();
  pwm.setOscillatorFrequency(25000000);  // replace with your measured value
  pwm.setPWMFreq(50);                    // hobby servos want 50 Hz
  delay(10);
}

void loop() {
  for (int a = 0; a <= 180; a += 5) {    // sweep, don't jump
    pwm.setPWM(0, 0, countsFor(a));
    delay(20);
  }
  for (int a = 180; a >= 0; a -= 5) {
    pwm.setPWM(0, 0, countsFor(a));
    delay(20);
  }
}

Константы SERVO_MIN/SERVO_MAX задают калибровку и различаются для каждого сервопривода, даже между двумя экземплярами одной модели из одной упаковки. Найдите их, медленно отходя от 307 и останавливаясь в момент, когда сервопривод гудит без движения: значит, он упирается в собственный крайний упор и впустую потребляет ток останова.

Обратите внимание и на плавное перемещение вместо скачка. setPWM мгновенно меняет заданную позицию, и сервопривод пытается достичь её на полной скорости, что на руке означает резкое движение и всплеск тока. Пошаговое изменение команды — простейший профиль движения, который стоит применять даже в тестовом коде.

Каскадирование плат

На каждой плате есть шесть площадок A0–A5, задающих 64 адреса от 0x40. Соединяйте на каждой плате свою комбинацию:

Соединённые перемычки Адрес
Нет 0x40
A0 0x41
A1 0x42
A0 + A1 0x43
A5 0x60

Документированный максимум — 62 платы: 0x70 зарезервирован для общего вызова I²C, поэтому доступны не все 64 адреса. На практике ограничение наступает намного раньше: 62 платы — это 992 сервопривода, для которых источник питания становится гораздо более серьёзной инженерной задачей, чем шина.

При каскадировании следите за одной особенностью: каждая плата имеет собственные подтяжки I²C 10 kΩ, включённые параллельно. Десять плат дают 1 kΩ, что уже многовато для шины 5 V. После нескольких плат отключите перемычки подтяжки на всех, кроме одной.

Диагностика

Симптом Вероятная причина Исправление
Вообще ничего не движется На V+ нет питания сервоприводов V+ — отдельная шина; VCC питает только микросхему
Сервоприводы постоянно дрожат Просадка источника под нагрузкой Рассчитать V+ по току останова; добавить конденсатор 470–1000 µF
Дрожание только при движении нескольких То же, но запас минимален Как выше — измерить V+ мультиметром при движении
Один сервопривод гудит и нагревается Команда выходит за крайний упор Сузить для этого канала SERVO_MIN/SERVO_MAX
Все углы постоянно занижены Генератор не равен ровно 25 MHz Измерить реальную частоту и вызвать setOscillatorFrequency
Плата не найдена на шине Неверный адрес или нет логического питания Просканировать шину; проверить VCC и соответствие перемычек коду
Из двух плат отвечает только одна Обе используют 0x40 по умолчанию Соединить перемычки, чтобы адреса были уникальны
Arduino перезагружается при движении руки Ток сервоприводов проходит через плату V+ должен иметь отдельный источник, общей остаётся только земля
Выходы не работают, но I²C исправна OE удерживается в высоком уровне Оставить OE неподключённым или подать низкий уровень

PCA9685 или прямые PWM микроконтроллера?

Прямые выводы PWM PCA9685
Каналы 6 на Uno, причём библиотека Servo занимает таймер 16 на плату, 62 платы на одной шине
Используемые выводы По одному на сервопривод Всего два на все
Хронометраж Формируется микроконтроллером — дрожит при нагруженном цикле Формируется аппаратно — стабилен независимо от кода
Путь питания Как подключите, часто неудачно Выделенная клемма V+, делающая правильное решение очевидным
Дополнительная стоимость Нет Несколько долларов и адрес I²C

Честный порог: один-два сервопривода управляйте напрямую. Сканирующей голове датчиков на роботе для объезда препятствий эта плата не нужна. При трёх и более либо для любого сервопривода, важна плавность, и PCA9685 окупается сразу: не из-за числа выводов, а потому что микроконтроллер перестаёт отвечать за хронометраж. Сервопривод под управлением библиотеки Servo дёрнется при задержке цикла; управляемый PCA9685 — нет.

Исследуйте граф

Используется в этих сборках

Проекты, учебные пути и симуляторы, в которых используется Драйвер сервоприводов PCA9685.

Вопросы

Драйвер сервоприводов PCA9685: частые вопросы

Что такое PCA9685?

PCA9685 — 16-канальный 12-разрядный драйвер PWM, управляемый по I²C. Чаще всего его используют как драйвер сервоприводов: одна небольшая плата управляет максимум 16 сервоприводами всего от двух выводов микроконтроллера, поэтому это стандартный выбор для роботизированных рук, гексаподов и поворотных конструкций.

Сколько сервоприводов может управлять PCA9685?

16 на плату; на одной шине I²C можно соединить до 62 платы, получив 992 канала. На практике ограничение — питание, а не число каналов: 16 одновременно движущихся сервоприводов могут потреблять несколько ампер, которые должны поступать через отдельную клемму V+, а не от микроконтроллера.

Нужно ли PCA9685 отдельное питание?

Да, для сервоприводов. Логика микросхемы питается от микроконтроллера напряжением 3.3–5 V, но сервоприводы потребляют ток через выделенную клемму V+. Подключите к ней источник, способный одновременно обеспечить ток останова всех сервоприводов, иначе возникнет просадка питания и дрожание.

Как подключить PCA9685 к Arduino?

Подключите его по I²C: SDA и SCL к выводам I²C Arduino, а также VCC и GND для питания логики микросхемы. Затем подведите отдельный источник к V+ для сервоприводов и подключите каждый сервопривод к разъёму канала. Библиотека, например Adafruit, позволяет задавать угол каждого канала в коде.

Как соединять платы PCA9685 каскадом?

На каждой плате есть шесть площадок-перемычек для задания адреса I²C. Соедините на каждой плате свою комбинацию, чтобы адреса были уникальными, а затем подключите все платы к одной паре линий I²C: до 62 плат и 992 каналов на одной шине.

Дополнительные материалы

Источники