Энкодер как подключить

РадиоКот >Статьи >

Теги статьи: ЭнкодерИз желудей и спичекШаговый двигательДобавить тег

Энкодер из шагового двигателя.

Автор — Александр Кленин.
Участник Конкурса «Поздравь Кота по-человечески 2009»
Опубликовано 26.08.2009.

Использование шаговых двигателей (ШД) в качестве энкодера по-прежнему остается привлекательным решением, т.к. промышленные энкодеры, при всех своих достоинствах, имеют существенные недостатки — цена и сложности при покупке единичных экземпляров. Если контактные энкодеры еще с трудом можно приобрести, то цена бесконтактных энкодеров совершенно неподъемная.
В моем случае исключалось применение контактного энкодера, т.к. не допускались пропуски и генерация паразитного (из-за дребезга) сигнала при вращении. Мне не удалось получить удовлетворительных результатов при испытаниях контактных инкрементального и абсолютного энкодеров. Марки называть не буду.
В итоге, склонился к применению ШД от старого 5-дюймового дисковода. За основу взял https://ru3ga.qrz.ru/UZLY/encod.htm, но большое число элементов совсем не радовало.

В результате, схема была приведена к виду, показанному на Рис.1. Для подавления паразитных колебаний у обоих каналов закорочена одна из полуобмоток, что обеспечило достаточное демпфирование, резко снизило скорость нарастания сигнала при больших скоростях вращения и позволило использовать ШД с внутренним соединением средних выводов обмоток.
Также введен гистерезис порядка 50…100 мВ (зависит от напряжения питания 4…5В).
После изменений работа схемы при напряжении питания 5В меня устроила, но хотелось, чтобы она работала от 3В. Большое число элементов и сравнительно большой потребляемый ток, привели к схеме Рис.2.

Подключение обмоток двигателя осталось таким же, а в качестве формирователя сигнала использована микросхема HEF4069 (можно заменить CD4069, MC14069). Ввод схемы в линейную область сделан на одном инверторе, выход которого соединен с входом. Такое соединение позволяет превратить инвертор в повторитель напряжения, примерно равного половине напряжения питания без использования дополнительного резистивного делителя.
При 3В схема на LM358 отказалась работать из-за недостаточно хороших выходных уровней компаратора.
Качество работы обеих схем при 5В питании получилось примерно одинаковое. При монотонном пошаговом повороте вала двигателя наблюдалась четкая последовательность 2-битного кода Грея. Но! При смене направления вращения первый шаг нарушал эту последовательность.
Например:

Вращение по часовой

Вращение против часовой

Видно, что при смене направления происходило изменение состояния обоих каналов, что противоречило правилу кодирования. Последующие шаги соответствовали правильной последовательности нового направления.
Эта особенность поведения ШД (смена состояния в обоих каналах) учитывалась программно. Для примера приведены ассемблерные программы обработки сигналов ШД в качестве энкодера для AVR и MSP430.

На Рис.3 приведены диаграммы сигналов, генерируемых ШД при включении обмоток в соответствии со схемами. Алгоритм обработки сигналов энкодера показан на двух нижних диаграммах Рис.3
-при поступлении прерывания от активного фронта канала А анализируется уровень и флаг требования прерывания канала B. Если флаг установлен, что говорит о смене направления вращения, дополнительно анализируется состояние внутреннего рабочего флага, который сигнализирует о предыдущем направлении вращения и идет соответствующее изменение значения счетчика шагов. Это сделано для исключения неоднозначности определения кодовой последовательности, возникающей при смене направления вращения. Если флаг сброшен, что говорит об отсутствии смены направления вращения, идет простое изменение значения счетчика шагов.
-совершенно аналогично идет обработка прерывания от активного фронта канала В.
В итоге получается обработка каждого шага двигателя.
Шаговый двигатель, в качестве энкодера, был встроен в конструкцию ленточной пилорамы для повышения точности изготовления пиломатериалов.

Файлы:
Прошивки для AVR и MSP430.

Вопросы, как обычно, складываем .

Как вам эта статья?

Заработало ли это устройство у вас?

41 3 1
12 1 1

Эти статьи вам тоже могут пригодиться:

Оптический энкодер или шутка производителя

