Что такое энкодер и для чего он нужен

Эндокер

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

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

Виды и принцип действия

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

У такого энкодера, показанного на рисунке, ручка также может применяться в качестве кнопки. Это является вспомогательной функцией конкретного вида энкодера.

По типу выдаваемых данных энкодеры делятся на две большие группы:
  1. Абсолютные.
  2. Инкрементальные.
Абсолютные энкодеры

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

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

У данного алгоритма имеются свои недостатки. Из таблицы 1 виден порядок выдаваемых значений n-го энкодера. Стоит обратить внимание на две последние строчки, переход от 127 на 128.

Таблица 1

Здесь меняются абсолютно все биты. В идеальном энкодере они все меняются одновременно и нет никаких проблем. Практически в реальном энкодере биты меняются быстро, однако не одновременно. И в какой-то момент на выходе энкодера оказывается совершенно произвольное значение. Так как меняются все биты, следовательно, у энкодера будет произвольное значение от нуля до всех единиц.

Справа изображен пример такого переключения. Чем это может грозить? Разберем пример. Микроконтроллер с помощью двигателя управляет валом и поворачивает его на определенный угол. В определенный момент при переключении со 127 на 128 ячейку он получает определенное случайное значение. Контроллер делает вывод, что вал находится совершенно в другом месте, в отличие от фактического места, и начинает его вращать в другую сторону, с другой скоростью и т.д.

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

Код Грея

Выше описанная проблема решается с помощью введения кода Грея. Особенностью кода Грея является то, что при переключении энкодера на единицу, значение кода Грея меняется также на единицу. Меняется только один вид. Это видно в таблице 2 в сравнении двоичного кода и кода Грея.

Таблица 2

Первые две строчки совпадают, но уже во второй строчке поменялся средний бит. Далее также меняется один бит. Также стоит отметить, что последний и первый код Грея отличается на один бит, то есть код Грея может зациклиться.

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

Инкрементальные энкодеры

Следующим типом является инкрементальный энкодер, который имеет более простую структуру. Но при этом он не показывает конкретное место положения своей ручки. Он показывает только направление поворота, а число делений поворота должен считать микроконтроллер.

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

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

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

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

Фактически у энкодера имеется четыре состояния:
  1. Две единицы.
  2. Ноль и единица.
  3. Ноль и ноль.
  4. Единица и ноль.

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

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

Читайте также:  Правила проезда нерегулируемых перекрёстков; Автошкола «ОСНОВА»
Оптические энкодеры

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

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

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

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

Фотоэлектрический энкодер является датчиком, работающим на основе фотоэлектрического принципа. Этот эффект наблюдается при воздействии светового потока на вещество. Этот принцип был открыт в 1887 году. При эксплуатации такого датчика происходит постоянное преобразование луча света в сигнал электрического тока.

Аналогами фотоэлектрического энкодера являются оптоэлектронный, оптический и оптронный. Эти датчики наиболее чувствительны к характеристикам изготовления, эксплуатации и другим факторам, по сравнению с другими моделями. Однако это оправдывается их повышенной точностью, в отличие от конкурентов.

Encoder Class

Definition

Конвертирует набор символов в последовательность байтов. Converts a set of characters into a sequence of bytes.

Examples

В следующем примере показано, как преобразовать массив символов Юникода в блоки байтов, используя указанную кодировку. The following example demonstrates how to convert an array of Unicode characters into blocks of bytes using a specified encoding. Для сравнения массив символов сначала кодируется с помощью UTF7Encoding. For comparison, the array of characters is first encoded using UTF7Encoding. Затем массив символов кодируется с помощью Encoder. Next, the array of characters is encoded using an Encoder.

Remarks

Чтобы получить экземпляр реализации класса Encoder, приложение должно использовать метод GetEncoder реализации Encoding. To obtain an instance of an implementation of the Encoder class, the application should use the GetEncoder method of an Encoding implementation.

Метод GetByteCount определяет, сколько байт приводит к кодированию набора символов Юникода, а метод GetBytes выполняет фактическую кодировку. The GetByteCount method determines how many bytes result in encoding a set of Unicode characters, and the GetBytes method performs the actual encoding. Существует несколько версий обоих методов, доступных в классе Encoder. There are several versions of both of these methods available in the Encoder class. Дополнительные сведения см. в разделе Encoding.GetBytes. For more information, see Encoding.GetBytes.

Объект Encoder хранит сведения о состоянии между последовательными вызовами методов GetBytes или Convert, чтобы они могли правильно кодировать последовательности символов, охватывающие блоки. A Encoder object maintains state information between successive calls to GetBytes or Convert methods so that it can correctly encode character sequences that span blocks. Encoder также сохраняет замыкающие символы в конце блоков данных и использует замыкающие символы в следующей операции кодирования. The Encoder also preserves trailing characters at the end of data blocks and uses the trailing characters in the next encoding operation. Например, блок данных может заканчиваться непарным старшим символом-заместителем, а соответствующий младший символ-заместитель может находиться в следующем блоке данных. For example, a data block might end with an unmatched high surrogate, and the matching low surrogate might be in the next data block. Таким образом, GetDecoder и GetEncoder полезны для передачи по сети и операций с файлами, так как эти операции часто работают с блоками данных, а не с полным потоком данных. Therefore, GetDecoder and GetEncoder are useful for network transmission and file operations, because those operations often deal with blocks of data instead of a complete data stream.

Когда приложение выполняется с помощью потока данных, необходимо убедиться, что сведения о состоянии сброшены, задав для параметра flush значение true в соответствующем вызове метода. When the application is done with a stream of data it should make sure that the state information is flushed by setting the flush parameter to true in the appropriate method call. Если возникает исключение или приложение переключает потоки, оно должно вызвать Reset, чтобы очистить внутреннее состояние объекта Encoder . If an exception occurs or if the application switches streams, it should call Reset to clear the internal state of the Encoder object.

Рекомендации по версиям Version Considerations

Объект Decoder или Encoder может быть сериализован во время операции преобразования. A Decoder or Encoder object can be serialized during a conversion operation. Состояние объекта сохраняется, если он десериализуется в той же версии .NET Framework, но теряется, если он десериализуется в другой версии. The state of the object is retained if it is deserialized in the same version of the .NET Framework, but lost if it is deserialized in another version.

Notes to Implementers

Когда приложение наследуется от этого класса, оно должно переопределять все члены. When your application inherits from this class, it must override all the members.

Constructors

Инициализирует новый экземпляр класса Encoder. Initializes a new instance of the Encoder class.

Properties

Получает или задает объект EncoderFallback для текущего объекта Encoder. Gets or sets a EncoderFallback object for the current Encoder object.

Читайте также:  Тойота Хайлюкс Сурф расход топлива на 100 км отзывы владельцев • DRIVER; S TALK

Получает объект EncoderFallbackBuffer, связанный с текущим объектом Encoder. Gets the EncoderFallbackBuffer object associated with the current Encoder object.

Methods

Преобразует буфер символов Юникода в закодированную последовательность байтов и сохраняет результат в другом буфере. Converts a buffer of Unicode characters to an encoded byte sequence and stores the result in another buffer.

Преобразует массив символов Юникода в закодированную последовательность байтов и сохраняет результат в массиве байтов. Converts an array of Unicode characters to an encoded byte sequence and stores the result in an array of bytes.

Преобразует диапазон символов Юникода в закодированную последовательность байтов и сохраняет результат в другом буфере. Converts a span of Unicode characters to an encoded byte sequence and stores the result in another buffer.

Определяет, равен ли заданный объект текущему объекту. Determines whether the specified object is equal to the current object.

При переопределении в производном классе вычисляет количество байтов, полученных при кодировании набора символов, начиная с заданного указателя символа. When overridden in a derived class, calculates the number of bytes produced by encoding a set of characters starting at the specified character pointer. Параметр указывает, следует ли очистить внутреннее состояние кодировщика после расчета. A parameter indicates whether to clear the internal state of the encoder after the calculation.

При переопределении в производном классе вычисляет количество байтов, полученных при кодировании набора символов из указанного массива символов. When overridden in a derived class, calculates the number of bytes produced by encoding a set of characters from the specified character array. Параметр указывает, следует ли очистить внутреннее состояние кодировщика после расчета. A parameter indicates whether to clear the internal state of the encoder after the calculation.

При переопределении в производном классе вычисляет число байтов, полученных при кодировании набора символов в диапазоне chars. When overridden in a derived class, calculates the number of bytes produced by encoding a set of characters in the ‘chars’ span. Параметр указывает, следует ли очистить внутреннее состояние кодировщика после расчета. A parameter indicates whether to clear the internal state of the encoder after the calculation.

При переопределении в производном классе кодирует набор символов, начало которого задается указателем символов, и все байты, расположенные во внутреннем буфере, в последовательность байтов, которые сохраняются, начиная с заданного указателя байтов. When overridden in a derived class, encodes a set of characters starting at the specified character pointer and any characters in the internal buffer into a sequence of bytes that are stored starting at the specified byte pointer. Параметр указывает, следует ли очистить внутреннее состояние кодировщика после выполнения преобразования. A parameter indicates whether to clear the internal state of the encoder after the conversion.

При переопределении в производном классе кодирует набор символов из заданного массива символов и все символы, расположенные во внутреннем буфере, в указанный массив байтов. When overridden in a derived class, encodes a set of characters from the specified character array and any characters in the internal buffer into the specified byte array. Параметр указывает, следует ли очистить внутреннее состояние кодировщика после выполнения преобразования. A parameter indicates whether to clear the internal state of the encoder after the conversion.

При переопределении в производном классе кодирует набор символов во входном диапазоне символов и любые символы во внутреннем буфере в последовательность байтов, которые сохраняются во входном диапазоне байтов. When overridden in a derived class, encodes a set of characters in the input characters span and any characters in the internal buffer into a sequence of bytes that are stored in the input byte span. Параметр указывает, следует ли очистить внутреннее состояние кодировщика после выполнения преобразования. A parameter indicates whether to clear the internal state of the encoder after the conversion.

Служит хэш-функцией по умолчанию. Serves as the default hash function.

Возвращает объект Type для текущего экземпляра. Gets the Type of the current instance.

Создает неполную копию текущего объекта Object. Creates a shallow copy of the current Object.

При переопределении в производном классе возвращает кодировщик в исходное состояние. When overridden in a derived class, sets the encoder back to its initial state.

Возвращает строку, представляющую текущий объект. Returns a string that represents the current object.

ПОДКЛЮЧЕНИЕ ЭНКОДЕРА К ARDUINO

Самый классический энкодерный модуль KY-040. Имеет 28 тиков на оборот, рукоятка является кнопкой (отдельный выход). Тип энкодера – 1 или 2 импульсный, китайцы могут прислать любой (о типах читайте ниже)

Более новый модуль, гораздо меньший процент брака. Имеет 28 тиков на оборот, рукоятка является кнопкой (отдельный выход). Тип энкодера – 2 импульсный.

Промышленный энкодер – надёжная и точная штука: металлический корпус, подшипниковый узел. Имеет 100, 200, 300, 360, 400, 600, 1000 тиков на оборот (на выбор). Тип энкодера – 2.

ПОДКЛЮЧЕНИЕ

Подключается модуль энкодера очень просто: питание на питание (GND и VCC), логические пины CLK, DT (тактовые выводы энкодера) и SW (вывод кнопки) на любые пины Arduino (D или A). У круглых модулей выводы энкодера подписаны как S1 и S2, а вывод кнопки как Key, подключаются точно так же. От порядка подключения тактовых выводов энкодера зависит “направление” его работы, но это можно поправить в программе.

