Найти тему
Электроника, ESP32, Arduino

Как подключить к Arduino 2 (ДВА) и более энкодера.

Задача не так проста как может показаться. Речь пойдет про механические энкодеры с кнопкой EC11. Все, что будет описано в данной статье касается плат на базе микроконтроллере ATMega328P (платы Nano, UNO).

Энкодер EC11
Энкодер EC11

Принцип работы и общий алгоритм работы с этими устройствами был разобран в статье Подключение энкодера EC11 к ESP32 (программное решение), но воспользоваться тем примером при работе с Arduino не получится - так как прерывания из среды Arduino IDE поддерживаются только на выводах 2,3 а для двух энкодеров потребуется 4 ноги с прерываниями. С ESP32 было все проще - там прерывания поддерживаются всеми выводами, и весь код уместился в 60 строк.

Когда диванные дзен-эксперты дают советы в стиле, зачем там мощный контроллер хватило бы и какого-нибудь "на старом PIC16F84" имейте ввиду, что кодить под него придется гораздо дольше, и проще заплатить лишние 100 рублей за современную железку, чем угрохать несколько лишних вечеров на разработку ПО для какой-нибудь идеально подходящей старой железки.

Ссылка на статью "подключение энкодера к ESP32" будет в конце этой статьи, можете наглядно оценить трудозатраты при разработке ПО для подключения к современной ESP32 и уже в принципе морально устаревшей Arduino.

Вообще на гитхабе есть и готовая библиотека для подключения энкодеров,

https://github.com/PaulStoffregen/Encoder
https://github.com/PaulStoffregen/Encoder

но применять её можно только с дополнительными электронными компонентами устраняющими дребезг контактов. Мне лишние детали паять лень - попробуем обойтись без них.

Схема подключения энкодеров EC11 к Arduino NANO
Схема подключения энкодеров EC11 к Arduino NANO

Энкодеры подключены к аналоговым выводам, которые будет использоваться в качестве цифровых. (для Arduino NANO любые выводы кроме A6, A7).

Для решения задачи воспользуемся прерываниями при изменении состояния вывода (Pin Change Interrupts, PCINT)

  • D8 .. D13 - генерируют запрос прерывания PCINT0
  • A0 .. A5 - генерируют запрос прерывания PCINT1
  • D0 .. D7 - генерируют запрос прерывания PCINT2

Входы-источники прерываний объединены в группы, каждой группе соответствует свой вектор и обработчик. Если мы, например, разрешим прерывания на всех выводах первой группы (PCINT0), то для всех поступающих от них запросов на прерывания будет вызываться один и тот же обработчик. Специальных средств для определения конкретного вывода, от которого поступил запрос прерывания, в микроконтроллере нет. И именно созданием этих средств и придется заняться, а вот саму логику работы с энкодерами утащу из своей прошлой статьи.

Для работы с PCINT предусмотрены регистры PCICR, PCIFR и три регистра PCMSKx.

Назначение битов регистра PCICR (Pin Change Interrupt Control Register):

  • PCIE0 - значение "1" в этом бите разрешает обработку прерываний группы PCINT0.
  • PCIE1 - значение "1" в этом бите разрешает обработку прерываний группы PCINT1.
  • PCIE2 - значение "1" в этом бите разрешает обработку прерываний группы PCINT2.

Назначение битов регистра PCIFR (Pin Change Interrupt Flag Register):

  • PCIF0 - значение "1" в этом бите сигнализирует об обнаружении запроса прерывания PCINT0.
  • PCIF1 - значение "1" в этом бите сигнализирует  об обнаружении запроса прерывания PCINT1.
  • PCIF2 - значение "1" в этом бите сигнализирует  об обнаружении запроса прерывания PCINT2.

Три регистра PCMSK0, PCMSK1 и PCMSK2 (Pin Change Mask Register) используются для указания входов, которым разрешено генерировать сигнал запроса прерывания. Соответствие битов регистров PCMSKx выводам микроконтроллера ATmega328/P (для 28-выводного DIP корпуса) и их обозначениям в IDE Arduino приведено в следующей таблице:

PCMSK0, PCMSK1 и PCMSK2
PCMSK0, PCMSK1 и PCMSK2

Более подробно читайте в источнике:
https://tsibrov.blogspot.com/2019/06/arduino-interrupts-part2.html

Собираем прототип
(там есть лишние провода - но это будет продолжение проекта)

Прототип на макетной плате
Прототип на макетной плате

Для проверки железа и аппаратной части пишем незамысловатый скетч
(жуткая смесь чистого С и Arduino-Wiring)

Процедура обработки прерываний на выводах A0....A3
Процедура обработки прерываний на выводах A0....A3
Конфигурация прерываний на выводах  A0....A3
Конфигурация прерываний на выводах A0....A3

Все элементарно и никаких библиотек.....

Открываем монитор порта и слегка шатаем ручки энкодеров. Получаем числа от 14....17 в зависимости от того какую ручку и куда шатаем.

Осталось прикрутить процедуры антидребезга контактов, и вызывать их c использованием прерываний.

Вызов процедур предназначенной для обработки поворотов ручек
Вызов процедур предназначенной для обработки поворотов ручек
Процедура обработки событий левого энкодера
Процедура обработки событий левого энкодера

Все происходит в процедуре обработке прерываний, в loop мы только отображаем повороты ручек.

Отображение поворотов ручек
Отображение поворотов ручек
Результат работы программы
Результат работы программы

Осталось разобраться с кнопками. На контактах A4 A5 находится интерфейс I2C. Занимать его нежелательно, может пригодится если потребуется повесить туда какой-нибудь дисплей или датчик. Кнопки подключим к выводам 2 и 3. Прерывания использовать не будем.

Подключение кнопок и обработка дребезга контактов
Подключение кнопок и обработка дребезга контактов
Модуль обработки дребезга кнопок
Модуль обработки дребезга кнопок

Нажатие на кнопку правого энкодера увеличивает счетчик, нажатие на кнопку левого уменьшает.

Результат работы программы
Результат работы программы

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

Если не до конца понятно что здесь происходит, читайте статью где были описаны общие принципы работы энкодера:

Подключение энкодера EC11 к ESP32 (Arduino) (программное решение)

Полный список всех статей канала доступен по этой ссылке:

Всем удачи!