Еще один способ опроса энкодера


Мне известно два метода обработки энкодера: по прерыванию (от INT0,INT1,PCINT…)
и сравнение предыдущего состояния энкодера и текущего ( easyelectronics.ru/avr-uchebnyj-kurs-inkrementalnyj-enkoder.html ). Я предлагаю еще один способ, который заключается в следующем: при вращении ручки энкодера, ждем когда оба канала станут нулями, после чего начинаем подсчет сколько времени/раз каждый канал был в единице пока они оба не станут равными лог. «1»

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

Код на ассемблере получился довольно компактный и использует всего лишь три регистра (R16,RegA,RegB). В общем скомпилил, залил – работает! Исходники прикрепил в конце статьи.
Но такой метод опроса оказался не очень удачный и правильный. Как говорится одна голова хорошо, а две — почти змей горыныч -)) Благодаря предложению от steel_ne «родился» такой алгоритм:

В этом случае используем всего два регистра (RegAB, R16), что очень хорошо.
Минусов такого метода опроса я не обнаружил, так что жду конструктивной критики от вас -))
  • +3
  • 26 января 2012, 15:59
  • noblako
  • 1
Файлы в топике: Исходники на асм.zip

Комментарии (23)

RSS свернуть / развернуть
В какой программе рисовали алгоритм?
0
  • avatar
  • Rita
  • 26 января 2012, 16:56
На Visio похоже.
Хотя кроме Visio ничего толком и нет. Он самый лучший из опробованных мной.
0
0
Ухты. Спасибо за ссылку. Выглядит неплохо.
0
А разве сравнение предыдущего состояния энкодера и текущего не короче в реализации? И он также не боится дребезга. Видел еще варианты анализа с логическими операциями XOR — самый короткий, как мне показалось. Где-то попадались исходники, однако у меня он не завелся, х.з. может портировал код неправильно, незнаю, но не заработало тогда, плюнул и написал сравнение.
0
Сравнение предыдущего состояния энкодера и текущего немного длиннее в реализации.У Medveda на сайте есть пример на ассемблере ( avrdevices.ru/podklyutchaem-enkoder-k-avr/ ) А так, своей статьей просто предлагаю еще один способ опроса энкодера, и каким пользоваться выбирать только вам.
0
а я чуть иначе сделал. как раз сейчас этот алгоритм писал. есть два вывода 1 и 2. Первый отправляем на RB<4-7>(я на пиках, тут у нас прерывание по смене уровня) а второй на какой-нибудь другой вывод. Смена первого сигнала-, например, возрастание. Смотрим второй вывод если ноль увеличиваем если 1 уменьшаем(ну можно наоборот, эт пример). Запоминаем состояние второго вывода. Крутим ручку дальше. Если это не помехи то второй вывод должен изменить уровень. После должен упасть до нуля 1. Прерывание. Если второй изменялся то ничего не делаем, если не изменился — то наоборот отнимаем ошибочно прибавленую или прибавляем отнятую единичку. по коду получается некомпактно, но выполняется таки быстро, т.к. состоит в основном из проверки битов, что в пиках стандартная АСМ-инструкция.
0
  • avatar
  • kest
  • 26 января 2012, 17:53
В таком варианте разрешение энкодера снижается в два раза. Все-таки вариант конечного автомата с подсчетом состояний более, так сказать, правильный
0
За счет чего разрешение энкодера снижается в два раза?
0
Считаются состояния, когда оба канала в нуле (00) либо единице (11) и не учитываются состояния, когда уровни каналов разные (01 и 10), то есть учитывается только половина состояний энкодера.
0
Не правильно. Точка отсчета — состояния обоих каналов 00. Когда наступает состояние 01 или 10, уже известно направление движение энкодера. Но результат выдоятся, когда наступит состояние 11. Затем снова ожидается состояние 00.
0
ага, но а если во время 00 или 11 изменится напрвление вращения? зачем считать эти состояния если информации они не несут? но суть не в этом. энкодеры(механические) вродебы как раз и устроены что так получается 1 тик на один щелчок. К тому же это у меня работает с оптическим энкодером и разшешением 400 отсчетов на оборот. Точности хватает. У них заполнение не 0,5 а чутка плавает в зависимости от температур и освещенности. поэтому подсчетом длинны и интервалов тут не пойдет. да и очень много времени будет занимать при такой дискретности. А еще у меня их 2 на одном контроллере.
Кстати можно по спаду первого сигнала не проверять изменился ли второй, а еще раз обработать аналогично фронту только наоборот(0-увеличиваем,1 уменьшаем если соответственно с приведенным ранее примером). но это опять же если ширины высокого и низкого уровня при постоянной скорости равны.
0
Ой! Я ошибся. Конечно же разрешение не снижается в 2 раза. Оно снижается в 4 раза.
0
Вы наверно говорите о каких-нибудь промышленных энкодерах, где мой способ опроса не прокатит. На практике же у меня обычный механический китайский экземпляр(что на картинке сверху), который за 20 щелчков на оборот делает 20 изменений регистра RegLed.
0
Фаза начала отсчета (то есть начало комбинации 00) при вращении влево, на четверть щелчка не совпадает с вращением вправо.
Как себя ведет регистр RegLed если покрутить несколько раз энкодер на один щелчок то влево, то в право? Или если аналогично покрутить энкодер на пол щелчка?
0
Вместо
nop             ;rjmp INT_0 ; External Interrupt0 Handler
nop     ;rjmp INT_1 ; External Interrupt1 Handler

логичнее было бы делать переход по адресу 0x00
Но это так, к слову=)
0
Хм, вот как-то потребовалось другу на магнитоле поменять энкодер. Он там был механический, с кнопкой. Запаял новый, и почему-то направления регулирования поменялись на противоположные. Энкодеры что, еще и на разные направления делаются? :) Или надо было еще и калибровку какую сдедать?
0
  • avatar
  • yars
  • 27 января 2012, 09:59
Просто поменять местами выводы A и B. Направление вращения абсолютно симметрично относительно этих выходов
0
Ясно, спасибо. Но там нельзя было просто поменять местами — все-таки готовое заводское устойство. Значит, прошивку надо было перепилить под этот энкодер. Не делать же новую печатку самому :)
А так, я конечно мог бы и соплей из проводков налепить, но это не есть хорошее решение.
0
Ну и придирок ради — вторая красная линия будет не там, где нарисована, а раньше, по первому фронту заднего дребезка канала И
0
Да точно! Но исправлять не буду -))
0
Ну и можно один регистр освободить — использовать не inc A/inc B, а inc A/dec A, а потом смотреть, куда уехали — в плюс или минус. Ну или взять начальное значение 128 и смотреть — больше или меньше получилось. Это чтобы со знаком не возиться.

Кстати, а переполнения не возникнут, если без паузы опрашивать?
0
Да походу переполнения возникают, все сделал по другому. Статью немного подправил.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.