Найти в Дзене
Электроника, ESP32, Arduino

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

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

Схема подключения:

Подключение энкодера EC11 - электрическая принципиальная схема
Подключение энкодера EC11 - электрическая принципиальная схема

Как обычно соберем прототип на макетной плате:

Подключение энкодера EC11 - прототип на макетной плате
Подключение энкодера EC11 - прототип на макетной плате

Контакты S1 и S2 это обычная кнопка (нужно утопить ручку), контакты
AB и BC будут замыкаться в определенной последовательности (с задержкой относительно друг друга) в зависимости от того в какую сторону вращается ручка, что позволит определить не только на сколько шагов повернулась ручка, но и направление вращения.

Технические характеристики энкодера EC11

  • Количество положений вала - 20
  • Количество импульсов на оборот - 10
  • Высота вала (без резьбы) - 8 мм
  • Угол вращения - 360°, бесконечный
  • Максимальное напряжение - 5 В
  • Максимальный ток - 10 мА

Для начала набросаем простенький скетч, для проверки работоспособности с устранением дребезга контактов. Кнопку для простоты понимания задействовать не будем - её можно опросить и в основном цикле.

-3

-4

Открываем монитор порта и при вращении ручки энкодера на один щелчок по часовой стрелке мы видим картинку в какой последовательности замыкались контакты А и С:

Вращение по часовой стрелке на одну позицию
Вращение по часовой стрелке на одну позицию

Если повернуть ручку на 1 щелчок против часовой стрелки, последовательность замыкания - размыкания контактов А и С будет другая

Вращение против часовой стрелки на одну позицию
Вращение против часовой стрелки на одну позицию

Таким образом мы получили определенную последовательность сигналов которая однозначно указывает на поворот ручки на 1 позицию, а также направление этого поворота.
A,C 10110100 - вращение по часовой на 1 щелчок
A,C 01111000 - вращение против часовой на 1 щелчок

Последние 4 бита можно отбросить, и таким образом если при вращении ручки к нам придет последовательность сигналов:

1011 - ручку повернули вправо
0111 - ручку повернули влево

Осталось поместить данный код в процедуру прерываний, но там возникает проблема как бороться с дребезгом контактов (задержки в прерываниях, чтобы точно убедиться что контакты энкодера не тилипаются использовать не получится).

Еще раз проанализируем табличку:

-7

Пока энкодер находится в неподвижном состоянии - контакт А и контакт С находятся в нулевом состоянии. Потом свое состояние меняет контакт А, потом контакт С, потом снова А, и потом снова С. Смена всегда идет строго друг за другом, не важно в какую сторону мы вращаем ручку. Воспользуемся этим свойством и пусть контакт А после изменения состояния будет блокировать сам себя и разблокировать контакт С. Контакт С после изменения состояния будет блокировать сам себя и разблокировать контакт А. Можно писать код:

Объявление переменных
Объявление переменных

Переменная oldencoderCount нужна, чтобы выводить в COM порт только если крутанули ручку энкодера.

Функция фильтра
Функция фильтра

В переменную encoderResult будем скидывать все изменения стояний на входах микроконтроллера, но реагировать будем только если попадется определенная последовательность сигналов.

Две функции прерываний по изменению состояний контактов AB и BC
Две функции прерываний по изменению состояний контактов AB и BC

Каждая функция блокирует сама себя после первого вызова. Весь дребезг будет игнорироваться с помощью оператора return; Разблокировка будет происходить либо из другой функции - либо когда ручка не вращается с помощью конструкции:
if (!pinA && !pinC) blockA = false; else blockA = true;
if (!pinA && !pinC) blockC = false; else blockC = true;

В секции setup назначаем функции для обработки прерываний по изменению состояния входов к которым подключены контакты.
В секции setup назначаем функции для обработки прерываний по изменению состояния входов к которым подключены контакты.

Если надумаете использовать данный пример с платой Arduino - для подключения энкодера необходимо будет использовать только пины 2 и 3.

Выводим значения энкодера
Выводим значения энкодера

В loop выводим новое значение поворота энкодера. (только если ручку крутим). Использование механизма прерываний позволяет не пропускать импульсы, и не задействует ресурсы микроконтроллера пока ручка стоит неподвижно, и ненужно ни каких библиотек :-). Код примера скачивайте по этой ссылке.

Также вы можете ознакомиться с полным списком статей на моем канале.
Всем удачи!