Это не новость и не статья. Это просто развёрнутый комментарий к датагосркой статье "Что есть валкодер?"
Я попробую «на пальцах», без привязки к конкретной реализации, рассказать алгоритм программной обработки валкодера, т.е. когда всю аппаратную обвязку мы выбросили и диаграмму работы обрабатываем микроконтроллером (раз уж он всё равно есть — пусть работает).
Содержание статьи / Table Of Contents
↑ Схема
От приведенной там схемы оставляем только:
↑ Немного теории
Берём таблицу истинности (приведенную там же ):
T — шаг состояния;
VAL0 — состояние датчика №0
VAL1 — состояние датчика №1
Заметим, что эта таблица истинности описывает изменения состояний датчиков при движении диска на один зуб только в одну сторону, в реальности требуется ещё одна таблица, описывающая обратное движение. Но её можно не рисовать, просто прочесть уже имеющуюся справа-налево (от состояния 5 к состоянию 1), главное не запутаться.
Приводим таблицу истинности к линейному виду (делаем проекцию двухмерного объекта на линию), получаем:
T — шаг состояния;
VAL — номер датчика (№0 или №1)
data — состояния датчика, или собственно таблица истинности. Поскольку движение закольцовано, два нуля в начале и конце диаграммы смыкаются и одну пару из них отбрасываем. Нужный нам байт выделен жёлтым.
byte — пронумеруем биты в байте, просто что бы не запутаться.
Не забудем таблицу и для обратного движения:
Кстати, в этом месте уже можно догадаться, что будет дальше.
В программе нам потребуется переменная (один байт) для хранения текущего состояния датчиков и две константы для проверки исполнения таблицы истинности:
static char diagramma;
const char diag_plus = 0b00011110;
const char diag_minus = 0b00101101;
Реализовать алгоритм можно как обработку прерывания от таймера или в общем цикле программы (если он не слишком длинный).
↑ Теперь собственно алгоритм:
1. При входе в подпрограмму обработки валкодера первым шагом сравниваем состояние датчика VAL0 с битом diagramma.0 и датчика VAL1 с битом diagramma.1 если хоть один не совпал, то тогда идём дальше, иначе выход из прерывания (или в основной цикл программы), здесь больше ничего не делаем. Таким образом нам не страшны зависания диска в промежуточных состояниях.
2. Сдвигаем байт diagramma на два разряда в сторону старшего разряда.
3. Присваиваем двум младшим разрядам diagramma текущие значения соответствующих датчиков.
4. Сравниваем поочерёдно diagramma с константами diag_plus и diag_minus с какой совпала, на обработку того события уходим, если ни с одной не совпала — значит выход (диаграмма ещё не завершена). Таким образом нам не страшны никакие колебания диска в промежуточных состояниях — мы считаем только полные циклы прохождения зубцов перед датчиком.
↑ Вопрос быстродействия
Если для регуляторов громкости и тембра пропустить несколько зубцов диска не смертельно, то при реализации валкодером, например, счётчика ленты магнитофона, это уже критически важно и, чтобы не было пропусков в счете, потребуется считать ограничение по минимальной частоте вызова прерывания для обработки датчика (или максимальной длительности главного цикла программы, если делать без прерываний).
Но этот вопрос слишком зависит от конкретной реализации и здесь рассматривать не будем.
Кстати при реализации алгоритма на ассемблере он занимает считанные байты и вопрос быстродействия скорее всего не возникнет.
В общем всё заключается в том, что кому проще: распаять несколько деталей или дописать несколько строк.
Камрад, рассмотри датагорские рекомендации
🌼 Полезные и проверенные железяки, можно брать
Опробовано в лаборатории редакции или читателями.