Мы уже говорили о том, как решить проблему нехватки цифровых портов ввода-вывода. В этой статье вы узнаете, как увеличить количество портов с аппаратной поддержкой ШИМ.

Широтно-импульсная модуляция (ШИМ, PWM) – это управление соотношением длительности высокого и низкого уровня импульсного сигнала. Чаще всего такой сигнал используют для управления углом поворота сервомашинок и яркостью свечения ламп или светодиодов.

В микроконтроллере Atmega328 доступно шесть универсальных портов с функцией ШИМ. Не так уж мало, но эти порты могут быть нужны для других целей. Представьте, что вам надо собрать робота-паука:

В этой конструкции задействовано 18 сервомашинок. Выводов Arduino явно не хватает.

Проблема нехватки портов ШИМ легко решается при помощи модулей на основе микросхемы PCA9685:

Эту микросхему разработали для управления яркостью светодиодов, но она идеально подходит для управления сервомашинками и сервоприводами.

Основные характеристики PCA9685

  • Количество каналов: 16
  • Разрешение канала: 12-bit, 4096 шагов (в Arduino 8-bit, 256 шагов)
  • Частота ШИМ: от 24 Гц до 1526 Гц (в Arduino по умолчанию 488 Гц)
  • Напряжение питания: от 2.3 до 5.5 вольт
  • Частота шины I2C: до 1000 кГц

Библиотеки Arduino PCA9685

Наиболее популярны библиотеки от Adafruit и NachtRaveVL. Вторая библиотека пригодится для продвинутых пользователей, а для простых проектов и примеров достаточно библиотеки Adafruit PCA9685 PWM Library. Для установки библиотеки запустите Arduino IDE, перейдите в меню Скетч → подключить библиотеку → Управлять библиотеками → Все. Введите в строку поиска “adafruit pwm”, щелкните на строке с названием найденной библиотеки и нажмите кнопку “Установить”.

Подключение модуля PCA9685 к Arduino

Соберите простую схему, в которой светодиод подключен к порту P0, а сервомашинка подключена к порту P3:

На плате модуля уже установлены последовательные гасящие резисторы, поэтому светодиод можно подключить непосредственно к выводу платы:

Микросхема оснащена инверсным входом управления EN (enable). Если на вывод EN подан высокий уровень, все выходы принудительно переключаются в низкий уровень. В схеме модуля есть резистор, который подтягивает EN в низкий уровень, но для надежной работы следует соединить его с общим проводом. Этот вывод при необходимости можно соединить со свободным портом платы Arduino и программно отключать порты микросхемы PCA9685 подачей высокого уровня.

Выходные каскады PCA9685 питаются от независимого источника по линии V+, которая также выведена на отдельный зажимной разъем. Если вы используете модуль для управления несколькими сервомашинками или светодиодами, то его можно питать от платы Arduino и не подключать линию V+ или соединить ее с линией питания +5V платы Arduino. Но если вы используете мощные сервомашинки или сервоприводы, они могут создать импульсные помехи по питанию, вплоть до зависания или перезагрузки платы Arduino. В таком случае для питания управляемых устройств надо подключить к линии V+ отдельный источник питания.

Пример управления светодиодом и сервомашинкой

Скопируйте и загрузите в плату Arduino скетч примера:

Сначала вал сервомашинки вращается от минимального положения до максимального и обратно. Затем яркость светодиода плавно нарастает от нуля до максимума и вновь снижается до нуля. Частота повторения импульсов ШИМ установлена в 60 Гц, потому что это значение подходит для обычной сервомашинки и действует на все выводы. При управлении только светодиодами частоту желательно увеличить минимум до 100 Гц чтобы избежать неприятное мерцание.

Настройка значений SERVOMAX и SERVOMIN

Сервомашинка работает только в пределах своего механического диапазона вращения, поэтому мы вынуждены ограничить диапазон изменения длительности импульса с двух сторон. При попытке выйти за пределы диапазона могут сломаться зубцы пластиковых шестеренок или ограничители вращения сервомашинки. Точные значения пределов зависят от марки машинки. Желательно начинать отладку с узкого диапазона значений SERVOMIN – SERVOMAX и постепенно расширить его, но не доводя вращение вала машинки до ограничителей.

Перекодировка угла поворота в длительность импульса

Управлять сервомашинкой удобнее, если указывать в скетче физический угол поворота вала. У стандартной машинки угол поворота от минимума до максимума обычно составляет 180 градусов. Используя стандартную функцию Arduino map()  вы можете конвертировать угол поворота в значение длительности импульса:

pulselength = map(degrees, 0, 180, SERVOMIN, SERVOMAX);

Статические уровни порта – эмуляция цифровых выходов GPIO

Порты микросхемы PCA9685 можно использовать для эмуляции обычных цифровых выходов.

Команда pwm.setPWM(pin, 4096, 0);  устанавливает на выводе pin логическую единицу.

Команда pwm.setPWM(pin, 0, 4096);  устанавливает на выводе pin логический ноль.