Руководство · Средний · 18 min read
Управление сервоприводами через PCA9685 (драйвер PWM по I²C)
Управляйте сервоприводами через PCA9685 по I²C: задайте частоту PWM, преобразуйте угол в ширину импульса и обеспечьте безопасное питание.
У микроконтроллера есть лишь несколько аппаратных каналов PWM. Для одного или двух сервоприводов этого достаточно, но у роботизированной руки четыре, у гексапода восемнадцать, и Arduino заканчиваются таймерами задолго до того, как закончатся суставы. PCA9685 решает эту задачу: одна небольшая плата формирует шестнадцать независимых сигналов PWM аппаратно, а управление всеми ими идёт всего по двум проводам I²C. Именно так на реальном оборудовании управляют каждым суставом симулятора роботизированной руки.
Почему не подключить сервоприводы напрямую к Arduino
Две причины. Первая — выводы: у Uno хватает таймеров лишь для нескольких объектов Servo, после чего библиотека начинает конфликтовать сама с собой. Вторая, более важная, — питание: при срыве сервопривод может потреблять 500–700 mA, а четыре движущихся одновременно — несколько ампер. Такой ток не может идти от вывода 5 V Arduino: плата проседает и перезагружается посреди движения. PCA9685 исправляет обе проблемы. Формирование PWM выполняет отдельная микросхема, а ток сервоприводов поступает от собственного разъёма V+, полностью удерживая большой ток от логики.
Задайте частоту PWM
Каждый хобби-сервопривод ожидает управляющий сигнал 50 Hz — один импульс каждые 20 ms. PCA9685 задаёт одну частоту для всей микросхемы, поэтому установите её один раз в setup():
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40); // default I²C address
void setup() {
pwm.begin();
pwm.setPWMFreq(50); // 50 Hz — the standard servo refresh rate
}
Теперь все шестнадцать каналов работают с частотой 50 Hz. Угол, который удерживает каждый сервопривод, задаётся шириной его импульса, а не частотой — это часть, которую вы контролируете отдельно для каждого канала.
От угла к ширине импульса — важная калибровка
Сервопривод считывает ширину импульса как команду положения: примерно 1 ms для 0°, 1.5 ms для центра, 2 ms для 180°, повторяемые 50 раз в секунду. SG90 управляется по тому же принципу — ширина импульса задаёт угол; PCA9685 просто формирует его аппаратно.
PCA9685 не принимает миллисекунды напрямую. Микросхема делит каждый период 20 ms на 4096 отсчётов (разрешение 12 бит), а вы указываете, сколько отсчётов импульс остаётся высоким. При 50 Hz полный период равен 4096 отсчётов = 20 ms, поэтому:
- 1 ms ≈ 205 отсчётов (0°)
- 1.5 ms ≈ 307 отсчётов (90°)
- 2 ms ≈ 410 отсчётов (180°)
Это номинальные значения. Реальные сервоприводы различаются: один и тот же SG90 может останавливаться на 130 и доходить до 490. Это единственное число, которое необходимо откалибровать. Сохраните минимум и максимум для каждого сервопривода и отображайте угол в этот диапазон:
// Calibrate these two per servo by eye — see "Gotchas" below.
const int SERVO_MIN = 130; // counts at the servo's 0° hard stop
const int SERVO_MAX = 490; // counts at the servo's 180° hard stop
int angleToCount(int deg) {
return map(deg, 0, 180, SERVO_MIN, SERVO_MAX);
}
Пропуск калибровки — причина того, что команда «90°» даёт фактический угол 78° на одном суставе и 96° на другом, а рука на неоткалиброванных сервоприводах никогда точно не достигает позы, запрошенной решателем обратной кинематики.
Подключение: две силовые шины, одна земля
- Логика —
VCC,GND,SDA,SCLот Arduino. Это питает только микросхему. - Питание сервоприводов — отдельный источник 5–6 V на винтовой разъём V+, рассчитанный на ток срыва всех сервоприводов одновременно, а не на их потребление в покое.
- Общая земля — земля источника и земля Arduino должны быть соединены, иначе у PWM-сигнала нет опорного уровня, а сервоприводы дёргаются или игнорируют команды. То же относится к линиям I²C, передающим команды.
Добавьте конденсатор между V+ и землёй, чтобы поглотить скачок тока при запуске сервоприводов; на плате PCA9685 для этого есть посадочное место.
Код: перемещение сустава
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);
const int SERVO_MIN = 130;
const int SERVO_MAX = 490;
int angleToCount(int deg) {
return map(deg, 0, 180, SERVO_MIN, SERVO_MAX);
}
void setServo(uint8_t channel, int deg) {
pwm.setPWM(channel, 0, angleToCount(deg)); // on at count 0, off at the angle count
}
void setup() {
pwm.begin();
pwm.setPWMFreq(50);
setServo(0, 90); // base to centre
setServo(1, 45); // shoulder
setServo(2, 120); // elbow
setServo(3, 10); // gripper open
}
void loop() {}
Каждый setPWM(channel, 0, count) означает «включить этот канал в начале периода и выключить после count тактов». Для плавного движения сустава меняйте угол в цикле с коротким delay() между шагами, чтобы сервопривод успел двигаться, а не перескакивал.
Подводные камни
- Откалибруйте
SERVO_MIN/SERVO_MAXдля каждого сервопривода. Подайте команду 0°, запомните, где фактически находится рычаг сервопривода, и слегка измените отсчёт до совпадения. Сделайте то же при 180°. Десять минут здесь предотвращают ошибки в каждом дальнейшем положении. - Никогда не питайте V+ от Arduino. Один сервопривод может выдержать; четыре вызовут просадку и перезагрузку платы.
- Рассчитывайте источник на срыв, а не на покой. Слишком слабый источник проседает, когда несколько сервоприводов двигаются одновременно, и вся плата дрожит.
- Проверьте адрес. По умолчанию
0x40. Для каскада плат соедините перемычки и передайте новый адрес конструктору. - Двигайтесь плавно. Постепенное приближение к цели лучше скачка: снижает скачок тока и бережнее к пластиковым шестерням.
- Канал захвата — тот, который перегревается. Остальные суставы достигают угла и простаивают; захват, удерживающий объект, упирается в него и постоянно потребляет около половины ампера. Откройте его сразу после установки детали; в силе захвата, срыве и податливости сервопривода-захвата объясняется, почему более высокое разрешение PWM не обеспечивает более точное регулирование усилия.
Когда каждый сустав отвечает на угол, следующий шаг — геометрия: превращение целевой точки в углы суставов, которые её достигают. Именно для этого нужны обратная кинематика двухзвенной руки и симулятор роботизированной руки.
Исследуйте граф
Входит в эти сборки
Проекты и учебные пути, в которые входит это руководство.
Дополнительные материалы