У модулей энкодера тактовые выводы подтянуты к питанию и дают низкий сигнал при срабатывании, также на них стоят RC цепи для гашения дребезга. Вывод кнопки никуда не подтянут! Промышленный энкодер подключается точно так же, чёрный и красный провода у него питание, остальные – тактовые выходы.

У модулей энкодеров тактовые выходы и кнопка подтянуты к питанию, у круглого модуля также стоят RC цепи для аппаратного подавления дребезга контактов, у KY-40 (прямоугольный) распаяна только подтяжка. Если нужно подключить “голый” энкодер к плате – в целом можно подключить напрямую без обвязки, как на схеме ниже, моя библиотека отработает и подтяжку средствами микроконтроллера (INPUT_PULLUP), и программный антидребезг. Но рекомендуется всё-таки делать RC цепи для кнопки и для тактовых выходов энкодера.

Читайте также:  Infiniti QX70 (2020-2021) цены и характеристики, обзор с фотографиями

Голый энкодер без обвязки

Схема круглого модуля

RC цепь на выводы энка

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

ПРОГРАММИРОВАНИЕ

GyverEncoder v4.8

Я не нашёл в интернете нормальных библиотек для энкодера с хорошей функциональностью, поэтому написал свою, GyverEncoder. Что умеет:

  • Отработка поворота рукоятки энкодера
    • Обычный поворот
    • “Нажатый поворот”
    • “Быстрый” поворот
  • Три алгоритма опроса энкодера
    • Быстрый – но не справляется с люфтами
    • Бинарный – медленнее, лучше справляется с люфтами
    • Высокоточный – ещё медленнее, но работает даже с убитым энкодером
  • Возможность работы с “виртуальным” энкодером – через расширитель пинов или ещё как
  • Работа с двумя типами энкодеров (тип 1 и 2, см. выше)
  • Работа с кнопкой энкодера:
    • Отработка нажатия
    • Клика
    • Двойного клика
    • Удержания
    • Антидребезг контактов
    • Возможность полностью убрать код кнопки для быстродействия

Поддерживаемые платформы: все Arduino (используются стандартные Wiring-функции)

Версии

– 4.1
– Исправлено изменение подтяжек

– 4.2
– Добавлена поддержка TYPE1 для алгоритма PRECISE_ALGORITHM
– Добавлена отработка двойного клика: isSingle / isDouble

– 4.3: Исправлено ложное isSingle
– 4.4: Добавлен метод resetStates, сбрасывает все is-флаги и счётчики
– 4.5: Улучшен алгоритм BINARY_ALGORITHM (спасибо Ярославу Курусу)
– 4.6: BINARY_ALGORITHM пофикшен для TYPE1, добавлена isReleaseHold
– 4.7: Исправлен случайный нажатый поворот в BINARY_ALGORITHM
– 4.8: увеличена производительность для AVR Arduino

Документация

Инициализация

Объект энкодера может быть создан несколькими способами:

Опрос

Опрос энкодера происходит в методе .tick() , после чего можно узнать состояние энкодера из методов is*. Сам .tick() должен вызываться как можно чаще:

  • В loop() – у вас должен быть “прозрачный” loop() без задержек
  • В прерывании таймера – достаточно опрашивать энкодер каждые 5 мс (зависит от скорости поворота)
  • В аппаратном прерывании (достаточно завести одну таковую ногу энкодера)

Для “расшифровки” состояния энкодера используются следующие методы:

  • isTurn(); // возвращает true при любом повороте, сама сбрасывается в false
  • isRight(); // возвращает true при повороте направо, сама сбрасывается в false
  • isLeft(); // возвращает true при повороте налево, сама сбрасывается в false
  • isRightH(); // возвращает true при удержании кнопки и повороте направо, сама сбрасывается в false
  • isLeftH(); // возвращает true при удержании кнопки и повороте налево, сама сбрасывается в false
  • isFastR(); // возвращает true при быстром повороте
  • isFastL(); // возвращает true при быстром повороте

