Пользователь
0,0
рейтинг
1 июля 2010 в 22:07

Подключение поворотного энкодера к компьютеру через USB

Давно хотел приспособить к ноуту регулятор громкости, сделанный из энкодера. Подключать этот регулятор нужно будет к USB, чтобы все было «по-взрослому» (да и по-другому никак внешнее устройство к ноуту не подключишь). Крутим энкодер влево — громкость должна уменьшаться, вправо — должна увеличиваться. Жмем вниз ручку энкодера — запускаем какую-нибудь полезную программу, или переключаемся на регулирование тембра.

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

image

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

image

Принцип работы энкодера довольно прост — в нем всего лишь два контакта (кнопка на ручке не в счет), которые начинают замыкать, как только пользователь начал крутить ручку энкодера. Контакты подключаются к двум ножкам микроконтроллера (работающих как цифровые входы), и при вращении ручки энкодера на этих ножках появляются импульсы, по фазе и количеству которых микроконтроллер определяет направление вращения и угол поворота ручки энкодера.
image
Чтобы заработал регулятор громкости, нужно решить, как минимум, три инженерные задачи:

Шаг 1. Создание низкоскоростного USB-устройства на макетке.
Шаг 2. Подключить к этому USB-устройству энкодер, добиться, чтобы микроконтроллер его отрабатывал, и передавал в компьютер информацию о вращении энкодера.
Шаг 3. Разобраться, как можно программно управлять регулятором громкости. Наверняка есть какое-нибудь мультимедиа-API, которое позволяет это делать. Программа минимум — нужно написать программку, которая будет принимать сигналы от USB-устройства и управлять громкостью. Неплохо бы, конечно, написать драйвер, но за это браться страшновато. Лучше оставим на потом.

Итак, опишу процесс создания регулятора по шагам. Подробности опускаю, иначе будет слишком скучно. Кому интересно, см. исходники [6] и документацию по ссылкам.

[Шаг 1. Создание низкоскоростного USB-устройства на макетке]

Этот шаг прошел, даже не начавшись — как-то слишком просто и банально. Тупо скачал пример проекта по ссылке [1]. Поправил файлик usbconfig.h — для понтов назвал мое устройство ENCODER DEMO, на большее фантазии не хватило. Проверил в Makefile тип проца (ATmega16), частоту кварца (16 МГц) — чтобы соответствовало моей макетке AVR-USB-MEGA16. Скомпилил проект в AVRStudio, прошил макетку, подключил к компьютеру — все завелось с полоборота, мое USB-устройство исправно заработало как виртуальный COM-порт — все в точности так, как написано в статье [1].

[Шаг 2. Подключить к USB-устройству энкодер]

Этот шаг у меня вызывал самые большие опасения, что все заработает как надо. Что энкодер подключу и смогу его читать — в этом я не сомневался. Были сомнения, что смогу его считывать качественно, когда в фоне работает ещё и обработка протокола USB — все-таки это задача для микроконтроллера не из легких (как впоследствии оказалось — волновался я совершенно напрасно).

Как обычно, начал рыться в Интернете в поисках готовых подпрограмм для чтения энкодера. Нашел очень быстро то, что нужно — именно для AVR, очень простой код на C [2], файлики encoder.c и encoder.h. Что ни говори, а open source крутая штука.

Приделал два индикационных светодиода — ЗЕЛЕНЫЙ и ЖЕЛТЫЙ — для обозначения направления вращения энкодера. Подключил энкодер для удобства прямо к разъему ISP, воспользовавшись тем, что сигналы MOSI, MISO и SCK — это всего лишь ножки PB5, PB6 и PB7 микроконтроллера ATmega16 (подключил туда фазы A и B, а также кнопку энкодера).

image

Поправил определения ножек, добавил код инициализации. Присоединил к проекту модуль encoder.c. Добавил в главный цикл main управление зеленым и желтым светодиодами, когда приходит инфа с энкодера. КРАСНЫЙ светодиод привязал к кнопке энкодера — когда её нажимаем, красный светодиод зажигается, отпускаем — гаснет. Скомпилировал, прошил — работает. Кручу ручку влево, и в такт щелчкам энкодера вспыхивает зеленый светодиод. Кручу ручку вправо — вспыхивает желтый светодиод. Несмотря на то, что чтение энкодера происходит методом поллинга, благодаря эффективному коду к чтению энкодеру НИКАКИХ нареканий даже при одновременной работе с библиотекой V-USB (респект, Pashgan!). Добавил вывод информации от энкодера в виртуальный COM-порт (крутим энкодер влево вывожу в консоль минусики '-', крутим вправо вывожу в консоль плюсики '+'). По таймеру каждые 10 мс вывожу состояние кнопки энкодера и индицирую её красным светодиодом (кнопка нажата — передаю символ '1', отпущена — '0'). Все работает. Скукотища.

