Андрей Смирнов
Время чтения: ~21 мин.
Просмотров: 14

Как подключить энкодер к частотному преобразователю. Схема

Сегодня я хочу рассказать об энкодерах вращения, какие они бывают, как работают и где применяются. И для примера рассмотрим подключение модуля KY-040 к Ардуино. А пока начнем с теории.

Что такое энкодер вращения

Принцип работы

Работу энкодера вращения проще всего объяснить на примере оптического энкодера. Представьте себе вал электродвигателя, на котором закреплен диск с прорезями. С одной стороны диска расположен светоизлучающий элемент, луч света проходит через прорези и регистрируется фотоэлементом, расположенным с другой стороны (устройство, состоящее из спаренных светоизлучающего и принимающего элементов, называется фотопрерыватель). При вращении диска луч прерывается, в результате чего на выходе фотоэлемента мы получим меандр — сигнал прямоугольный формы. И частота меандра будет пропорциональна скорости вращения диска. Таким образом можно судить о скорости вращения вала электродвигателя.simple_encoder.png Однако работающее по описанному принципу устройство не способно определить направление вращения. Чтобы исправить это добавим в него второй фотопрерыватель и расположим с некоторым смещением относительно первого. В зависимости от направления вращения диска сигнал на выходе первого фотопрерывателя будет меняться раньше или позже чем сигнал на выходе второго. А значит, анализируя как меняются эти два сигнала, мы можем определить направление вращения.quadrature_encoder.png На практике смещения сигналов добиваются не за счет особого расположения фотопрерывателей, а путем добавления второй полосы с прорезями или прозрачными и непрозрачными участками. Участки на двух полосах расположены так чтобы обеспечить сдвиг сигнала по фазе на 90 градусов, поэтому работающие по такому принципу энкодеры называются квадратурными. На этом же принципе основаны механические энкодеры, только вместо фотопрерывателей в них используются скользящие контакты. Основным недостатком таких энкодеров является дребезг контактов, который может приводить к неправильному подсчету сигналов. Кроме того скользящие контакты подвержены износу. Все это ограничивает область применения механических энкодеров.Магнитные энкодеры строятся на базе магниточувствительных элементов, таких как датчики Холла или магниторезистивные датчики. Они просты в изготовлении, лишены недостатков контактных энкодеров и мало чувствительны к внешним факторам. Но все же проигрывают в точности емкостным, индуктивным и оптическим энкодерам.Емкостные энкодеры имеют в своем составе диск асиметричной формы, который при вращении изменяет емкость между двумя электродами. Это изменение регистрируется и используется для определения углового положения. Емкостные энкодеры так же просты в изготовлении и надежны в эксплуатации, из внешних факторов чувствительны только к изменению влажности.Индуктивные энкодеры работают в магнитном поле и используют явление электромагнитной индукции. Благодаря устойчивости к внешним факторам подходят для использования в неблагоприятной среде, когда другие энкодеры могут оказаться ненадежными.Резистивный энкодер работает по тому же принципу что и обычный потенциометр: электрический сигнал на его выходе пропорционален положению ручки энкодера. Собственно и сами потенциометры могут использоваться для отслеживания углового положения, например, их можно увидеть в сервомашинках:servo_inside.jpg

Абсолютные и инкрементные энкодеры

