Меня давно занимала мысль применить в качестве энкодера шаговый двигатель, так чтобы маленький и бесконтатный, а не механическая трещотка, которая довольно быстро разваливается. Наконец-то выдался ничем не занятый день, и я решил наконец-то попробовать, что из этого получится.
Для проверки идеи был собран стенд, состоящий из маленького китайского шагового двигателя (униполярный, двухфазный), двух драйверов по известной схеме на LM358 – по одному для каждой из обмоток, старого заслуженного контроллера Arduino Uno, который пылился без дела в ящике, и 5-вольтового стаба на 7805. К оси шагового двигателя был прицеплен редуктор, что позволило очень точно и медленно позиционировать его ось, это мне было важно для исследования.
Для начала была выбрана вот такая схема подключения шагового двигателя, в которой использовались одна обмотка и один драйвер:
Выходы драйвера подключены ко входам прерывания D2 и D3. Был написан простой скетч с использованием широко известной библиотеки Eherkit. На Serial Monitor выдавалось содержимое счетчика шагов, чтобы понять, какая получается разрешающая способность такого „энкодера“, каков характер дребезга и т.п.
Результат получился не очень-то впечатляющим. Дребезг есть, причем довольно заметный. Возможно, имело бы смысл отфильтровать его аппаратно и/или программно, но оказалось (вполне ожидаемо), что такой вариант включения даёт не более 10 шагов за 1 оборот оси (точнее – от 6 до 10). Эта величина зависит от характера дребезга, обусловленного динамикой вращения оси и, в свою очередь, наличием и длительностью всплесков наведенного ротором в обмотках напряжения, в основном, в моменты, когда ротор только-только начинает взаимодействовать с краем обмотки, или когда уже почти прекращает с ней взаимодействовать. Т.е., в конечном счете, зависит от наличия паразитных импульсов на выходе драйвера и их ширины.
Такой результат порадовать не мог, и стало понятно, что нужно делать две вещи:
- для увеличения разрешающей способности использовать вторую пару обмоток двигателя и
- фильтровать дребезг.
На втором этапе исследований были задействованы обе обмотки, для чего был подключен второй драйвер. Скетч был построен так, чтобы контроллер видел как бы два энкодера, генерирующих импульсы независимо друго от друга, но работающих тандемом и складывающих импульсы в одну «корзину», т.е. работающих на общий счетчик – накопитель. Схема получилась такая:
В скетче была применена библиотека ErriezRotaryEncoderH alfStep, позволяющая работать с двумя или несколькими энкодерами. Выходы драйверов были подключены ко входам D4, D5, D6 и D7 контроллера, и, поскольку это не входы прерывания, был реализован вариант работы без прерываний. Можно было, конечно, использовать и прерывания от ввода-вывода, но решил для разнообразия остановиться на этом варианте.
Первый результат оказался обнадеживающим, хотя и не вполне оптимальным. Мне удалось реализовать разрешающую способность порядка 25 – 35 импульсов на оборот оси, но без фильтрации набюдались выбросы на 1-2 и иной раз и более импульсов в ту или ную сторону.
После того, как была реализована программная фильтрация (медианный фильтр и контроль области допустимых значений), результат получился намного лучше. Теперь он меня вполне устраивает. Выбросов практически нет, а наличие дребезга приводит лишь к незначительым флюктуациям разрешающей способности такого «энкодера» - как я уже писал, от 25 до 35 импульсов на оборот. Какие факторы влияют на изменение разрешающей способности, я выше описал. В принципе, такие колебания разрешающей способности практически ни на что не влияют.
Скетчи первого и второго варианта, а также примененная во втором варианте билиотека, приведены ниже. Возможно, кому-нибудь они понадобятся. На самом деле, оба драйвера можно собрать на маленькой плате из копеечных деталей, а чтобы не занимать 4 входа контроллера, на этой же плате можно поместить PCF8574, подключить к ней выходы драйверов и получится решение, позволяющее использовать шаговый двигатель в качестве бесконтактного и очень надежного энкодера, висящего на шине I2C.