image

В заключение выкинул модули cmd.c, crc16.c, eepromutil.c, strval.c. Объем кода упал до 3 килобайт — отлично, теперь поместится и в память ATtiny45 (можно в будущем задействовать макетку AVR-USB-TINY45, она меньше по размерам и дешевле).

[Шаг 3. Разобраться, как можно программно управлять регулятором громкости]

Как обычно, прогуглил вопрос. Отсеял кучу мусора, и наконец выгреб жемчужину — [3]. Дальше дело техники. Достаю любимый детский конструктор — Visual Studio. Ни о чем не думая, визардом генерю dialog-based приложение. Бросаю на панель движок регулятора громкости, привязываю к нему переменную, добавляю обработчик положения движка. При старте приложения настраиваю движок на минимум 0 и максимум 65535 (чтобы соответствовало границам значения громкости, которым манипулируют библиотеки управления микшером). Считываю функцией mixerGetControlDetails текущее значение громкости, и ставлю движок регулятора в соответствующее положение. В обработчике положения движка все наоборот — читаю положение движка и функцией mixerSetControlDetails устанавливаю нужную громкость. Управление громкостью делаю в точности так, как написано в статье [3]. Проверил — работает.

Теперь осталось дело за малым — читать, что приходит с виртуального COM-порта (на нём у нас висит свежеиспеченное USB-устройство с энкодером). Если пришел минусик (-) то двигаем движок влево (уменьшаем громкость), плюсик (+), то двигаем движок вправо (увеличиваем громкость). Если приходят символы 0 и 1, то соответственно управляем состоянием чекбокса (просто для индикации — нажата кнопка энкодера, или нет). С COM-портом можно работать, как с обычным файлом (см. [4]). Инициализируем подключение к COM-порту как открытие файла (вызовом ::CreateFile) в блокирующем режиме. Запускаем отдельный поток, туда в бесконечный цикл добавляем чтение файла (блокирующим вызовом ::ReadFile) по одному символу, и этот символ анализируем. По тому, какой символ пришел, крутим движок слайдера в нужную сторону (громкость будет регулировать обработчик слайдера) или обновляем состояние чекбокса. Проверил — работает.

image

Вот и все, собственно. Дальше можно заниматься бесконечным (и, наверное, бесполезным) улучшательством. Сделать автоматический поиск нужного виртуального COM-порта (сейчас для упрощения имя COM-порта передается через командную строку). Переделать USB-устройство с CDC-класса на HID — это может упростить код USB-устройства, а также упростить программный поиск и открытие устройства на компьютере по VID и HID. Или написать вместо программы сервис (чтобы не надо было запускать отдельную программу). Или даже драйвер. Это очень интересно, но не умею (может, кто из хабравчан научит уму-разуму?..). Прикрутить к кнопке энкодера какое-нибудь действие. Ну и так далее до бесконечности.

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

[UPD120803]

Один грамотный человек собрал на микроконтроллере AVR регулятор громкости — USB HID устройство, эмулирующее стандартную мультимедийную клавиатуру (как предлагалось в комментариях). Такая клавиатура имеет возможность регулировать громкость без дополнительного программного обеспечения, всю необходимую работу выполняет драйвер операционной системы.

image

[Ссылки]

1. USB консоль для управления радиолюбительскими приборами.
2. Тут нашел код для энкодера. Тут авторское описание алгоритма.
3. Описание, как работать с микшером звуковой карты через mixerSetControlDetails.
4. Как работать с COM-портом в Windows.
5. Видеоролик, демонстрирующий работу регулятора громкости.
6. Исходники проекта ENCODER DEMO (проект AVRStudio и проект Visual Studio).
@Derailed
карма
144,5
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое

Комментарии (43)

  • +9
    hint: если переделать на HID, то достаточно просто посылать виртуальные коды клавиатуры «громче»/«тише». Все современные системы эти коды понимают (когда эти кнопки есть на клавиатуре — мультимедийные клавиатуры и ноуты).
    • 0
      Спасибо, хорошая идея.
    • 0
      или как вариант переделать в MIDI
      • 0
        Самое интересное что для AVR-ов есть библиотеки программно обеспечивающие USB стек,
        те можно использовать дешевые AVR-ы аппаратной реализации такового не имеющие,
        и к ним существуют заготовки сякой нативщины вроде различных HID-ов, MIDI-порта, итд…
        И не нужно мутить никаких драйверов, так один мой знакомый Ботан (нет он серьёзно ботаник, никакой не программист, не железячник...) Сделал себе систему сбора данных с различных датчиков (температуры, освещённости, влажности почвы, etc.) Которая для компьютера была, тупо клавиатурою, показания датчиков в эксель забивающую!
        • 0
          Самая популярная из этих библиотек — V-USB.
    • 0
      Попытался последовать Вашему совету — сделал HID-клавиатуру, передавал скан-коды 80h (Keyboard Volume Up) и 81h (Keyboard Volume Down) — никакой реакции. Другие скан-коды (цифры, буквы) передаются нормально.
      • 0
        Это странно. У меня на мультимедийной клавиатуре кнопки вполне отрабатывают (lenny).
        • 0
          Так у меня же самодельная HID-клавиатура. Наверное, что-то в ней не так. То есть она не такая, как Ваша. А что в ней не так — я никак не могу разобраться…
  • +10
    а по кнопке можно включать/выключать звук.
  • 0
    Спасибо, очень интересно!
  • +7
    улыбнуло видео :) особенно озвучка :)
    • +3
      стошлько эмоций:-)) «И нажимать и щелкать!?»
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        Люблю в них такую логику.
  • +23
    Когда то делал такое дело на ATmega16 для своей панели авиасимулятора.
    Жалко забросил. А какое счастье то было mitrichlab.ru/table.jpg :)

    Ностальгирую.
    Спасибо за напоминание. Может выдерну из пыльных завалов джой и снова займусь
    • +2
      Вот это да!.. Такое дело надо продолжить однозначно.
    • +3
      Это заслуживает отдельной статьи
    • +2
      Холодильник рядом — чтобы от полёта не отвлекаться? )
      • +1
        Это аварийный выход
      • 0
        В связи с тем, что за работой курю, а жена этого не переваривает, мой домашний офис оборудован на кухне (благо кухня позволяет).
        Ну и ИБП (Источник Бесконечного Пива) под рукой очень кстати :)
    • 0
      как именно применялся микроконтроллер — в комплексе для всех контрол девайсов или только для коробки между мониторами?
  • +1
    Захотелось прямо сделать маленький пульт для перемотки видео в pinnacle studio. А по нажатию ставить метку.
    • 0
      /dreammodeon Осталось раздобыть где-нибудь исходники pinnacle studio. /dreammodeoff
      • 0
        Зачем? Сейчас это делается колесом мышки, иногда с шифтом. Задача сводится к написанию драйвера, который будет отдавать нужные команды.
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        Какие три кнопочки?
  • +2
    В итоге изобретем пульт как у Доктора Кто :)
  • +1
    Классная статья. Мотивирует тоже взять и соорудить что-нибудь… эдакое, чтобы бальзам на душу и радость по всем нейронам. Спасибо.
  • +1
    Отличный стимул. Я занимался микроконтроллерами, но дальше подключения VGA дисплея и собирание маленького робота — у меня руки не доходили :(

    Сейчас же, есть стимул собирать дивайс. Аля Радио-управляемый регулятор громкости.
  • 0
    Вот такие энкодеры стоят в принтерах.
    • 0
      А еще энкодеры стоят в видеомагнитофонах, в устройствах поворота и настройки антенн, тахометрах, промышленных роботах и во многих устройствах автоматики. Но эти энкодеры имеют специфическое назначение, очень далекое от содержимого данной статьи.
      • 0
        В тахометрах стоят датчики Холла но никак не энкодеры.
        • +1
          Для подсчета частоты вращения (в тахометрах) могут также использоваться энкодеры. Такие тахометры имеют повышенную точность и могут определять направление вращения.

          В энкодерах тоже могут стоять датчики Холла (энкодеры бывают механические, оптические, магнитные).
          • 0
            Виноват. Исправлюсь :)
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        уже и не помню, фотка 2005 года.
  • 0
    Вместо написания драйвера — глянуть протокол как работает www.griffintechnology.com/products/powermate. И сделать аналог под их драйвер
    • 0
      Идея неплохая, но не очень интересно и слишком сложно для меня. Может, Вы попробуете?
      • 0
        Мои познания в электронике кончились на перепайке транзистора в магнитофоне Электроника 312 лет 20 назад.
        Познания в реверсинжиниринге протоколов отсутствуют.

        Но я люблю генерить идеи и концепции.

        В чем огромный плюсик powermate — он умеет работать как jog в аудио-видео редакторах, по крайней мере в Final Cut, нажал — включилось выделение, крутишь — выделяет, нажал — закончил выделение. Ну и громкость.
  • 0
    я для упрощения монтажа мышку разбирал. ролик уж больно удобен. и ограничения нет, можно пролистывать видео до бесконечности
  • 0
    У меня клава logitech internet navigator, в которой есть колесико прокрутки как на мышке. Кайф в том, что можно родным софтом назначить на него не скрол, а другую функцию, я поставил изменение громкости. У меня сильное непонимание почему нельзя добавить такое колесико во все клавиатуры. Это настолько удобно, что даже не описать словами. Как можно жить без этого — не понимаю. :)
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Ехехех, говнорекламщики не дремлют. Опять Вы тут как тут. Получите еще один минус.

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