Приведенный выше пример оптического энкодера вращения генерирует на выходе импульсы, по которым принимающее устройство определяет текущее положение вала путём подсчёта числа импульсов счётчиком. Такие энкодеры называют инкрементными или накапливающими. Сразу же после включения инкрементного энкодера положение вала неизвестно. Для привязки системы отсчёта к началу отсчёта инкрементные энкодеры могут иметь нулевые (референтные) метки, через которые нужно пройти после включения оборудования. К недостаткам также относится то, что невозможно определить пропуск импульсов от энкодера по каким-либо причинам. Это приводит к накоплению ошибки определения угла поворота вала до тех пор, пока не будет пройдена нуль-метка. Этих недостатков лишены абсолютные энкодеры. Они выдают на выходе сигналы, которые можно однозначно интерпретировать как угол поворота. Как и в приведенной выше схеме инкрементного энкодера, абсолютный оптический энкодер содержит светоизлучающий и принимающий элементы. Существенное отличие в используемом диске: он имеет прозрачные и непрозрачные участки на нескольких радиусах. Световые лучи, проходя через диск, засвечивают те или иные участки фоточувствительного элемента, который в свою очередь формирует на выходе соответствующие сигналы, уникальные для каждого положения диска. Для кодирования углового положения абсолютные энкодеры используют диски с двоичными кодами и кодами Грея. Двоичный код удобен тем, что не требует дополнительных преобразований. В целом же использование кода Грея предпочтительнее т.к. он более устойчив к ошибкам чтения за счет того, что каждое следующее значение отличается от предыдущего только в одном разряде. При этом вероятность считывания совершенно неверного значения полностью исключена. Более подробно о коде Грея можно почитать в Википедии. На следующем изображении приведены примеры дисков для инкрементного квадратурного и абсолютного энкодеров. Этот пример наглядно иллюстрирует принцип кодирования углового положения на диске абсолютного энкодера. Для каждого положения вала формируется свой уникальный код. В данном случае для кодирования 16 положений потребовалось 4 концентрических дорожки. При увеличении разрешения абсолютного энкодера возрастает число дорожек и разрядность считываемого значения. Поэтому наряду с параллельным интерфейсом в абсолютных энкодерах широко применяются последовательные интерфейсы, такие как Profibus, CANopen, SSI, BiSS, ISI, Profinet, PWM, Ethernet Powerlink, EtherNet TCP/IP, Modbus, DeviceNet, EtherCAT. Также существуют энкодеры, возвращающие значение углового положения в виде аналогового сигнала. Абсолютные энкодеры могут быть однооборотными и многооборотными. Если однооборотные способны только выдавать значение угла поворота, то многооборотные позволяют также определять количество оборотов. Это возможно за счет наличия в их составе редуктора и дополнительного диска, который изменяет свое положение при каждом полном обороте вала энкодера.

Подключение инкрементного энкодера к Ардуино

Теперь после небольшой теоретической части можно перейти к практике. Попробуем подключить к Ардуино инкрементный энкодер вращения. У меня в распоряжении имеется модуль KY-040 (вроде того, что изображен на фото в начале этой статьи), который представляет из себя энкодер с разрешением 20 шагов на оборот со встроенной кнопкой, распаянный на плату с подтягивающими резисторами. Это идеальный компонент для организации меню: вращение вала энкодера можно интерпретировать как перемещение курсора по элементам меню, а нажатие кнопки — выбор конкретного элемента. Позже я приведу пример создания такого меню, а сейчас разберемся с подключением энкодера к Ардуино. Модуль имеет 5 контактов, это:

  • CLK и DT — выводы энкодера, они подтянуты к линии питания резисторами 10кОм;
  • SW — вывод кнопки, при нажатии вывод замыкается на землю;
  • + и GND — линии питания и земли. Данный энкодер является механическим, питание для него не требуется, линии нужны для цепи с подтягивающими резисторами.

Существует 2 способа работы с энкодером: с использованием прерываний и путем опроса выводов энкодера в теле программы. Первый способ требует четкий сигнал на выводах энкодера, без помех. Поскольку данный энкодер является механическим, сигнал на его выходах искажен дребезгом контактов и не может быть использован для генерации прерываний (по крайней мере без дополнительных средств для восстановления сигнала, о чем будет рассказано позже). Поэтому сейчас реализуем второй способ и бороться с дребезгом будем программно. Загрузим в Ардуино нижеприведенный код, ссылка для скачивания.

unsignedlong CurrentTime, LastTime; enum eEncoderState {eNone, eLeft, eRight, eButton}; uint8_t EncoderA, EncoderB, EncoderAPrev; int8_t counter; bool ButtonPrev;  eEncoderState GetEncoderState() {      eEncoderState Result = eNone;   CurrentTime = millis();   if (CurrentTime - LastTime >= 5) {          LastTime = CurrentTime;     if (digitalRead(pin_Btn) == LOW ) {       if (ButtonPrev) {         Result = eButton;          ButtonPrev = ;       }     }     else {       ButtonPrev = 1;       EncoderA = digitalRead(pin_DT);       EncoderB = digitalRead(pin_CLK);       if ((!EncoderA) && (EncoderAPrev)) {          if (EncoderB) Result = eRight;              else          Result = eLeft;             }       EncoderAPrev = EncoderA;      }   }   return Result; }  voidsetup() {   pinMode(pin_DT,  INPUT);   pinMode(pin_CLK, INPUT);   pinMode(pin_Btn, INPUT_PULLUP);    Serial.begin(9600);   counter = ; }  voidloop() {   switch (GetEncoderState()) {     case eNone: return;     case eLeft: {            counter--;         break;       }     case eRight: {           counter++;         break;       }     case eButton: {          counter = ;         break;       }   }   Serial.println(counter); }

