Вы здесь: Главная » Программный валкодер

Программный валкодер

Программный валкодер




Это не новость и не статья. Это просто развёрнутый комментарий к статье
Я попробую «на пальцах», без привязки к конкретной реализации, рассказать алгоритм программной обработки валкодера, т.е. когда всю аппаратную обвязку мы выбросили и диаграмму работы обрабатываем микроконтроллером (раз уж он всё равно есть — пусть работает).

Схема


От приведенной там схемы оставляем только:


Немного теории


Берём таблицу истинности

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 с какой совпала, на обработку того события уходим, если ни с одной не совпала — значит выход (диаграмма ещё не завершена). Таким образом нам не страшны никакие колебания диска в промежуточных состояниях — мы считаем только полные циклы прохождения зубцов перед датчиком.

Вопрос быстродействия


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

В общем всё заключается в том, что кому проще: распаять несколько деталей или дописать несколько строк.