Как использовать энкодер (Rotary Encoder) с Raspberry Pi

Как использовать энкодер (Rotary Encoder) с Raspberry Pi

В этом простом руководстве мы покажем вам, как подключить ваш энкодер (rotary encoder) и как использовать код на Python для взаимодействия с ним.

Давайте начнём с краткого объяснения того, что такое энкодер и как он работает!

Энкодер (rotary encoder) — это устройство, которое определяет вращение и направление вращения прикреплённой ручки. Он работает за счёт двух внутренних контактов, которые замыкают и размыкают цепь при повороте ручки. Когда вы поворачиваете ручку, вы можете ощутить характерный «щелчок», указывающий на поворот на одну позицию. Если внутренние контакты изначально были в состоянии HIGH (замыкали цепь), после одного щелчка они оба перейдут в состояние LOW (разомкнут цепь). С помощью простой логики можно определить направление вращения (подробно объясняется ниже, обязательно сначала ознакомьтесь с кодом!).

Вот так выглядят внутренности энкодера:

Внутренности энкодера (rotary encoder)

Вот так выглядит поворот энкодера на 1 щелчок против часовой стрелки:

Поворот энкодера на 1 щелчок против часовой стрелки

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

Давайте начнём со схемы подключения:

Схема подключения энкодера к Raspberry Pi

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

  • CLK — GPIO17 (pin11)

  • DT — GPIO18 (pin12)

  • + — 3v3 (pin1)

  • GND — GND (pin6)

Вот и всё, что касается подключения. Вам не нужно беспокоиться о каких-либо резисторах или других компонентах, так как в энкодер встроены резисторы на 10 кОм, которые поддерживают ток на абсолютном минимуме!

Код на Python

Далее перейдём к коду на Python. Вы можете скачать наш пример кода с нашего GitHub — https://github.com/modmypi/Rotary-Encoder/

Или скачать его напрямую на ваш Pi, используя эту команду в окне терминала:

git clone https://github.com/modmypi/Rotary-Encoder/

Этот пример кода представляет собой простой счётчик. Когда вы поворачиваете энкодер по часовой стрелке, число увеличивается на 1 при каждом «щелчке», а когда вы поворачиваете его против часовой стрелки, число уменьшается на 1 при каждом «щелчке».

Давайте погрузимся в код и посмотрим, как он работает…

cd Rotary-Encoder
nano rotary_encoder.py
  • Строка 4 — Определяем GPIO-пин для пина CLK нашего энкодера

  • Строка 5 — Определяем GPIO-пин для пина DT нашего энкодера

  • Строки 8-9 — Устанавливаем наши GPIO-пины как входы с подтягивающим резистором к земле (pull down resistor)

  • Строка 11 — Определяем переменную нашего счётчика, начиная с 0

  • Строка 12 — Получаем начальное состояние нашего пина CLK

  • Строки 16-26 — Это бесконечный цикл, в котором мы проверяем состояния наших пинов CLK и DT, чтобы сначала определить, вращается ли энкодер, а затем определить, вращается ли он по часовой стрелке или против часовой стрелки

  • Строки 17-18 — Итак, сначала мы получаем текущее состояние наших пинов CLK и DT

  • Строка 19 — Затем мы сравниваем текущее состояние пина CLK с его предыдущим состоянием. Если оно отличается, энкодер вращается, и тогда мы можем определить направление вращения

  • Строки 20-21 — Если состояние нашего пина DT отличается от состояния нашего пина CLK, значит мы вращаем по часовой стрелке и, следовательно, нам нужно увеличить значение нашего счётчика на 1

  • Строки 22-23 — Если состояние нашего пина DT совпадает с состоянием нашего пина CLK, значит мы вращаем против часовой стрелки и, следовательно, нам нужно уменьшить значение нашего счётчика на 1

  • Строка 24 — Просто выводит значение нашей переменной счётчика

  • Строка 25 — Обновляем нашу переменную clkLastState, чтобы она соответствовала нашему clkState

  • Строка 26 — Приостанавливаем скрипт на 0.01 секунды

Логика определения направления вращения

Логика определения направления вращения очень проста для написания в коде, но не так легко понять, почему она работает.

Вот небольшой пример того, как это работает:

Для вращения по часовой стрелке

  1. CLK и DT оба в состоянии HIGH

  2. CLK переходит в LOW, DT остаётся HIGH — clkLastState был HIGH, clkState стал LOW (clkState != clkLastState), поэтому теперь мы можем определить направление — dtState равен HIGH, clkState равен LOW, dtState != clkState, +1

  3. DT переходит в LOW, CLK остаётся LOW — clkLastState был LOW, clkState равен LOW — Ничего не происходит

Для вращения против часовой стрелки

  1. CLK и DT оба в состоянии HIGH

  2. DT переходит в LOW, CLK остаётся HIGH — clkLastState был HIGH, clkState равен HIGH — Ничего не происходит

  3. CLK переходит в LOW, DT остаётся LOW — clkLastState был HIGH, clkState стал LOW (clkState != clkLastState), поэтому теперь мы можем определить направление — dtState равен LOW, clkState равен LOW, dtState == clkState, -1