Для удобства работы код опроса энкодера помещен в отдельную функцию. В таком виде я использую ее в большинстве проектов с энкодером, достаточно скопировать функцию с переменными в новый скетч и в цикле опрашивать состояние энкодера. Подавление дребезга реализовано за счет добавления в функцию условия, которое обеспечивает опрос энкодера не чаще 1 раза в 5мс. Подобный код можно увидеть на различных сайтах, и везде говорится что вывод CLK — это сигнал A, а вывод DT — это B. Почему-то на моих энкодерах это не так и сигналы поменяны местами. Этот момент учтен в функции при чтении значений с контактов. И если вдруг у Вас окажется, что при вращении вала энкодера по часовой стрелке значение переменной counter будет уменьшаться, то замените в функции строки чтения значений с выводов pin_CLK и pin_DT на следующие:

EncoderA = digitalRead(pin_CLK); EncoderB = digitalRead(pin_DT);

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

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

Предыдущий урок     Список уроков     Следующий урок

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

Совсем коротко, о чем идет речь, т.е. о классификации энкодеров.

Энкодеры это цифровые датчики угла поворота. Другими словами преобразователи угол-код.

Я подчеркиваю, что это цифровые датчики, потому что существует большое число датчиков с выходными аналоговыми сигналами. Простой переменный резистор можно считать датчиком угла. Энкодеры формируют на выходе дискретные сигналы.

Энкодеры бывают абсолютные и накапливающие (инкрементальные).

Абсолютные энкодеры формируют на выходе код, соответствующий текущему углу положения вала. У них нет памяти. Можно выключить устройство, повернуть вал энкодера, включить и на выходе будет новый код, показывающий новое положение вала. Такие энкодеры сложные, дорогие, часто используют для подключения стандартные цифровые интерфейсы RS-485 и им подобные.

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

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

В подобных случаях инкрементальные энкодеры становятся идеальными устройствами управления, установки параметров, выбора меню. Они намного удобнее, чем кнопки ”+” и ”-”.

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

По моей партнерской ссылке механический инкрементальный энкодер с кнопкой EC11 стоит всего 50 руб. При покупке 5 штук 45 руб., при 10 — 40 руб.

Принцип действия механического инкрементального энкодера.

Импульсы на выходе инкрементального энкодера должны сообщать не только о повороте вала, но и о направлении поворота. Поэтому необходимо использовать 2 сигнала, которые обычно обозначаются A и B. Эти сигналы подключены к механическим контактам энкодера, другие выводы которых соединены на выводе C.

Если подключить к сигналам A и B подтягивающие резисторы, то диаграмма выходных сигналов при вращении энкодера будет выглядеть так.

Если вы покрутите вал энкодера, то заметите, что у него есть фиксированные положения. У моего энкодера 20 таких положений на оборот. Т.е. точность определения угла 360° / 20 = 18° или 20 импульсов на оборот.

Эти, механически зафиксированные, положения отмечены на диаграмме стрелочками снизу вверх. В этот момент оба контакта разомкнуты, сигналы A и B находятся в высоком уровне.

На первых 2 отрезках диаграммы энкодер повернули по часовой стрелке. Сначала в низкий уровень упал сигнал A, затем B. На 3 и 4 интервалах вал вращают против часовой стрелки. После фиксированного положения сначала становится равным нулю сигнал B. По последовательности изменения сигналов можно определить, в какую сторону повернули энкодер.

Формализованный алгоритм анализа сигналов энкодера выглядит так.

  • Если в момент перехода сигнала A в низкое состояние сигнал B находится в высоком уровне, то произошел поворот по часовой стрелке.
  • Если в момент перехода сигнала A в низкое состояние сигнал B находится в низком уровне, то был поворот против часовой стрелки.