Рано или поздно в жизни каждого самоделкина возникает потребность в покупке чего-то такого этакого, что обычно само в голову не придет. Вот и я жил себе спокойно и об энкодерах даже не задумывался.
Хотя должен признаться опыт работы с энкодерами имел. Как-то в одной и поделок использовал энкодер из принтера.
В данной истории все приключилось внезапно. Ползая по своим хоббийным форумам натолкнулся на конкурс. Сайт (называть не буду, т.к. разговор не о нем) проводил видимо раскрутку посещаемости и плюс один из форумчан проводил раскрутку своих российского производства изделий. И разыгрывался комплект из 3 наборов для самостоятельной сборки сервоконтроллеров. Я зарегистрировался на этом форуме, подал заявку (вместе с 3 или 4-мя всего лишь участниками) и… выиграл.
Так я стал обладателем 3-х наборов для сборки сервоконтроллеров. Далее мне потребовались энкодеры. Позволю себе объяснить для читателей не так глубоко погруженных в электронные компоненты, что такое сервоконтроллер, энкодер и с чем все это едят.
Есть 2 основных способа управлять точным перемещением в изделиях с ЧПУ (числовое программное управление). Попробую объяснить максимально доступным языком, без сложных схем и терминов.
Первый способ это шаговые двигатели. Шаговый двигатель имеет сложное устройство — несколько катушек, притягивающих сердечник в заданных положениях.


Количество положений, в которых может быть зафиксирован сердечник называется шагами, промежуточные положения (регулируются различными промежуточными напряжениями и соответственно магнитными полями) называют микрошагами. Управляет шаговым двигателем драйвер — это плата управления, как правило с микропереключателями шагов и регулировкой тока, протекающего через двигатель. На вход драйвера подаются сигналы: Enable (разрешить работу шагового двигателя), DIR (направление вращения), STEP (количество шагов, на которое двигателю необходимо повернуть вал). И драйвер переводит команды в обороты вала двигателя. Очень простая и надежная конструкция. Из минусов — скорость вращения двигателя ограничена из-за его конструктива, и если двигатель пропустит по той или иной причине шаги, то управляющая программа об этом не узнает. Отсюда и область применения — низко и среднескоростные двигатели в заданной области нагрузок. Например 3Д принтер или хоббийные станки.
Второй способ управлять перемещениями — сервомотор. Мотор сам по себе может быть любым, постоянного или переменного тока, без разницы. Единственное условие, его вал должен иметь энкодер. Энкодер — это устройство определения позиции вала в данный момент времени. Об энкодерах мы поговорим подробнее чуть позже. Сервоконтроллер имеет другой принцип работы, в отличии от драйвера шагового двигателя. Сервоконтроллер получает на входе те же самые сигналы Enable, STEP, DIR и подает на двигатель напряжение. Двигатель начинает вращаться в нужном направлении, энкодер возвращает данные о положении вала двигателя. Как нужное положение достигается, вал двигателя в нем фиксируется. Конечно это сильно упрощено, т.к. есть ускорение и торможение двигателя, управление током и напряжением, пропорционально-интегрально-дифференцирующий (ПИД) регулятор в контуре обратной связи,… но мы же договорились в этот раз не сильно лезть в теорию.

Какие же плюсы серводвигателей: любая скорость вращения, отсутствие пропуска шагов, бесшумность (шаговый двигатель ощутимо громок в работе из-за своего конструктива). Но цена сервоконтроллеров выше и существенно драйверов шаговых двигателей. Поэтому основная ниша сервоконтроллеров — профессиональное применение.
Для своего проекта я выбрал двигатели Динамо Сливен. Эти двигатели широко использовались в советское время в ЭВМ и их было какое-то нереально большое количество. Кажется, что практически любой хоббийщик или имеет такой двигатель или сталкивался с ним. На барахолках их до сих пор перепродают. Это двигатели постоянного тока с фантастическим неубиваемым ресурсом и устойчивостью к любым издевательствам.

В качестве сервоконтроллера я использовал выигранную плату. Она представляет собой развитие open source сервоконтроллера, известного под устойчивым брендом «сервоконтроллер Чена» — по имени китайца, году так в 2004-м, если не ошибаюсь, предложившим данную схему.

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

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

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

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

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


