Подключаем энкодер к AVR

Наконец то у меня появилась эта замечательная крутилка и теперь я хочу рассказать вам как с ней работать. Мой энкодер (EC12E24204A9)  представляет из себя примерно следующее:

Энкодер имеет три контакта: Общий, А и В. Общий обычно всегда подключается к земле а два других к любым пинам микроконтроллера. Выводы А и В должны быть подтянуты к плюсу питания через резисторы порядка 10 кОм, чтоб исключить ложные срабатывания от наводок. Использовать внутреннюю подтяжку микроконтроллера я бы не посоветовал. Уж очень она слабая.  Для демонстрации работы, повесим еще 8 светодиодов. (примечание: Если используется мега16, мега32  и старше то необходимо выключить jtag иначе половина светодиодов гореть не будет)
Итак получили следующую схему:


Крутим ручку энкодера вправо — огонек бежит вправо. Крутим влево — огонек бежит влево.  Как работает энкодер? Будем разбираться. Ничего сложного нет. Посмотрим на графики ниже.
При  вращении энкодера в одну сторону сигнал выглядит  так:

Подключаем энкодер к AVR

В другую:

Подключаем энкодер к AVR

Возникает вопрос, а как же микроконтроллеру различить направление вращения энкодера ?

Существуют два популярных алгоритма опроса энкодера:

  • Опрос при помощи прерываний
  • Опрос со сравнением предыдущего состояния энкодера и текущего

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

Исходник

Подключаем энкодер к AVR: 30 комментариев

  1. Я пытался, пытался присоединить Н-кодер, но так ничего толкового ен получилось. А вообще, если успешно его внедрить в свои конструкции то это решение всех проблем напрмиер с меню, и тд. тп. Три кнопки влево, вправо и выбрать.

  2. Слушай а на Си нету программы а то я в асме ноль, для меня это просто бессмысленный набор символов. И если можно подробней об алгоритме а то не много не понял. Я пробовал но дребезг такой что мама родная…

  3. Почему и тут) пишут, что жалко отдавать прерывание под энкодер, что прерывание можно использовать под что-то длругое? Это вы про INTx? Там же на каждой ножке есть PCINT, их как доктор прописал для кнопок и энкодеров.
    Дребезг… на таймере, по-другому никак.
    И с внутренней подтяжкой нормально работает.

  4. А можно мне алгоритм для этой программы, плиз. Мне очень нужно, у меня курсовая на тему программирования энкодера, правда мне нужно выводить на цифровую идикацию. Может чем-нибудь поможете, а то я совсем в программировании не разбпраюсь((( И я не могу понять зачем в этой программе в начале столько выходов из прерывания и зачем бесконечный цикл?????Помогите пожалуйста!!!!!!!!!!!!

    1. Когда возникает прерывание, микроконтроллер начинает выполнять код расположенный по определённому адресу (в зависимости от того какое прерывание произошло). Выходы из прерываний это своего рода «заглушки» они нужны для того чтобы строчка rjmp Scan; TIM0_COMP была размещена по определённому адресу в памяти. Потому что когда возникнет прерывание от таймера нужно перейти на метку Scan и начать опрос энкодера. Все эти reti которые ниже строчки rjmp Scan; TIM0_COMP можно не писать. ничего от этого не изменится.

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

      Скорее всего могу написать нужную программу. За деньги разумеется. Если заинтересованы пишите на Sasha__05@mail.ru как можно подробней опишите что требуется.

    1. Андрей. Схема подключения аналогичная. Энкодер на PB0 и PB1.
      6 светодиодов на PC0-PC5.
      Меняешь только сдвиг влево, т.к. двигаем не 8, а 6 светодиодов.
      В LeftShift вместо «cpi temp,0b10000000» пишешь «cpi temp, 0b00100000»

  5. //3 ) При прошлом опросе Пин В=1 и Пин А=0 ?
    Cpi OldState,2
    brne Cpi3 //Если нет то проверяем другое условие
    Cpi NewState,3
    brne Cpi31
    Rcall RightShift
    Cpi31:
    Cpi NewState,0
    brne Cpi12 !!!!!!!!!!!!
    rcall LeftShift
    Cpi32:
    mov OldState,NewState //То что было новым состоянием энкодера, стало старым…
    reti

    строчка «brne Cpi12». По идее, прыгнуть нужно на «brne Cpi32». Или здесь логический подвох?)

  6. При проверке энкодера (снял с DVD Samsung) иногда появлялся странный дребезг. Кручу в одну сторону с постоянной скоростью, огонёк бежит-бежит в эту же сторону, и вдруг меняет направление. Потом опять нормально бежит.
    Пробовал подтянуть на плюс резисторами по 10кОм. Не помогло. Переписывал код и перепроверял на 10 раз подключения — не помогло.
    Косяк нашёлся просто. портВ -ввод, портС — вывод. Добавил портD на вывод состояния входа, т.е.

    rcall delay \\задержка прописана отдельной процедурой на 1-20 милисекунд
    in r16, portB \\читаем фазы
    andi r16, 0b00000011 \\зачищаем всё, кроме 2-х последних бит
    out portD, r16\\выводим то, что творится на входе

    кручу, значит…
    и тут всё понятно! дребезжит сам энкодер, и вместо 00 01 11 10
    выдаёт иногда что-то типа 00 01 10 11. или 00 10 00 11

    четыре строчки кода — и наглядно видно, где и как ведёт себя крутилка.

      1. Как это сделать? В инете такой информации практически нет, желательно подключить энкодер к lpt на прямую, без МК. Если есть схемы подключения и программы, или скрипты, можно ссылки?

  7. Спасибо!
    Ещё вопрос по подпрограмме.
    Зачем вставлена команда brne exitRS. В тексте я обозначил серией вопросительных знаков. Вероятно для сброса флага переноса после воздействия команды lsr temp ?

    RightShift:
    cpi count,4 //Состояние пинов сменилось 4 раза?
    brne exitRS
    ///////Здесь можно вставить свой код////////////
    //////Который будет срабатывать если крутим в право///
    //////В демонстрационном примере мы двигаем огонек=)
    clr count
    in temp,portc
    cpi temp,0b00000001
    breq exitRS2
    lsr temp
    out PORTc,temp
    //////////////////КОНЕЦ СВОЕГО КОДА/////////////
    brne exitRS //?????????????????????????????????????????????????
    exitRS:
    inc count
    exitRS2:
    ret

  8. Новенький энкодер PEC12 (похожий как на фото вверху) безбожно дребезжит. Легко может остановиться между двумя щелчками (нет чёткой фиксации положения оси) и начинает самопроизвольно хаотично выдавать импульсы. Даже не могу представить куда вообще можно применять такие энкодеры, если только для грубой регулировки в дешёвой бытовой аппаратуре. Короче хлам, видимо из китая. Я разочарован.

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

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

Добавить комментарий