Возможны другие кодировки положения энкодера. Все, что я пишу верно, относительно EC11.

Параметры инкрементальных энкодеров.

Подробно технические характеристики и параметры энкодера EC11 в формате PDF можно посмотреть по этой ссылке EC11.pdf. Я приведу и поясню основные.

  • Главный параметр – число импульсов на оборот. Определяет точность измерения угла. У моего датчика 20 импульсов на оборот, точность 18°.
  • Предельно допустимые электрические параметры определяют предельные значения тока и напряжения для контактов. В моем случае это 10 мА и 5 В. Эти параметры влияют на выбор подтягивающих резисторов. Сопротивление резисторов не должно быть ниже 500 Ом.
  • Прочность изоляции. Я бы не рискнул использовать подобный энкодер в цепях, гальванически связанных с высоким напряжением.
  • Износоустойчивость. Разработчики гарантируют от 15 000 до 1 000 000 циклов, в зависимости от модификации.
  • Рабочий диапазон температур -30 … +85 °C.
  • Механические параметры: габаритные и установочные размеры, моменты вращения и т.п.

Подключение энкодера к плате Ардуино.

С электрической точки зрения энкодер это 3 кнопки: сигналы A, B и кнопка. Я использовал внутренние подтягивающие резисторы, но в рабочих схемах лучше добавить внешние резисторы сопротивлением 2 – 10 кОм.

Программная обработка сигналов энкодера.

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

void setup() {  Serial.begin(9600); // инициализируем порт, скорость 9600  pinMode(2, INPUT_PULLUP); // определяем вывод как вход  pinMode(8, INPUT_PULLUP); // определяем вывод как вход}void loop() {  if( digitalRead(2) == HIGH ) Serial.print(«H «);   else Serial.print(«L «);  if( digitalRead(8) == HIGH ) Serial.println(«H»);   else Serial.println(«L»);  delay(200); }

У меня энкодер подключен к выводам 2 и 8. Программа в цикле выводит через последовательный порт состояния сигналов A и B.

Все как на диаграмме выше.

Алгоритм обработки сигналов энкодера простой:

  • выделяем отрицательный фронт сигнала A;
  • считываем состояние сигнала B;
  • если у сигнала B:
    • высокий уровень – был поворот по часовой стрелке;
    • низкий  уровень – был поворот против часовой стрелки.

Но у механического энкодера механические контакты. Им свойственно явление дребезга. К тому же энкодеры часто устанавливаю на передней панели устройства, и подключают к контроллеру достаточно длинными проводами. Т.е. нужна цифровая фильтрация сигналов и устранение дребезга. Все это реализовано в моей библиотеке Button.h. Ее вполне можно использовать для работы с энкодером.

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

#include #include <button>

Button encoderA (2, 4); // сигнал AButton encoderB (8, 4); //  сигнал BButton encoderButton(10, 40); // кнопка

long pos=0; // пооложение энкодера

void setup() {  Serial.begin(9600); // инициализируем порт, скорость 9600  Timer1.initialize(250); // инициализация таймера 1, период 250 мкс  Timer1.attachInterrupt(timerInterrupt, 250); // задаем обработчик прерываний}

void loop() { // сброс положения   if( encoderButton.flagClick == true ) {    encoderButton.flagClick= false;    pos= 0;  }  Serial.println(pos); // вывод положения}

// обработчик прерывания 250 мксvoid timerInterrupt() {  encoderA.filterAvarage(); // вызов метода фильтрации  encoderB.filterAvarage(); // вызов метода фильтрации   encoderButton.filterAvarage(); // вызов метода фильтрации

// обработка сигналов энкодера  if( encoderA.flagClick == true ) {    encoderA.flagClick= false;      if( encoderB.flagPress == true) {        // против часовой стрелки        pos—;      }      else {        // по часовой стрелке        pos++;      }  } }

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

Вопрос, с какой частотой необходимо опрашивать энкодер. У меня в программе цикл прерывания 250 мкс и 4 выборки при фильтрации. В итоге период реакции на изменения состояния сигналов 1 мс.

Все зависит от того с какой частотой сигналы энкодера могут изменять свое состояние. А это определяют максимальная скорость вращения энкодера и параметр — число импульсов на оборот.

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

  • Запомнить механическое положение вала.
  • Сбросить вычисленное положение кнопкой (привязать к механическому положению).
  • Теперь сколько бы вы ни вращали вал, при попадании в механическое положение, к которому он был привязан, на экране должно быть значение кратное числу импульсов на оборот. В моем случае это 0,20, 40…

Библиотека Encod_er.h.

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

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

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

Для реализации этого алгоритма необходимо вычислять скорость вращения энкодера. Я разработал библиотеку обработки энкодера с этой функцией.

Загрузить библиотеку Encod_er.h можно по этой ссылке:

 Зарегистрируйтесь и оплатите. Всего 40 руб. в месяц за доступ ко всем ресурсам сайта! 

Описание класса Encod_er.

Я привел только public свойства и методы.

class Encod_er {  public:    Encod_er(byte pinA, byte pinB, byte timeFilter);    byte timeRight; // время/признак вращения вправо (* 8 периодов)    byte timeLeft; // время/признак вращения влево (* 8 периодов)    long position; // текущее положение     void scanState(); // метод проверки состояния    long read(); // метод чтения положения };

Encod_er(byte pinA, byte pinB, byte timeFilter)  — конструктор.

  • pinA – вывод сигнала A;
  • pinB – вывод сигнала B;
  • timeFilter – число выборок фильтрации сигналов.

Encod_er myEncoder(2, 3, 5);   // энкодер к выводам 2 и 3, 5 выборок фильтрации

void  scanState() – метод сканирования состояния энкодера. Должен вызываться регулярно в параллельном процессе.

// обработчик прерывания 250 мксvoid timerInterrupt() {  myEncoder.scanState(); }

byte timeRight и timeLeft – признаки поворота энкодера соответственно вправо и влево. Если равны 0, то поворота не было. Если не равны 0, то содержат время поворота на один шаг. Время вычисляется, как

Tповорота = Tвызова scanState()  * 8 * timeRight.

Т.е. единица значения timeRight или timeLeft это период вызова scanState(),  умноженный на 8. В моей программе это 250 мкс * 8 = 2 мс. На 8 я умножил, чтобы использовать один байт. Значение переменных  timeRight или timeLeft ограничиваются на уровне 255.

Если признаки используются, то должны сбрасываться  в основном цикле.

if(encoder.timeRight != 0) {  encoder.timeRight= 0;……….. }

long  position – текущее положение энкодера. Может быть прочитано или записано.

long  read() – метод чтения положения энкодера. Возвращает переменную position.

Все просто. Предыдущую программу можно переписать с использованием библиотеки Encod_er.h.

#include #include <encod>

Encod_er encoder( 2, 8, 4);

void setup() {  Serial.begin(9600); // инициализируем порт, скорость 9600  Timer1.initialize(250); // инициализация таймера 1, период 250 мкс  Timer1.attachInterrupt(timerInterrupt, 250); // задаем обработчик прерываний}

void loop() {  if(encoder.timeRight != 0) {    Serial.print(«R=»);    Serial.print(encoder.timeRight);    Serial.print(» Pos=»);     Serial.println(encoder.read()); // вывод текущего положения     encoder.timeRight= 0;  }  if(encoder.timeLeft != 0) {    Serial.print(«L=»);    Serial.print(encoder.timeLeft);    Serial.print(» Pos=»);     Serial.println(encoder.read()); // вывод текущего положения    encoder.timeLeft= 0;  } }

// обработчик прерывания 250 мксvoid timerInterrupt() {  encoder.scanState(); }

На каждый поворот вала в монитор последовательного порта выводится направление вращение и значение timeRight или timeLeft.

Обработку кнопки энкодера я в библиотеку не включил. Кнопку лучше обрабатывать библиотекой Button.h.

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

Анализировал признаки timeRight и timeLeft. При ненулевом значении признаков шаговый двигатель перемещения шпинделя делал количество шагов в зависимости от значения активного признака. Зависимость задал в массиве.

Предыдущий урок     Список уроков     Следующий урок

Поддержать проект

СОДЕРЖАНИЕ ►

Энкодер Ардуино, а точнее модуль KY-040 очень часто используется в проектах для управления различными устройствами от платы Arduino. В этом обзоре мы рассмотрим схему подключения модуля к микроконтроллеру, а также представим сразу несколько примеров с использованием датчика для включения и управления яркостью светодиодов, вращение сервопривода с помощью энкодера и платы Arduino.

Модуль энкодер Ардуино: схема, распиновка

Энкодер служит для преобразования угла поворота в электрический сигнал. При вращении ручки модуля мы получаем два сигнала (A и B), которые противоположны по фазе. Сигналы A и B зависят друг от друга при вращении энкодера Ардуино по часовой или против часовой стрелки. Для считывания сигнала A и B с энкодера можно использовать, как цифровые, так и аналоговые порты микроконтроллера.

encoder-raspinovka.jpg
Распиновка и принципиальная схема модуля энкодера

Каждый раз, когда сигнал A переходит от положительного уровня к нулю, мы считываем значение сигнала B (смотри диаграмму выше). Если сигнал B находится в этот момент в положительном состоянии, значит энкодер вращается по часовой стрелке, если B равен нулю, то энкодер вращается против часовой стрелки. Считывая оба выхода при помощи Ардуино, можно определить направление и угол поворота.

Как подключить энкодер к Ардуино

Для занятия нам понадобятся следующие детали:

  • плата Arduino Uno / Arduino Nano / Arduino Mega;
  • модуль энкодер ky-040;
  • беспаечная макетная плата;
  • светодиоды и резисторы;
  • микро сервопривод;
  • провода «папа-папа», «папа-мама».

Для работы с энкодером потребуется установить библиотеку RotaryEncoder.h, скачать архив можно здесь. Если у вас возникли трудности с установкой библиотеки для энкодера, то рекомендуем ознакомиться с информацией, как установить библиотеку в Arduino IDE. Для подключения KY-040 к Arduino можно использовать цифровые и аналоговые пины микроконтроллера, в наших примерах используются пины A1-A3.

Скетч. Пример Ардуино энкодер прерывание

encoder-arduino.jpg
Схема подключения энкодера к Ардуино (модуль KY-040)

Разберем для начала самый простой пример управления энкодером от Ардуино с помощью прерываний, где вся черновая работа по определению положения ручки энкодера выполняется с помощью библиотеки RotaryEncoder.h. Мы лишь выводим данные на монитор порта Arduino IDE. Соберите схему с энкодером, как показано на картинке выше и загрузите в микроконтроллер Arduino следующую программу.

#include"RotaryEncoder.h"// библиотека для энкодера  RotaryEncoder encoder(A2, A3);  // пины подключение энкодера (DT, CLK)static int pos = 0;  // задаем начальное положение энкодераint newPos;    voidsetup() {    Serial.begin(9600);    Serial.println(pos);  // выводим на монитор начальное значение  }    voidloop() {     // проверяем положение ручки энкодера     encoder.tick();     newPos = encoder.getPosition();       // если положение изменилось - выводим на мониторif (pos != newPos) {        Serial.println(newPos);        pos = newPos;      }  }

Пояснения к коду:

  1. начальное положение ручки равно нулю static int pos = 0; и это значение выводится на мониторе порта в процедуре void setup в начале программы;
  2. в примере программы для энкодера нет ограничения по положению рукоятки датчика KY-040, положение может быть положительным и отрицательным.

Скетч. Управление энкодером Ардуино светодиодом

encoder-knopka-arduino.jpg
Как подключить энкодер для управления светодиодами

Следующий пример позволит управлять яркостью светодиода с помощью ШИМ сигнала, а также включать и выключать второй светодиод с помощью нажатия кнопки энкодера. Для этого соберите схему, размещенную выше. Обратите внимание, что порт SW энкодера подключен к пину 2 Arduino, а светодиоды к 12 и 11 пину. После сборки схемы загрузите следующий код управления светодиодами на Arduino с энкодером.

#include"RotaryEncoder.h"// библиотека для энкодера  RotaryEncoder encoder(A2, A3);  // пины подключение энкодера (DT, CLK)// задаем шаг энкодера и макс./мин. значение#define STEPS  5  #define POSMIN 0  #define POSMAX 255    int lastPos, newPos;    voidsetup() {     pinMode(2, INPUT_PULLUP);  // пин подключения кнопки энкодера (SW)pinMode(11, OUTPUT);           // пины для подключения светодиодовpinMode(12, OUTPUT);       Serial.begin(9600);     encoder.setPosition(10 / STEPS);  }    voidloop() {     // проверяем положение ручки энкодера     encoder.tick();     newPos = encoder.getPosition() * STEPS;       if (newPos < POSMIN) {      encoder.setPosition(POSMIN / STEPS);      newPos = POSMIN;     }     else if (newPos > POSMAX) {      encoder.setPosition(POSMAX / STEPS);      newPos = POSMAX;      }     // если положение изменилось - выводим на мониторif (lastPos != newPos) {        Serial.println(newPos);        lastPos = newPos;     }       // включаем первый светодиод с установленной яркостьюanalogWrite(11, lastPos);       // включаем второй светодиод с помощью нажатия кнопкиif (digitalRead(2)==HIGH) { digitalWrite(12, LOW);  }     if (digitalRead(2)==LOW)  { digitalWrite(12, HIGH); }  }

Пояснения к коду:

  1. для пина 2 используется конфигурация INPUT_PULLUP, так как кнопка энкодера подключена к GND и при ее нажатии на цифровом входе будет сигнал LOW;
  2. в программе можно изменить максимальное и минимальное значение поворота энкодера, а также шаг вращения ручки датчика ky-040.

Скетч. Управление серво мотором от энкодера

encoder-servo.jpg
Управление микро серво от энкодера Ардуино Уно

Следующий скетч демонстрирует подключение серво с энкодером. Логический провод микросерво (желтый или оранжевый цвет) подключается к ШИМ порту 11 микроконтроллера. В программе задается угол поворота серво с помощью поворота ручки модуля ky-040. Работа программы похожа на управление потенциометром серво, но в случае с энкодером, можно задавать максимально точный угол поворота.

#include"RotaryEncoder.h"// библиотека для энкодера  RotaryEncoder encoder(A2, A3);  // пины подключение энкодера (DT, CLK)#include<Servo.h>          // библиотека для сервоприводаServo servo;    // задаем шаг энкодера, макс./мин. значение поворота#define STEPS  10  #define POSMIN 0  #define POSMAX 180    int lastPos, newPos;    voidsetup() {     servo.attach(11);    // пин для подключения сервоSerial.begin(9600);     encoder.setPosition(10 / STEPS);  }    voidloop() {     // проверяем положение ручки энкодера     encoder.tick();     newPos = encoder.getPosition() * STEPS;       if (newPos < POSMIN) {      encoder.setPosition(POSMIN / STEPS);      newPos = POSMIN;     }     else if (newPos > POSMAX) {      encoder.setPosition(POSMAX / STEPS);      newPos = POSMAX;      }     // если положение изменилось - выводим на мониторif (lastPos != newPos) {        Serial.println(newPos);        lastPos = newPos;     }     // устанавливаем угол поворота микросерво     servo.write(lastPos);  }

Пояснения к коду:

  1. шаг поворота качалки серво Ардуино составляет 10 градусов. Шаг поворота и максимальный угол поворота можно изменить в программе.

Заключение. Мы рассмотрели несколько вариантов подключения модуля энкодера к Arduino: пример с прерыванием и управлением светодиодом, пример с управлением мотором серво. Также модуль можно использовать для управления меню на дисплее 1602 LCD Ардуино. Мы использовали библиотеку RotaryEncoder.h, но есть еще несколько библиотек энкодера для Ардуино, которые в одном обзоре не уместить.

Используемые источники:

  • /2017/09/blog-post.html
  • http://mypractic.ru/urok-55-rabota-s-inkrementalnym-enkoderom-v-arduino-biblioteka-encod_er-h.html
  • https://xn--18-6kcdusowgbt1a4b.xn--p1ai/%d1%8d%d0%bd%d0%ba%d0%be%d0%b4%d0%b5%d1%80-%d0%b0%d1%80%d0%b4%d1%83%d0%b8%d0%bd%d0%be/

Рейтинг автора
5
Подборку подготовил
Максим Уваров
Наш эксперт
Написано статей
171
Ссылка на основную публикацию
Похожие публикации