Абсолютные энкодеры используют диск со сложной системой кодировки положения. Наиболее распространен код Грея — двоичная кодировка с защитой от ошибок.
Я остановил свой выбор на инкрементальном энкодере с контролем направления вращения, т.е. с двумя квадратурными каналами вывода информации. Разрешения в 100 линий на оборот диска мне было за глаза. Поэтому на Алиэкспрессе я нашел энкодеры за разумную цену и с нужными мне характеристиками.
Вот фотка 3-х пришедших мне энкодеров. Дошли они недели за 3.

У энкодеров 4 вывода, Красный — питание 5В, Черный — земля, Цветные — каналы А и В.
Я быстренько выточил втулочку на вал двигателя под крепление диска, ввинтил туда стержень с резьбой.

На 3Д принтере распечатал площадку под крепление датчика энкодера

Собрал все вместе

Подключил сервоконтроллер, и… тут бы был счастливый конец обзору, но нет. Ничего не заработало. Даже близко ничего не заработало.
Подключил осциллограф и понял, что никаких квадратурных сигналов на выходе нет, только шумы, наводки и непонятные выплески. Грешил я на все на свете. И на требовательность к позиционированию, и на засветку, и на наводки электромагнитные. И часами аккуратно возюкал датчик в разных положениях, выключал свет и пытался проделать все тоже самое в темное. «Крокодил не ловится, не растет кокос.» Разумеется я перепробовал все 3 энкодера. Везде тоже самое. И тут меня дернуло поразглядывать датчик в микроскоп.

То что я увидел повергло меня в изумление. Все 4 сенсора стояли в ряд по радиусу диска, т.е. засвечивались через прорезь диска одновременно. Разумеется ничего не работало. Датчики должны стоять перпендикулярно радиусу диска, и засвечиваться последовательно разными фронтами прорези диска. Я не мог поверить, что это так просто и так глупо. Китайцы поставили датчик с поворотом на 90 градусов. Я спросил на форуме у такого же как я покупателя таких же энкодеров как у него стоит датчик. И у него все было также неправильно и не работало.
Почесав в затылке я решил попробовать это дело исправить. Энкодер разобрался легко, при помощи фена расплавил термоклей и достал внутренности.

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

Дальше разрезал корпус энкодера сбоку, наростил проводочками расстояние между светодиодом и матрицей сенсоров и засунул все в корпус по-новому.

На фото видно, что сенсоры стали перпендикулярно радиусу диска.
Собрал, подключил к сервоконтроллеру и… Бинго, все заработало! Мотор встал в режим удержания позиции. Т.е. при попытке проворота вала двигателя, мотор упирается и если его все же провернуть, то возвращается в исходное положение.

Ну а дальше двигатель займет свое место на фрезерном станке, но это уже совсем другая история…:-)
Как резюме. Энкодер из коробки не работает. К покупке не рекомендую. Но в своей ценовой категории, если он был бы исправным, это хорошее бюджетное решение. Либо если переделка изделия в работающее не пугает, то можно брать и переделывать.
У продавца куча положительных отзывов на такой энкодер. Либо это все липа, либо, что вероятнее, брак пошел массово совсем недавно.
Я написал продавцу, он пока шлет мне тонну технических описаний и предлагает попробовать еще, и намекает, что это я не разобрался. Буду на него давить. Пусть хоть часть денег вернет. Я столько времени угрохал из-за их заводского разгильдяйства.
Всем добра и удовольствия от хобби!

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

Код для Ардуино нуждается в использовании библиотек Adafruit Trinket, которые можно скачать (потребуется конкретно библиотека «TrinketHidCombo»). Больше информации можно найти . Код для Ардуино можно скачать .

Шаг 2: Припаиваем Trinket к крутилке

У крутилки есть 5 пинов — три с одной стороны и две с другой. Два пина на одной стороне связаны с кнопкой, они замыкаются, когда стержень крутилки зажат и будут служить для отключения звука. Эти пины не имеют полярности, и не имеет значения, каким образом вы припаяете к ним провода. Три пина на другой стороне — сигнальные. Если вы повернёте крутилку стороной с тремя пинами к себе, а стержень будет указывать вверх, то левый пин будет сигналом » A», средний — землей, правый – сигналом «B». Это отражено на прикреплённой картинке.

Соедините Trinket с крутилкой следующим образом:

  • Пин #0 на Trinket к сигналу «A» на крутилке.
  • Пин #1 на Trinket к одному из пинов кнопки на крутилке.
  • Пин #2 на Trinket к сигналу «B» на крутилке.
  • Пин 5V на другой пин кнопки на крутилке.
  • Пин GND на Trinket к земле на крутилке.

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

Шаг 3: Программируем Trinket

Откройте ИДЕ Ардуино. Скачайте и установите библиотеки Adafruit Trinket, а также код для контроллера звука (ссылки в начале проекта). Установите тип платы на «Adafruit Trinket 16MHz», и Programmer на «USBtinyISP».

Trinket должна быть в режиме Bootloader, иначе она не сможет принимать код. При первом подключении к USB порту компьютера, зелёный диод загорится, а красный будет мигать в течение 10 секунд, а затем погаснет. В этом 10секундном промежутке Trinket будет находиться в нужном режиме. Также можно ввести Trinket в режим Bootloader в любое время, просто нажав кнопку на той части Trinket, которая находится с противоположной стороны от USB порта.

Я обнаружил, что у ИДЕ Ардуино уходит больше 10 секунд на то, чтобы скомпилировать, проверить и отправить код на плату. Поэтому следите за зеленым прогрессбаром в нижней части окна ИДЕ и нажимайте кнопку на Trinket только тогда, когда он доходит до середины. В приложенном видео виден нужный нам прогрессбар. Когда он доходит примерно до середины, я нажимаю кнопку reset на Trinket.

Trinket будет принимать код только в тех случаях, когда прогрессбар дойдёт до конца, а 10 секундный промежуток еще не завершится. Если красный диод непрерывно горит перед тем, как выключится, значит код принимается. Если режим Bootloader закончился, а приём кода не начался, то вы увидите в ИДЕ Ардуино сообщение об ошибке на оранжевом фоне, просто повторите всё заново.

Подключение инкрементального энкодера к микроконтроллеру.


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

По сути инкрементальный энкодер преобразует вращение вала в электрические импульсы, содержащие информацию о направлении вращения.
Давайте соберём тестовую схему изображенную на картинке выше и подключимся к выводу A и B осциллографом, резисторы подтяжки — 4.7К.
Покрутим энкодер по часовой стрелке.

Теперь против часовой.

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

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

Так как дребезг явление кратковременное, он легко гасится конденсатором.

На осциллограмме видно, что после установки конденсаторов, фронты стали менее крутыми, а дребезг исчез.
Второй способ — программный и тут всё зависит от реализации опроса выводов энкодера. Если состояние энкодера отслеживается с помощью внешних прерываний, то после срабатывания прерывания необходимо сделать задержку 20 — 30 миллисекунд, во время которой МК не будет реагировать на изменение состояния вывода, то есть не будет чувствовать дребезг. Если опрос выводов энкодера реализован на таймере, то интервал между опросами должно быть больше длительности дребезга, те же 20 -30 миллисекунд.
Давайте рассмотрим методы обработки данных, приходящих с энкодера.
Первый метод, заключается в том, что одну из ножек энкодера мы подключаем к выходу внешних прерываний и настраиваем её на прерывание по спадающему фронту. В прерывании мы проверяем состояние другой ножки и если на ней ноль, то вращение происходит в одну сторону, иначе в другую. Ниже приведён код, реализующий этот метод для AVR.

#define F_CPU 8000000UL #include <avr/io.h> #include <avr/interrupt.h> ISR(INT2_vect) { if (PINB & 0X02) { PORTB |= (1<<0); } else { PORTB &= ~(1<<0); } //антидребезг _delay_ms(20); //сбрасываем флаг прерывания вызванный дребезгом GIFR = (1<<INTF2); } int main(void) { //настраиваем вывод внешнего прерывания на вход DDRB &= ~(1<<2); //включаем подтяжку PORTB |= (1<<2); //настраиваем вход для подключения второго вывода энкодера DDRB &= ~(1<<1); //настраиваем на выход подключения светодиода DDRB |= (1<<0); //определяем фронт прерывания — спадающий MCUCR &= ~(1<<ISC2); //разрешаем внешнее прерывание int2 GICR |= (1<<INT2); sei(); while(1) { } }
При повороте энкодера в одну сторону светодиод загорается, при повороте в другую — гаснет.
Второй метод, заключается в сравнении текущего состояния и предыдущего. Давайте выразим логические уровни последовательности импульсов в виде нулей и единичек.

Тогда мы получим конечное число состояний энкодера. Первая цифра — логический уровень первого вывода энкодера, вторая — логический уровень второго вывода.
00 = 0
10 = 2
11 = 3
01 = 1
Предположим последнее состояние в котором находился энкодер равно трем, если следующее состояние будет равно единице, то он вращается в одну сторону, если двум, то в другую. Получается, что можно фиксировать переход из одного состояние в другое и определять направление вращения, но наиболее простой является реализация при переходе от 11 к 01 и 10. Ниже приведён код реализующий описанный алгоритм для AVR,
#define F_CPU 8000000UL #include <avr/io.h> #include <avr/interrupt.h> uint8_t last_state = 0; ISR(TIMER0_COMP_vect) { //оба вывода энкодера подключены к 2 и 3 выводу порта B //считываем их состояние uint8_t current_state = (PINB & 0x06)>>1; //учитываем переход только если пред.состояние 11 //и если оно не равно новому if ((last_state == 3) && (last_state != current_state)) { //если новое сост 01 — включаем светодиод if(current_state == 1) { PORTB |= 0x01; } //если новое сост 10 — гасим светодиод if(current_state == 2) { PORTB &= ~0x01; } } //при выходе из прерывания текущее состояние становится прошлым last_state = current_state; } int main(void) { //два входа для подключения энкодера DDRB &= ~0x06; //подтягиваем входы к питанию PORTB |= 0x06; //выход для подключения светодиода DDRB |= 0x01; //настраиваем таймер по в режим сброс по совпадению TCCR0=(1<<WGM01); //разрешаем прерывания счетчика по совпадению TIMSK |= (1<<OCIE0); //устанавливаем число для сравнения, чтобы частота опроса была 20ms OCR0 = 150; //устанавливаем предделитель 1024 TCCR0|=(1<<CS02 | 1<<CS00); //разрешаем прерывания глобально sei(); while(1) { } }
На этом всё.
Энкодер покупал .

Первые оптические энкодеры были разработаны в середине 1940-х годов «Фортепианной компанией Болдуина» для использования в качестве «тоновых колес», которые позволяли электрическим органам имитировать другие музыкальные инструменты. Современные устройства в основном представляют собой миниатюрные версии датчика приближения с использованием прерывания света. В энкодере сфокусированный луч света, направлен на совмещенный с излучателем фотоприемник, периодически прерывается вращающимся диском, расположенным между приемником и передатчиком света и закрепленный на валу контролируемого объекта. Диск может быть непрозрачным с отверстиями, либо прозрачным с нанесенным на него кодированным рисунком. По сравнению с более сложными преобразователями переменного тока, это простая схема кодирования реализует, по существу, цифровой вывод результатов с оптических датчиков в недорогой надежной конструкции с хорошей помехоустойчивостью.

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

Инкрементный оптический энкодер

Оптические поворотные инкрементные энкодеры, еще их называют датчиками угла поворота, стали наиболее популярным устройством для измерения угловой скорости и положения в моторах, на валу колеса или рулевого механизма. В мобильных роботах, энкодеры используются для контроля положения или скорости колес и других, управляемых при помощи моторов соединений. Из-за того, что энкодеры являются проприоцептивными датчиками, их оценка положения является лучшей в системе координат робота и, при решении задачи локализации робота (см. слайды «Проблема локализации мобильного робота»), требуются значительные поправки.

Принцип действия инкрементного энкодера

Простейшим типом инкрементного энкодера является одноканальный тахометр, обычно состоящий из механического прерывателя света, производящего определенное количество прямоугольных или синусоидальных импульсов, при каждом обороте вала. Увеличение числа импульсов увеличивает разрешение (и стоимость) модуля. Разрешение энкодера измеряется в числе отсчетов на оборот (CPR, cycles per revolution). Минимальное угловое разрешение легко вычислить по величине CPR. Типичный энкодер в мобильной робототехнике имеет значение 2000 CPR, в то же время промышленный оптический энкодер может иметь параметр CPR равный 10000. С точки зрения требуемого диапазона, конечно же важно, чтобы энкодер был достаточно быстрым, чтобы успевать считывать значения на предполагаемой скорости вращения. Промышленные оптические энкодеры полностью удовлетворяют требованиям, предъявляемым в робототехнических приложениях.

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

В дополнение к нестабильности на низких скоростях, одноканальный тахометр также неспособен определять направление вращения и, следовательно, не может быть использован в качестве датчика положения. Квадратурные энкодеры, преодолели эти проблемы путем добавления второго канала, смещенного относительно первого, поэтому результирующие последовательности импульсов сдвинуты по фазе на 90 градусов, как показано на рисунке ниже. Этот метод позволяет декодирующей электронике определить, какой канал опережает другой и, следовательно, установить направление вращения. Кроме того, четыре детектируемых различных состояния увеличивают разрешение в четыре раза без изменения диска прерывателя. Таким образом, энкодер, имеющий 2000 CPR выдаст при квадратурной реализации даст уже 8000 отсчетов. Дальнейшее улучшение возможно путем измерения синусоидальной волны с помощью оптического детектора и выполнения сложной интерполяции. Такие методы, хотя и редко используемые в мобильной робототехнике, могут дать 1000-кратное увеличение разрешения.

Принцип действия квадратурного инкрементного оптического энкодера

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

В случае ограниченного вращения, такого как возвратно-поступательное движение вдоль направляющих (как в станках с ЧПУ) можно использовать электрические концевые выключатели и/или механические ограничители для задания исходного положения. Для улучшения повторяемости, возврат в исходное положение разбивается на два этапа. Ось вращается с пониженной скоростью в соответствующем направлении до тех пор, пока не встретится механизм остановки, после чего происходит обраткое вращение в течение предопределенного короткого промежутка времени. Вал вращается медленно обратно до остановки на заданной медленной скорости из этой заданной начальной точки, тем самым, устраняя любые изменения в инерциальной нагрузке, которые могли бы повлиять на окончательное исходное положение. Этот двухэтапный подход используется, например, при старте шагового двигателя для инициализации позиционирования печатающей головки в принтерах.

С другой стороны, функция абсолютного индексирования может быть основана на каком-то внешнем действии по созданию опорной точки, которое отделено от цикла непосредственного сервоуправления. Хорошей иллюстрацией этой ситуации служит инкрементный датчик, используемый для отслеживания угла рулевого управления платформы. Например, когда робот включается в первый раз, абсолютный угол рулевого управления неизвестен и должен быть инициализирован, используя «привязку» действия к маякам на док-станции, соседней стене, или какой-либо другой идентифицирующий набор ориентиров. Увеличение или уменьшение значения счетчика электронного декодера используется для изменения регистра направления транспортного средства в относительной форме.

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

Абсолютный оптический энкодер

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

Принцип действия абсолютного оптического энкодера

Вместо последовательного потока битов, как в инкрементном датчике, абсолютные оптические энкодеры обеспечивают параллельный вывод слова данных с уникальным кодом шаблона для каждого дискретного положения вала. Чаще всего используется код Грея, двоичное и двоично-десятичное кодирование. Характерной особенностью кода Грея (по имени изобретателя Франка Грея из Bell Labs) является то, что только один бит изменяется за раз, помогая избежать тем самым асинхронных неоднозначностей, обусловленными электронными и механическими допусками элементов. С другой стороны, двоичный код постоянно включает множество измененных битов при увеличении или уменьшении счета на единицу. Например, при переходе из положения 255 в положение 0, восемь бит меняются с 1 в 0. Так как нет никакой гарантии, что все пороговые детекторы, являющиеся элементами слежения детектора сработают одновременно, в момент перехода будет присутствовать значительная неопределенность в данной схеме кодирования. Поэтому требуется дополнительный сигнал подтверждения правильности данных, если больше чем один бит изменился между последовательными положениями энкодера.

Поворот 8-битного диска с кодом Грея

На рисунке слева поворот против часовой стрелки на одну позицию становится причиной изменения только одного бита. На рисунке справа такой же поворот двоично-кодированного диска станет причиной изменения всех битов в частном случае (с 255 в 0) иллюстрируя тем самым опорную линию на 12 часов.

Абсолютные энкодеры лучше всего подходят для медленных и/или редких поворотов, таких как кодирование угла поворота рулевого колеса, в отличие от измерения высокоскоростного непрерывного (например, ведущее колесо) вращения, которое потребует вычисления смещения вдоль всего пути движения. Хотя и не столь надежны как резольверы для высокотемпературных или в приложениях с высокой ударной стойкостью, абсолютные энкодеры могут работать при температурах свыше 125 градусов и средним разрешением (1000 отсчетов на оборот). Потенциальным недостатком абсолютных энкодеров является их параллельный вывод данных, который требует более сложного интерфейса из-за большего количества проводов. 13-битный абсолютный энкодер, использующий дополнительные выходные сигналы для помехоустойчивости потребует 28-жильный кабель (13 сигнальных пар плюс питание и заземление) вместо шести в случае с резольвером или инкрементным энкодером.

Приведенный выше пример оптического энкодера вращения генерирует на выходе импульсы, по которым принимающее устройство определяет текущее положение вала путём подсчёта числа импульсов счётчиком. Такие энкодеры называют инкрементными или накапливающими. Сразу же после включения инкрементного энкодера положение вала неизвестно. Для привязки системы отсчёта к началу отсчёта инкрементные энкодеры могут иметь нулевые (референтные) метки, через которые нужно пройти после включения оборудования. К недостаткам также относится то, что невозможно определить пропуск импульсов от энкодера по каким-либо причинам. Это приводит к накоплению ошибки определения угла поворота вала до тех пор, пока не будет пройдена нуль-метка.
Этих недостатков лишены абсолютные энкодеры. Они выдают на выходе сигналы, которые можно однозначно интерпретировать как угол поворота. Как и в приведенной выше схеме инкрементного энкодера, абсолютный оптический энкодер содержит светоизлучающий и принимающий элементы. Существенное отличие в используемом диске: он имеет прозрачные и непрозрачные участки на нескольких радиусах. Световые лучи, проходя через диск, засвечивают те или иные участки фоточувствительного элемента, который в свою очередь формирует на выходе соответствующие сигналы, уникальные для каждого положения диска.
Для кодирования углового положения абсолютные энкодеры используют диски с двоичными кодами и кодами Грея. Двоичный код удобен тем, что не требует дополнительных преобразований. В целом же использование кода Грея предпочтительнее т.к. он более устойчив к ошибкам чтения за счет того, что каждое следующее значение отличается от предыдущего только в одном разряде. При этом вероятность считывания совершенно неверного значения полностью исключена. Более подробно о коде Грея можно почитать в Википедии. На следующем изображении приведены примеры дисков для инкрементного квадратурного и абсолютного энкодеров.

Этот пример наглядно иллюстрирует принцип кодирования углового положения на диске абсолютного энкодера. Для каждого положения вала формируется свой уникальный код. В данном случае для кодирования 16 положений потребовалось 4 концентрических дорожки. При увеличении разрешения абсолютного энкодера возрастает число дорожек и разрядность считываемого значения. Поэтому наряду с параллельным интерфейсом в абсолютных энкодерах широко применяются последовательные интерфейсы, такие как Profibus, CANopen, SSI, BiSS, ISI, Profinet, PWM, Ethernet Powerlink, EtherNet TCP/IP, Modbus, DeviceNet, EtherCAT. Также существуют энкодеры, возвращающие значение углового положения в виде аналогового сигнала.
Абсолютные энкодеры могут быть однооборотными и многооборотными. Если однооборотные способны только выдавать значение угла поворота, то многооборотные позволяют также определять количество оборотов. Это возможно за счет наличия в их составе редуктора и дополнительного диска, который изменяет свое положение при каждом полном обороте вала энкодера.

Подключение инкрементного энкодера к Ардуино

Теперь после небольшой теоретической части можно перейти к практике. Попробуем подключить к Ардуино инкрементный энкодер вращения. У меня в распоряжении имеется модуль KY-040 (вроде того, что изображен на фото в начале этой статьи), который представляет из себя энкодер с разрешением 20 шагов на оборот со встроенной кнопкой, распаянный на плату с подтягивающими резисторами. Это идеальный компонент для организации меню: вращение вала энкодера можно интерпретировать как перемещение курсора по элементам меню, а нажатие кнопки — выбор конкретного элемента. Позже я приведу пример создания такого меню, а сейчас разберемся с подключением энкодера к Ардуино.
Модуль имеет 5 контактов, это:

  • CLK и DT — выводы энкодера, они подтянуты к линии питания резисторами 10кОм;
  • SW — вывод кнопки, при нажатии вывод замыкается на землю;
  • + и GND — линии питания и земли. Данный энкодер является механическим, питание для него не требуется, линии нужны для цепи с подтягивающими резисторами.

Подключим энкодер к Ардуино по следующей схеме:

Существует 2 способа работы с энкодером: с использованием прерываний и путем опроса выводов энкодера в теле программы. Первый способ более правильный, но для него нужен четкий сигнал без помех. Поскольку данный энкодер является механическим, сигнал на его выходах искажен дребезгом контактов и не может быть использован для генерации прерываний (по крайней мере без дополнительных средств для восстановления сигнала, о чем будет рассказано позже). Поэтому сейчас реализуем второй способ и бороться с дребезгом будем программно. Загрузим в Ардуино нижеприведенный код, для скачивания.
#define pin_CLK 2 #define pin_DT 3 #define pin_Btn 4 unsigned long CurrentTime, LastTime; enum eEncoderState {eNone, eLeft, eRight, eButton}; int EncoderA, EncoderB, EncoderAPrev, counter; bool ButtonPrev; eEncoderState GetEncoderState() { // Считываем состояние энкодера eEncoderState Result = eNone; CurrentTime = millis(); if (CurrentTime >= (LastTime + 5)) { // Считываем не чаще 1 раза в 5 мс для уменьшения ложных срабатываний LastTime = CurrentTime; if (digitalRead(pin_Btn) == LOW ) { if (ButtonPrev) { Result = eButton; // Нажата кнопка ButtonPrev = 0; } } else { ButtonPrev = 1; EncoderA = digitalRead(pin_DT); EncoderB = digitalRead(pin_CLK); if ((!EncoderA) && (EncoderAPrev)) { // Сигнал A изменился с 1 на 0 if (EncoderB) Result = eRight; // B=1 => энкодер вращается по часовой else Result = eLeft; // B=0 => энкодер вращается против часовой } EncoderAPrev = EncoderA; // запомним текущее состояние сигнала A } } return Result; } void setup() { pinMode(pin_DT, INPUT); pinMode(pin_CLK, INPUT); pinMode(pin_Btn, INPUT_PULLUP); // Кнопка не подтянута к +5 поэтому задействуем внутренний pull-up резистор Serial.begin(115200); counter = 0; } void loop() { switch (GetEncoderState()) { case eNone: return; case eLeft: { counter—; break; } case eRight: { counter++; break; } case eButton: { counter = 0; break; } } Serial.println(counter); } Для удобства работы код для опроса энкодера помещен в отдельную функцию. В таком виде я использую ее в большинстве проектов с энкодером, достаточно скопировать функцию с переменными в новый скетч и в цикле опрашивать состояние энкодера. Подавление дребезга реализовано за счет добавления в функцию условия, которое обеспечивает опрос энкодера не чаще 1 раза в 5мс.
Подобный код можно увидеть на различных сайтах, и везде говорится что вывод CLK — это сигнал A, а вывод DT — это B. Почему-то на моих энкодерах это не так и сигналы поменяны местами. Этот момент учтен в функции при чтении значений с контактов. И если вдруг у Вас окажется, что при вращении вала энкодера по часовой стрелке значение переменной counter будет уменьшаться, то замените в функции строки чтения значений с выводов pin_CLK и pin_DT на следующие:
EncoderA = digitalRead(pin_CLK); EncoderB = digitalRead(pin_DT);
Итак, прошиваем код в Ардуино, запускаем монитор порта, устанавливаем скорость соединения 115200 и проверяем работу энкодера. Должно получиться что-то вроде этого:

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