Отслеживание всех состояний энкодера

МЕНЮ


Искусственный интеллект
Поиск
Регистрация на сайте
Помощь проекту

ТЕМЫ


Новости ИИРазработка ИИВнедрение ИИРабота разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика

Авторизация



RSS


RSS новости


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

В прошлой статье я привел код для Arduino, позволяющий с помощью прерываний отслеживать только один выход энкодера, а сигнал на втором проверялся уже внутри обработчика и указывал на направление вращения. В результате мы улавливали 11-12 тиков на один оборот диска энкодера. Сегодня разовьем программу и научимся "отлавливать" все возможные состояния, что позволит в 4 раза увеличить точность (улавливать 44-48 состояний на один оборот диска).

Вспомним сигналы, возникающие на двух выходах энкодера:

С каждого энкодера приходит два сигнала. Для полного отслеживания сигналов потребуется подключать их к пинам, поддерживающим прерывания. У общеизвестной народно любимой платы Arduino UNO всего лишь два таких пина (2 и 3), то есть к ней получится подключить всего один мотор для полного отслеживания или два мотора, как было описано в прошлой статье. Узнать подробнее о прерываниях можно на официальном сайте. Для экспериментов хватит и UNO, но я сразу переключился на Arduino MKR Zero, которая имеет 9 пинов с прерываниями (до 4-х моторов). Код итоговой программы от выбранной платы почти не меняется, только указываются другие пины.

Про подключение подробно не буду рассказывать, для мотора Pololu 75:1 MP 12V оно выглядит как на фото:

Зеленый провод - "земля" энкодера - соединяем с GND платы;

Синий провод - питание энкодера - соединяем с Vcc платы (работает и от 3.3В, и от 5В);

Желтый провод - выход А энкодера - на пин платы с прерыванием;

Белый провод - выход B энкодера - на другой пин платы с прерыванием;

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

Итак, я подключил выходы А и В энкодера к пинам 6 и 7 Arduino MKR Zero (у Arduino UNO это будут пины 2 и 3). В программе я могу настроить прерывание на переход сигнала из 0 в 1 (передний фронт, RISING), из 1 в 0 (задний фронт, FALLING) или на любое подобное изменение (CHANGE). Для полноты картины придется ловить оба фронта.

В процедурах intAsub и intBsub будет происходить обработка прерываний. Первым делом, в каждой из них считываю и запоминаю текущий сигнал:

и

Внимательно изучим сигналы, приходящие по линиям А и В. При вращении мотора вперед:

При вращении мотора назад:

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

Если следить за прерываниями линии А, то получаем:

Передний фронт А при вращении вперед - на линии В сигнала нет,

Задний фронт А при вращении вперед - на линии В есть сигнал,

Передний фронт А при вращении назад - на линии В есть сигнал,

Задний фронт А при вращении назад - на линии В нет сигнала.

Внимательно смотрим на эти четыре варианта и замечаем, что при движении вперед сигналы sigA (считанный в самом начале прерывания) и sigB (считанный ранее в другом прерывании) отличаются, а при движении назад совпадают. Если не уловили, то остановитесь на этом моменте и еще раз внимательно изучите сигналы. Например, мотор крутится вперед и возникло прерывание на заднем фронте; мы считываем этот сигнал командой digitalRead и видим 0. А на линии В с последнего прерывания той линии хранится значение 1.

Таким образом обработчик прерывания для линии А принимает вид:

Переменная sigB обновляется и актуализируется в другом прерывании.

Если следить за прерываниями линии В, то получаем:

Передний фронт B при вращении вперед - на линии А сигнал есть,

Задний фронт В при вращении вперед - на линии А сигнала нет,

Передний фронт В при вращении назад - на линии А сигнала нет,

Задний фронт В при вращении назад - на линии А сигнал есть.

Внимательно смотрим на эти четыре варианта и замечаем, что при движении вперед сигналы sigA (считанный в самом начале прерывания) и sigB (считанный ранее в другом прерывании) совпадают, а при движении назад отличаются. Обработчик прерываний для линии В:

Вот и все! Не надо никаких сложных алгоритмов, запоминания текущей фазы и сравнивания с предыдущими, не надо хранить сигналы в 8 переменных и выстраивать трехэтажную логику.

Если к контроллеру надо подключить несколько моторов, то придется создавать такие процедуры для каждого пина. На три мотора получится 6 процедур, на 4 мотора 8 процедур и т.д.

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

Кстати, итоговый код программы:

Надеюсь, что рассмотренный материал пригодится кому-нибудь при подготовке к олимпиаде Innopolis Open in Robotics. Более детально о подготовке к олимпиаде мы будем рассказывать на тематических КПК, а подробнее познакомиться с подобными приемами можно на наших курсах по Arduino.

Автор — методист по олимпиадной робототехнике Университета Иннополис Алексей Овсянников.


Источник: m.vk.com

Комментарии: