Энкодер ардуино библиотека – Подключение модуля энкодера (KY-040) к Arduino и создание простейшего счетчика импульсов.

Работаем в Arduino с энкодерами

Решил тут на досуге поиграться с ардуинкой. Есть у меня кучка китайских энкодеров и вот руки наконец дошли их протестировать с Arduino и заодно разобраться с вопросом их подключения и использования.

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

Подробно разобран вот тут http://cxem.net/arduino/arduino8.php
В общем-то не скажу, что мне этот способ интересен — греть воздух и тратить энергию опрашивая энкодер в большинстве случаев лишь пустая трата ресурсов поэтому останавливаться на нём не буду.

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

Неплохой материал по теме нашёл тут http://www.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino и уже было дело ломанулся попробовать живьём, но тут мне попалась на глаза библиотечка с нехитрым названием Encoder, в которой вся грязная работа уже сделана и к тому-же утверждается, что процедуры обработки прерываний написаны на ассемблере и таким образом можно ожидать достаточно высокой производительности.

Библиотека достаточно универсальна — подключенный энкодер может работать в следующих режимах

  • наилучшая производительность: оба сигнала генерируют прерывания.
  • хорошая производительность: один сигнал генерирует прерывание — второй нет (не совсем понял — видимо второй пин опрашивается)
  • низкая производительность: оба пина опрашиваются

В комплекте идут примеры кода в виде ардуино скетчей.

Для начала качаем библиотеку Encoder.zip (version 1.2), распаковываем её в папку для библиотек настроенную в IDE. Пробуем скетч из комплекта библиотеки.



#include <Encoder.h>





Encoder myEnc(5, 6); 

void setup() {
  Serial.begin(9600);
  Serial.println("Basic Encoder Test:");
}

long oldPosition  = -999;

void loop() {
  long newPosition = myEnc.read();
  if (newPosition != oldPosition) {
    oldPosition = newPosition;
    Serial.println(newPosition);
  }
}

Библиотека прекрасно работает. Проверено!

www.diytronic.ru

Маленькая и быстрая библиотека для энкодера: elchupanibrei

Давно хотел разобраться с «крутилкой». Наконец появилось время и желание это сделать. В паутине нашел три метода обработки кода грея для энкодера.

Первый самый примитивный. Использует тонны if else и програмный debounce на millis(). Работает медленно. Вот скриншот такой копипасты.


энкодер курильщика и ардуино головного мозга
С переходными процессами в этом примере разбираются без таймера. Тупо ждут микросекунду. Шах и мат перфекционисты. Вторая особенность — вешают функцию onA() на первое прерывание, а onB() на второе. Зачем? Никто не запрещает читать encoder_A_Pin вместе с encoder_B_Pin при срабатывании внешнего прерывания на onA(). Освободившийся interrupt можно использовать для кнопки или второго энкодера.

Второй метод на основе массива всех возможных состояний энкодера. А их не много не мало 16 штук. Достоинства. Простота кода. Чуть-чуть быстрее if else. Автоматический debounce — все ложные состояния отбрасываются. Правда при сильном дребезге, через раз отбрасываются и истиные значения. Лечится добавлением 100nF/0.1uF кондесаторов между ногами энкодера и землей.


таблица состояний энкодера
Самы продвинутый — это доработанный второй. Из 16 состояний вырезаются все ненужные. Какая нам польза от того что мы будем знать где крутилка до/после клика? На основе оставшихся 4-х с помощью булевой алгебры и switch case делается простейший счетчик. Все! Правда есть нюанс. ATmega328 и реализация метода digitalRead() оказались настолько медленными, что камень не успевал читать значения pinA и pinB при срабатывании внешнего прерывания на pin A. Поэтому для AVR пришлось использовать прерывание по Timer1. Каждые 0.01 секунд таймер не спеша читает состояние пинов и обновляет счетчик энкодера. Для быстрых STM32 и ESP8266 все работает на внешнем прерывании по изменению состояния pinA. Как только энкодер начинает крутиться, срабатывает внешнее прерывание, считываются значения pinA и pinB и обновляется позиция энкодера.
энкодер здорового человека
Обязательно добавить два конденсатора по 100nF/0.1uF как показано на картинке, иначе будут пропуски! Библиотека подсчитывает только физические клики, оставляя все лишнее за бортом. Внутренняя подтяжка включена, но дополнительные резисторы приветствуются. Без них, на длинных проводах и сильных помехах могут появляться ложные срабатывания. У популярного шилда KY-040 10КОм уже есть на плате.
железный debounce и дополнительная подтяжка

расшифровка контактов KY-040
UDP: Переписал код. Теперь еще быстрее, меньше в размере и винарнее. Для кого-то недостаток, для кого-то достоинство, но теперь без аппаратных прерываний не работает. Спасибо товарищу kotyamba за консультацию и знания.

UDP2: Пришлось опять переписать код. Как правильно заметил ksergey9 в комментариях, наше с kotyamba творение более менее нормально работало на медленном AVR. Как только его запускали на быстрых Cortex все превращалось в тыкву. Тепрь все ОК. Лично проверил на Arduino Nano 16Mhz, STM32 Blue Pill и ESP8266.

UDP3: Воспользовался ООП и путем наследования сделал тяжелый класс с float — «RotaryEncoderAdvanced». В нем можно прописывать количество шагов на клик, минимальное и максимальное значение. Получился законченный велосипед. Естественно легкий класс «RotaryEncoder» никуда не делся и работает так же как и раньше.

Забирать как всегда тут.

elchupanibrei.livejournal.com

Arduino. Внешние прерывания. Подключение энкодера

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

Подготовка к работе

На нашей плате TutorShield установлены две кнопки, которые подключены к цифровым выводам D2 и D3. Подробно подключение кнопок описано в предыдущей статье цикла. Помимо них, для дальнейших экспериментов подключим еще две секции трехцветного светодиода (к выводам D9 и D10). Установите перемычки так, как показано на рисунке:

Установка перемычек

Первый пример

В предыдущем примере для обработки кнопок мы настраивали вывод микроконтроллера на вход и постоянно контролировали его состояние. Это не самый эффективный способ, так как при этом трудно заставить микроконтроллер делать что-то помимо опроса кнопок. Специально для этих целей можно использовать прерывания.
Прерывание — это функция микроконтроллера, которая при наступлении какого-либо события позволяет остановить выполнение основной программы и обработать произошедшие события. Например, прерывание можно использовать для обработки приема сигналов COM-порта: микроконтроллер выполняет основную программу, а когда модуль UART сообщает о завершении передачи, то МК прерывает работу и обрабатывает принятый байт. Прерывании в микроконтроллере Atmega8 ровно девятнадцать штук и два из них — это внешние прерывания, вызывающие при изменении напряжении на выводе D2 иди D3 Arduino-совместимой платы.
Рассмотрим работу с прерываниями на конкретном примере:


#define LED 11

void setup() {
    attachInterrupt(0, button1, RISING);
    attachInterrupt(1, button2, RISING);
    pinMode(LED, OUTPUT);
}

void loop() {
}

void button1() {
    digitalWrite(LED,HIGH);
}

void button2() {
    digitalWrite(LED,LOW);
}

Для работы с внешним прерыванием в первую очередь его надо инициализировать. Этим занимается функция attachInterrupt(pin,ISR,mode). У этой функции три параметра:

  • pin — номер вывода, на который настроено прерывание. Для платы EduBoard с МК Atmega8 прерывание может быть настроено только на 2ом и 3ем выводе
  • ISR — имя функции-обработчика прерывания
  • mode — режим работы прерывания, может принимать четыре значения. LOW — вызывает обработчик прерывания, когда на выводе низкое напряжение, CHANGE — при изменении, RISING — при переходе от низкого к высокому уровню, FALLING — от высокому к низкому

В приведенном примере настроено два прерывания. Прерывание «0» вызывает обработчик button1() при изменении напряжения с низкого на высокий уровень на выводе D2. Прерывание «1» вызывает обработчик button2() при изменении напряжения с низкого на высокий уровень на выводе D3.
В обработчике прерывания button1() зажигается светодиод, а при обработке прерывания button2() он гасится. То есть при нажатии на кнопку, подключенную к выводу D2 светодиод включится, а при нажатии D3 — выключится.

Второй пример

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


#define LED 11

int val = 0;

void setup() {
    attachInterrupt(0, button1, RISING);
    attachInterrupt(1, button2, RISING);
    pinMode(LED, OUTPUT);
    Serial.begin(9600);
}

void loop() {
    Serial.println(val);
    delay(500);
}

void button1() {
    digitalWrite(LED,HIGH);
    val++;
}

void button2() {
    digitalWrite(LED,LOW);
    val--;
}

После загрузки кода на плату, откройте монитор COM-порта (Ctrl+Shift+M) и посмотрите на то, как изменяются данные при нажатии на кнопки. Чаще всего все будет работать правильно, но иногда переменная будет меняться не на единицу, а сразу на два за одно нажатие. Это значит, что из-за дребезга контактов прерывание было вызвано несколько раз.
В каких-то ситуациях это не имеет большого значения. Чем лучше мы будем предотвращать дребезг контактов, там выше будет риск пропуска нажатия. Есть много способов борьбы с дребезгом контактов, как программных, так и аппаратных. Пока мы не будем останавливаться на них.

Обработка энкодера

На нашем шилде установлен инкрементальный энкодер. По своему виду он похож на переменный резистор, но работает он совершенно по-другому. Вы могли встречать инкрементальные энкодеры в регуляторах громкости с бесконечным вращением.
Мы не будем подробно описывать принцип работы энкодера. Самое главное для нас то, что при вращении на его двух выводах формируется импульсные последовательности сдвинутые по фазе. Фазовый сдвиг может быть положительным и отрицательным в зависимости от направления вращения. Для обработки энкодера необходимо один его вывод настроить на прерывания и в прерывании проверять состояние второго вывода. Если он в высоком состоянии, то значит энкодер вращали по-часовой стрелке. Если на входе низкое напряжение — то против. Рассмотрим на примере:


#define LED 11

int val = 0;

void setup() {
    attachInterrupt(0, button1, RISING);
    pinMode(LED, OUTPUT);
    pinMode(3, INPUT);
}

void loop() {
    if(val<0) val = 0;
    if(val>255) val = 250;
    analogWrite(LED,val);
}

void button1() {
    if( digitalRead(3) == HIGH) val=val+10;
    else val=val-10;
}

В результате работы этой программы при вращении энкодера по-часовой яркость светодиода будет увеличиваться, а при вращении против часовой — уменьшаться. Изменение яркости происходит с шагом в 10 единиц. Чтобы переменная не вышла за пределы нормальных значений в основном цикле она нормируется.

Индивидуальные задания

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

Остальные статьи цикла можно найти здесь.

Мы будем очень рады, если вы поддержите наш ресурс и посетите магазин наших товаров shop.customelectronics.ru.

www.customelectronics.ru

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

Научно-технические

Главная  Статьи, аналитика  Научно-технические

«Научно-технические статьи» — подборка научно-технических статей радиоэлектронной тематики: новинки электронных компонентов, научные разработки в области радиотехники и электроники, статьи по истории развития радиотехники и электроники, новые технологии и методы построения и разработки радиоэлектронных устройств, перспективные технологии будущего, аспекты и динамика развития всех направлений радиотехники и электроники, обзоры выставок радиоэлектронной тематики.


Для начала разберёмся детальнее, что такое энкодер.

Энкодер – это устройство, предназначенное для определения угла поворота и преобразующее данные в электрический сигнал. Другое название энкодера – «датчик угла поворота».

По выходному сигналу различают:

  • Инкрементные энкодеры — на выходе формируется две последовательности импульсных сигналов (нулей и единиц), при этом каждая «единица» соответствует фиксированному углу (зависит от точности датчика). Отслеживание полного поворота происходит по специальному сигналу (программному), а направление вращения определяется по смещению второй последовательности относительно первой. Для понимания принципа работы инкрементных датчиков угла лучше всего изучить изображение ниже.

Рис. 1. Изображение выходного сигнала инкрементного энкодера

С анимацией.

Рис. 2. Схема инкрементного энкодера

  • Абсолютные энкодеры – на выходе формируются не просто «единицы», а сразу последовательности фиксированной длины (зависит от точности измерения), которые явно говорят о конкретном угле, то есть значение угла поворота специальным образом кодируется (код Грея). Понять принцип его работы лучше поможет следующая схема.

Рис. 3. Схема принципа работы абсолютного энкодера

Или эта.

Рис. 4. Схема принципа работы абсолютного энкодера

Конструктивно (в зависимости от технологии измерения) экодеры могут быть:

  • Оптическими;
  • Магнитными;
  • Резисторными.

Подключение и работа с энкодерами в Arduino в первую очередь зависит от способа кодирования угла.

Начнём с инкрементных датчиков.

Подключение инкрементных энкодеров

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

Рис. 5. Типовая схема

Здесь приведён пример с использованием энкодера с кнопкой (есть и такие модели, кнопкой служит сама ручка).

При использовании Atmega можно просто включить встроенные резисторы микроконтроллера специальной командой.

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

Рис. 6. Типовая схема

Существует и программный способ сглаживания дребезга за счёт использования логики прерываний (смотри скетч во вложениях к материалу). Но подключение прибора следует выполнять только на 2 и 3 пины.

Простейший код для обработки данных с датчика выглядит следующим образом.

Для более сложных задач можно использовать готовые библиотеки, например:

  • https://github.com/GreyGnome/AdaEncoder
  • https://github.com/PaulStoffregen/Encoder
  • https://github.com/mathertel/RotaryEncoder
  • и другие.

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

Отрабатывается перемещение по иерархии меню и выбор между доступными пунктами.

Подключение абсолютных энкодеров

Абсолютные энкодеры не так распространены, как инкрементные. И схема подключения во многом зависит от требований производителя. Так, например, высокоточный 128-битный датчик Bourns ACE-128 легко подключается к Ардуино или Raspberry Pi. Производитель предлагает свои собственные библиотеки для работы с энкодером и даже типовую схему для тестирования функционала.

Схема соединения выглядит так.

Рис. 7. Схема соединения энкодеров

А схема для тестирования с выводом числового показателя угла поворота на дисплей, так.

Рис. 8. Схема для тестирования с выводом числового показателя угла поворота на дисплей

Готовая библиотека для Arduino, подробные инструкции и примеры скетчей можно найти на ГитХабе: https://github.com/arielnh56/ACE128

Аналогично и с изделиями других производителей – необходимо изучать их рекомендации.

Автор: RadioRadar

Дата публикации: 10.05.2018

Мнения читателей

Нет комментариев. Ваш комментарий будет первый.

Вы можете оставить свой комментарий, мнение или вопрос по приведенному вышематериалу:

www.radioradar.net