Для кнопки энкодера:

  • isPress(); // возвращает true при нажатии кнопки, сама сбрасывается в false
  • isRelease(); // возвращает true при отпускании кнопки, сама сбрасывается в false
  • isClick(); // возвращает true при нажатии и отпускании кнопки, сама сбрасывается в false
  • isHolded(); // возвращает true при удержании кнопки, сама сбрасывается в false
  • isHold(); // возвращает true при удержании кнопки, НЕ СБРАСЫВАЕТСЯ
  • isSingle(); // возвращает true при одиночном клике (после таймаута), сама сбрасывается в false
  • isDouble(); // возвращает true при двойном клике, сама сбрасывается в false

Примечание: isClick() возвращает true сразу же после отпускания кнопки, в то время как isSingle() возвращает true после таймаута, во время которого можно сделать второй клик и поймать уже двойной клик при помощи isDouble() .

В версии 4.4 появился метод resetStates() , который принудительно сбрасывает все флаги is-методов

Настройки в скетче

Некоторые параметры работы энкодера можно настроить из программы:

  • setType(type); // тип энкодера TYPE1 одношаговый, TYPE2 двухшаговый. Если ваш энкодер работает странно, смените тип
  • setTickMode(tickMode); // MANUAL / AUTO – ручной или автоматический опрос энкодера функцией tick() (по умолчанию ручной)
  • setDirection(direction); // NORM / REVERSE – направление вращения энкодера
  • setFastTimeout(timeout); // установка таймаута быстрого поворота
  • setPinMode(mode); // тип подключения пинов энкодера, подтяжка HIGH_PULL (внутренняя) или LOW_PULL (внешняя на GND)
  • setBtnPinMode(mode); // тип подключения кнопки, подтяжка HIGH_PULL (внутренняя) или LOW_PULL (внешняя на GND)

Настройки в библиотеке

В заголовочном файле библиотеки (GyverEncoder.h) есть несколько дополнительных настроек:

  • ENC_DEBOUNCE_TURN 1 // время антидребезга для энкодера, миллисекунд
  • ENC_DEBOUNCE_BUTTON 80 // время антидребезга для кнопки, миллисекунд
  • ENC_HOLD_TIMEOUT 700 // таймаут удержания кнопки, миллисекунд
  • ENC_DOUBLE_TIMEOUT 300 // таймаут двойного клика
  • #define ENC_WITH_BUTTON // если закомментировать данную строку, опрос кнопки будет полностью “убран” из кода, что сделает его легче и чуть быстрее
  • #define DEFAULT_ENC_PULL LOW_PULL // тип подключения энкодера по умолчанию (LOW_PULL или HIGH_PULL)
  • #define DEFAULT_BTN_PULL HIGH_PULL // тип подключения кнопки энкодера по умолчанию (LOW_PULL или HIGH_PULL)

Алгоритмы опроса энкодера

Алгоритм работы библиотеки можно выбрать в заголовочном файле библиотеки (GyverEncoder.h), для этого нужно раскомментировать одну из строк с дефайнами алгоритмов:

  • #define FAST_ALGORITHM // быстрый, не справляется с люфтами
  • #define BINARY_ALGORITHM // медленнее, лучше справляется с люфтами
  • #define PRECISE_ALGORITHM // медленнее, но работает даже с убитым энкодером (по мотивам https://github.com/mathertel/RotaryEncoder)

Работа с “виртуальным” энкодером

Версия библиотеки 4+ поддерживает работу с виртуальным энкодером, т.е. алгоритм опрашивает не напрямую цифровой пин микроконтроллера, а логическую величину, которую ему передадут. Таким образом можно попробовать опрашивать несколько энкодеров, подключенных через расширитель пинов. Для работы с таким энкодером нужно инициализировать энкодер без указания пина:

Работа с таким энкодером ничем не отличается от обычного, кроме метода tick() – в него нужно передать состояния тактовых пинов энкодера (CLK и DT), а также пина кнопки (опционально):

Смотрите пример external_enc в папке с примерами

Ссылка на основную публикацию
Adblock detector