PCA9685: подключение 16-канального ШИМ-драйвера к Arduino
PCA9685 подключается к Arduino по шине I2C четырьмя проводами и сразу даёт 16 каналов ШИМ с разрешением 12 бит, то есть 4096 градаций яркости. Сервоприводов на нём помещается 16 штук, и все они работают от одного вывода питания.
Обычный ШИМ Arduino ограничен шестью выводами на Uno и восемью битами яркости. PCA9685 снимает это ограничение, но добавляет к схеме микросхему, библиотеку и лишний провод на шину.
Первый раз я подключил PCA9685 к Nano, и сервоприводы на ней дёргались рывками. Оказалось, у Nano нет нужного вывода для I2C в том же месте, куда я втыкал провода, и я перепутал SDA с SCL.
Что умеет чип: 16 каналов, 12 бит, своя частота
PCA9685 это не расширитель выводов, а отдельный генератор ШИМ со своим тактовым генератором. Отсюда две возможности, которых у обычного ШИМ Arduino нет: у всех каналов своя яркость в 4096 градаций, а частота переключения задаётся один раз для всех каналов сразу.
| Параметр | Значение |
|---|---|
| Каналы | 16 независимых |
| Разрешение | 12 бит, 4096 градаций |
| Частота ШИМ | 6104, 3052, 2035, 1526, 1221 Гц |
| Предел по даташиту | 1,6 кГц |
| Внутренний генератор | 25 МГц |
| Адрес I2C | 0x40, задаётся выводами A0…A6 |
| Питание логики | от 2,3 до 5,5 В |
| Питание выхода | до 26 В |
| Ток на канал | до 60 мА по даташиту |
Частота считается просто: 25 мегагерц делённое на прескалер плюс один и на 4096. Поэтому максимальная частота 6104 герц, а чтобы попасть в паспортные 1,6 килогерца, прескалер ставят 3 и получают 1526 герц. Для сервоприводов нужна ровно 50 герц, и её получают прескалером 121.
Распиновка и адрес на шине
- VCC это питание логики, подойдут и 3,3 В, и 5 В.
- GND это общая земля, она обязательна.
- SDA и SCL это линии I2C, на Uno это A4 и A5, на ESP32 это 21 и 22.
- A0, A1 и A2 это выводы выбора адреса, на разных платах их от одного до трёх.
- OE это вход разрешения выходов, его тянут к земле, тогда каналы работают.
- V+ это отдельное питание нагрузки, для сервоприводов его берут от внешнего блока.
Адрес по умолчанию 0x40, и он меняется перемычками на выводах A0, A1 и A2. На модулях с тремя перемычками получается восемь адресов, на более дешёвых с одной перемычкой всего два. На одной шине I2C спокойно живут восемь таких чипов, это 128 каналов.
Светодиоды: ток задаётся регистром
Каждый канал умеет не только ШИМ, но и ограничение тока. В старшем байте регистра канала отведено 4 бита под ограничитель: значение 0 выключает канал совсем, значение 15 разрешает полный ток. На светодиод ток ограничивается резистором, а на мощных лентах этот бит помогает не сжечь канал.
- Каждый светодиод всё равно подключают с последовательным резистором, ток ограничитель не заменяет.
- Каналы включаются и выключаются независимо, запись в регистры идёт с автоинкрементом.
- Один регистр MODE1 управляет сном, частотой и откликом на общий вызов сразу для всех каналов.
- Регистры каналов идут подряд с адреса 0x06, на каждый канал отведено 4 байта.
#include <Wire.h>#include <Adafruit_PWMDriver.h> Adafruit_PWMDriver pwm = Adafruit_PWMDriver(0x40); void setup() { Serial.begin(115200); pwm.begin(); pwm.setPWMFreq(60); // chastota SHIM dlya svetodiodov pwm.setPWM(0, 0, 0); // kanal 0 pogashen} void loop() { for (uint16_t v = 0; v <= 4095; v += 8) { pwm.setPWM(0, 0, v); // 4095 eto polnaya yarkost delay(4); } for (uint16_t v = 4095; v > 0; v -= 8) { pwm.setPWM(0, 0, v); delay(4); }}Сервоприводы: 16 штук вместо двенадцати выводов
Вторая по популярности задача у PCA9685 это сервоприводы. Обычная библиотека Servo на Uno тратит под них таймер 1 и выключает ШИМ на выводах 9 и 10, а выводов под серво там всего 12. Через PCA9685 сервоприводов получается 16, и занимают они два вывода Arduino вместо двенадцати.
#include <Adafruit_PWMDriver.h>#include <Adafruit_Servo.h> Adafruit_PWMDriver pwm = Adafruit_PWMDriver(0x40);Adafruit_Servo servo = Adafruit_Servo(16, &pwm); // 16 kanalov void setup() { pwm.begin(); servo.setPWMFreq(50); // servoprivodu nuzhen period 20 ms servo.attach(0); servo.attach(1);} void loop() { servo.write(0, 0); // kanal 0 na 0 gradusov servo.write(1, 90); // kanal 1 na 90 gradusov delay(1000); servo.write(0, 180); servo.write(1, 45); delay(1000);}Чем это лучше обычного ШИМ Arduino
Сравнение честное: у PCA9685 больше каналов и выше разрешение, но у Arduino есть то, чего нет у микросхемы, это простота и отсутствие лишней детали в коде.
| Критерий | Arduino Uno | PCA9685 |
|---|---|---|
| Каналов ШИМ | 6 | 16 на одном чипе |
| Разрешение | 8 бит, 256 ступеней | 12 бит, 4096 ступеней |
| Частота | 490 или 980 Гц, задаётся аппаратно | от 1221 до 6104 Гц, задаётся программно |
| Серво | 12 выводов, таймер занят | 16 серво, таймеры свободны |
| Проводов | по одному на канал | 4 на все каналы |
| Расширяемость | не расширить | до 8 чипов, 128 каналов |
| Сложность кода | одна строка | объект и вызов метода |
Про обычный ШИМ подробнее: analogWrite на Uno даёт 8 бит и фиксированную частоту, а выводы 9 и 10 после подключения библиотеки Servo перестают работать как ШИМ. Про это подробно в уроке про analogWrite, там же разобрана своя частота на таймерах.
Что сначала не получилось
Первый раз я подключил модуль к Nano и сразу залил скетч с сервоприводом. Сервопривод не двигался, в мониторе порта была пустота. Я трижды перепроверял питание, пока не догадался посмотреть на нумерацию выводов: на Nano с гибридным корпусом выводы SDA и SCL подписаны цифрами A4 и A5, а рядом стояли цифровые 4 и 5.
Второй раз модуль я подключил правильно, но сервоприводы всё равно дрожали и подтормаживали. Дело оказалось в питании: я запитал сервоприводы от вывода 5 вольт самой платы, и по линии шёл просад. Как только я вынес питание серво на отдельный блок с общей землёй, дрожание исчезло.
Личный опыт: подсветка витрины
Первое устройство с PCA9685 у меня было подсветкой витрины в магазине у родственников. 14 отрезков светодиодной ленты по 30 сантиметров, плавный розовый градиент по кругу и отдельная кнопка для фиксации цвета.
Что выяснилось по ходу. Светодиоды питались через ограничитель тока в самом чипе, и когда я выставил его на максимум, лента грелась так, что пластик стал мягким. Пришлось снизить ток вдвое и заменить провода на более толстые. А градиент я перестал пересчитывать целиком: сдвиг цвета на один шаг это перезапись четырёх регистров, и на 14 каналах это 56 байт по I2C, что Arduino тянет за доли миллисекунды.
Авторская позиция: когда нужен именно PCA9685
Если у задачи один-два канала, а Arduino при этом не завален, то PCA9685 это лишняя деталь. Обычный analogWrite сделает то же самое, проводов будет столько же, а код короче на строчку. Покупать микросхему ради одной ленты смысла нет.
Смысл появляется с четвёртого канала. Как только светодиодов становится больше шести, а потом и сервоприводов больше двенадцати, вопрос упирается в выводы платы. Дальше вариантов два: менять плату на Mega или взять PCA9685, и второй вариант часто дешевле и удобнее, потому что даёт ещё и разрешение 12 бит.
И не покупайте чип, если задача в одном канале с плавным затуханием. Там хватит обычного ШИМ, а если хочется настоящей плавности, разумнее взять ленту с адресными светодиодами и библиотеку FastLED, про которую есть отдельный гайд.