- Делаем еще один джойстик (геймпад) на Arduino
- Arduino Leonardo как адаптер SegaMegaDrive Gamepad->USB
- Предисловие
- Протокол геймпада SMD
- Библиотека
- Пример
- Подключаем к плате Ардуино джойстик
- Смысл подключения джойстика к ардуино
- Принцип действия
- Необходимые инструменты, материалы и программы
- Сборка устройства
- Настройка и отладка
- Тестирование
- Руль, джойстик и геймпад с обратной связью (Force Feedback)
Делаем еще один джойстик (геймпад) на Arduino
Шла обычная пятница, ничто не предвещало беды…
Но червь «нужно что-то сделать» уже начал свою работу. После прочтения статьи я вспомнил, что у меня в барахле лет 15, если не больше, валяется сеговский геймпад. Забрал я его с твердым намерением сделать геймпад на процессоре AVR (про ардуино я тогда и не слышал, но пару небольших проектов на AVR сделал).
Еще больше утвердила мое намерение статья про MSX, и в пятницу я решил — делаю!
Из закромов был вытащен на белый свет сеговский геймпад в разобранном состоянии. К моему изумлению он был в полном комплекте (ну, если не считать порезанные дорожки и отсутствующий оригинальный контроллер), не хватало только 2-х болтиков.
В качестве контроллера я решил использовать Beetle, так как он был заказан мной когда-то, но пока не испробован, да и не очень понравился «малым количеством портов».
И тут меня ждало разочарование — портов 6, кнопок 10. Горю моему не было предела, но мозг таки нашел решение, для начала я решил попробовать собрать прототип из 2-х кнопок, так как я решил использовать фокус с диодом, чтобы опрашивать 10 кнопок с помощью 6 выводов. Практически окрыленный, я засел за проверку… И тут случилась следующая неприятность — кнопок на джойстике больше, чем 10! В общем это был тот момент, когда нужно было смотреть в документацию, хотя идей было много — например припаять (ага, моим паяльником, который накрывает почти все ножки с одной стороны микросхемы), или поискать просветления в интернете.
Документация же четко сказала, что портов у Beetle на самом деле не 6, а 10, что сделало дальнейший процесс скучным (так я думал). (Использование 8 выводов дает возможность опрашивать 2 * 6 = 12 кнопок, что мне и было нужно)
Схема подключения — матрица 6 х 2, потому как оригинальная плата была разведена удобным мне образом. (Кстати в процессе предыдущей переделки дорожки были порезаны, чтобы подключить клавиатурный контроллер, пришлось восстанавливать, вышло страшненько)
Схема получившегося геймпада:
Быстро накидав пример я убедился что он не работает… Не понял?! Пример то простейший. Подумав, сообразил, что цифровому пину не хватает того сопротивления, что дают резиновые токопроводящие кнопки, немного изменил схему, теперь читается аналоговый сигнал и сравнивается с половиной максимума. Перепаиваю контакты, переписываю программу и… ничего не работает, совсем. Контроллер не определяется, все пропало. Код проверен, и перепроверен, все должно работать! А контроллер не видится ни в какую. Мотивация падает, делаем перерыв.
Через некоторое время безуспешно поигравшись с Beetle, ну все, убил контроллер своим паяльником, с сожалением достаю из закромов Arduino Micro, прошиваю прошивку и снова тишина! Становится понятно, что-то не так с кодом, в конце концов нахожу банальную причину — бесконечный цикл в loop(), исправляю, но зашить то не могу! Оказывается проблема, когда контроллер не видится решается нажатием на резет во время прошивания (или замыканием пинов в моем случае)
В итоге получился сеговский геймпад, проверен, работает, я счастлив: поиграл в Metal Gear, Felix The Cat, Super Mario.
P. S. «Трюк со светодиодом». Конечно не обязательно использовать светодиод, обычный диод лучше подходит, суть простая, вместо двух выводов использовать один, соединенный с разными кнопками через 2 диода:
Источник
Arduino Leonardo как адаптер SegaMegaDrive Gamepad->USB
Предисловие
Протокол геймпада SMD
В самом простом случае получение данных выглядит так:
PIN | Направление | Select=LOW | Select=HIGH |
---|---|---|---|
1 | IN | UP | UP |
2 | IN | DOWN | DOWN |
3 | IN | HIGH | LEFT |
4 | IN | HIGH | RIGHT |
5 | OUT | 5v | 5v |
6 | IN | A | B |
7 | OUT | Select | Select |
8 | OUT | GND | GND |
9 | IN | Start | C |
Показатели меняются в зависимости от изменения Select пина.
Как видите здесь не хватает 4 клавиш.
Их получение немного усложнено: необходимо сделать 2 изменения Select LOW->HIGH с интервалом 1.1-1.2 миллисекунд, после чего пины 1,2,3,4 становятся LOW, а при еще одном изменении Select LOW->HIGH на них появляются значения Z,Y,X,Mode соответственно.
Select | PIN 1 | PIN 2 | PIN 3 | PIN 4 |
---|---|---|---|---|
LOW | UP | DOWN | LOW | LOW |
HIGH | UP | DOWN | LEFT | RIGHT |
LOW | UP | DOWN | LOW | LOW |
HIGH | UP | DOWN | LEFT | RIGHT |
LOW | LOW | LOW | LOW | LOW |
HIGH | Z | Y | X | MODE |
LOW | HIGH | HIGH | HIGH | HIGH |
HIGH | UP | DOWN | LEFT | RIGHT |
LOW | UP | DOWN | LOW | LOW |
Библиотека
Для удобства я написал простенькую библиотеку для работы с геймпадом.
SMDjoystick.read(SMD_id) позволяет считать значение 1 кнопки.
SMDjoystick.read() возвращает uint16_t со значениями всех кнопок, пригодную для JoyState.
Пример
Подключаем к леонардо:
Gamepad pin | Arduino pin |
---|---|
1 | 2 |
2 | 3 |
3 | 4 |
4 | 5 |
5 | 5v |
6 | 6 |
7 | 7 |
8 | GND |
9 | 8 |
Все, теперь можно использовать геймпад сеги как любой USB геймпад.
UPD:
Добавлен пример эмуляции нажатия клавиш клавиатуры.
Убран таймер
Добавлен репозиторий
Источник
Подключаем к плате Ардуино джойстик
Джойстики – отличный источник входных данных для проекта по робототехнике. Создатели электроники всегда любили подобные вещи. Однако новичкам может показаться трудным понять концепцию во время кодирования и тому подобное. В статье ниже подробно описан механизм сборки ардуино джойстика и принцип его работы.
Смысл подключения джойстика к ардуино
Многим роботизированным проектам нужен джойстик. Модуль джойстика на ардуино аналогичен тем, которые используются в игровых приставках. Это сделано путем установки двух потенциометров под углом 90 градусов. Потенциометры соединены с короткой палкой, центрированной пружинами.
Этот модуль производит на выходе около 2,5 В от X и Y, когда он находится в положение покоя. Перемещение джойстика приведет к изменению выходного сигнала от 0 В до 5 В в зависимости от его направления. Если вы подключите этот модуль к микроконтроллеру, вы можете ожидать, что значение будет около 512 в положении покоя.
Когда вы перемещаете джойстик, вы можете увидеть, что значения изменяются от 0 до 1023, в зависимости от его положения.
Принцип действия
В приведенном ниже коде мы определили оси X и Y модуля джойстика для аналогового вывода A0 и A1 соответственно:
Теперь в приведенном ниже коде мы инициализируем PIN 2 для аrduino для коммутатора модуля Joystick, а значение buttonsdtate и buttonsdtate1 будет 0 в начале описываемой программы:
В приведенном ниже коде устанавливаем необходимую скорость передачи до 9600 и определяем Pin 7, как выходной вывод, и контакт кнопки в качестве входного контакта. Первоначально контактная кнопка остается высокой, пока пользователь не нажмет на соответствующий переключатель.
Здесь, в этом коде считываем значения из аналогового вывода A0 и A1 и последовательно выводим на устройство:
Условия включения и выключения светодиода в соответствии с движением вала джойстика определяются в приведенном ниже коде. Здесь мы просто принимаем аналоговые значения напряжения на выводах A0 и A1 аrduino. Эти аналоговые значения будут меняться при перемещении джойстика, и светодиод будет светиться в соответствии с движением джойстика.
Это условие для перемещения вала джойстика в направлении оси Y:
Это условие для перемещения вала джойстика в направлении оси X:
Это условие для перемещения вала джойстика в направлении оси X:
Нижеописанный код – это условие для перемещения вала сконструированного прибора в направлении оси Y:
Когда мы перемещаем ось джойстика по диагонали, тогда одно положение приходит, когда аналоговое значение X и Y будет равно 1023 и 1023 соответственно, и светодиоды Pin 9, и Pin 8 будут светиться. Потому что он удовлетворяет условию светодиода. Итак, для устранения этого несоответствия указывается условие, что если значение (X, Y) равно (1023, 1023), то оба светодиода остаются в выключенном состоянии:
Нижеследующее условие используется для управления светодиодом, подключенным к кнопочному переключателю. Когда мы нажимаем джойстик, светодиод включается и фиксируется до тех пор, пока кнопка не опустится. Лучше использовать кнопочный переключатель.
Необходимые инструменты, материалы и программы
Для осуществления проекта “аrduino joystick” потребуются следующие материалы:
- аrduino UNO;
- модуль джойстика;
- светодиоды – 5 штук;
- резистор на 100 ом — 3 штуки;
- соединительные провода;
- макет.
Сборка устройства
Джойстики доступны в разных формах и размерах. Типичный модуль описываемого прибора показан на рисунке ниже. Этот модуль обычно обеспечивает аналоговые выходы, а выходные напряжения, обрабатываемые этим модулем, изменяются в соответствии с направлением, в котором его перемещает пользователь. Можно получить направление движения, интерпретируя эти изменения с помощью некоторого микроконтроллера.
Этот модуль джойстика имеет две оси. Они представляют собой ось X и ось Y. Каждая ось монтируется на потенциометр или горшок. Средние точки этих горшков определяются, как Rx и Ry. Таким образом, Rx и Ry являются переменными точками для этих горшков. Когда прибор находится в режиме ожидания, Rx и Ry действуют, как делитель напряжения.
Когда arduino джойстик перемещается вдоль горизонтальной оси, напряжение на контакте Rx изменяется. Аналогично, когда он перемещается вдоль вертикальной оси, напряжение на пикселе Ry изменяется. Таким образом, у нас есть четыре направления устройства на двух выходах ADC. Когда палочка перемещается, напряжение на каждом штыре должно быть высоким или низким, в зависимости от направления.
Настройка и отладка
После загрузки кода в аrduino и подключения компонентов в соответствии с электрической схемой, мы теперь управляем светодиодами с помощью джойстика. Можно включить четыре светодиода в каждом направлении в соответствии с движением вала устройства. Он имеет два потенциометра внутри, один – для перемещения по оси X, а другой – для перемещения по оси Y. Каждый потенциометр получает 5v от аrduino. Так как мы перемещаем устройство, значение напряжения изменится, и аналоговое значение в выводах A0 и A1 также станет иным.
Итак, из микроконтроллера аrduino мы считываем аналоговое значение для оси X и Y и включаем светодиоды в соответствии с движением оси устройства. Нажимаем переключатель на модуле и используем для управления одиночным светодиодом в цепи.
Код представлен ниже:
Тестирование
Для тестирования джойстика для ардуино понадобятся следующие компоненты:
- Микроконтроллер (любой, совместимый arduino).
- Модуль джойстика.
- 1 контактный разъем MM.
- Макет.
- USB-кабель.
- Подключите компоненты, используя MM-штырьковый разъем. + 5В подключается к источнику питания 5 В, вывод GND подключен к GND, контакты VRx и VRy подключены к аналоговому входу, контакты и штырьковый разъем подключены к цифровому выводу ввода/вывода.
- Номер контакта будет основан по фактическому программному коду.
- После аппаратного соединения вставьте образец эскиза в среду разработки аrduino.
- Используя USB-кабель, подключите порты от микроконтроллера к компьютеру.
- Загрузите программу.
- Смотрите результаты на последовательном мониторе.
Источник
Руль, джойстик и геймпад с обратной связью (Force Feedback)
Поводом для этой статьи явился, принесенный мне на ремонт, руль GW21-FB китайского производства. Обычно в устройствах такого происхождения ужасная механика, дешевые электролитические конденсаторы, не качественная пайка и ремонт не вызывает проблем. Иногда выходит из строя контроллер (как правило бескорпусный, залитый компаундом), в этом случае приходится менять всю плату, т.е. создавать ее заново, т.к. купить ее негде. Если руль (джойстик, геймпад) без обратной связи, то схема получается небольшая и что-либо изобретать нет необходимости — примеров реализации таких устройств в сети предостаточно. Например: Mjoy16 , Analog Joystick
В данном случае обратная связь должна быть, и я, походив по Интернету, с удивлением обнаружил, что ни одной реализации с открытым кодом нет! Многие самодельщики (в основном англо- и немецкоязычные) брались за это, но безрезультатно. Ну, что же, попробуем восполнить этот пробел. И попытаемся сделать это дешево, иначе ремонт может стать просто нерентабельным.
Далее последуют нудные разъяснения, кому это скучно, могут сразу перейти в конец статьи и скачать архив с готовыми схемами, платой, исходниками и прошивками.
Итак, для начала, как же работает «обратная связь»или точнее FFB (Force feedback)? Есть два ее вида — Вибрационная и Активная. В первом случае в устройство просто встроен вибромотор, такой же как в сотовом телефоне, только немного помощнее. В определенные моменты игры, например при столкновении, наезде на препятствие, этот мотор включается и руль (джойстик, геймпад) начинает вибрировать.
На этом фото показан вибромотор в ручке джойстика. На ось мотора напрессован груз со смещенным центром тяжести. При вращении груза мотор вместе с ручкой начинает вибрировать. Достоверность тактильных ощущений при этом, естественно, не велика, поэтому чаще ставят два мотора. Они одинаковые, но грузы на них разные, поэтому у одного частота вибрации выше, но амплитуда ниже, у другого наоборот — частота ниже, а амплитуда выше. Кроме того, моторы расположены под углом друг к другу, поэтому и направление вибрации различно. Комбинируя одновременное и раздельное включение моторов можно несколько разнообразить тактильные ощущения.
Однако, частоту, амплитуду и, главное, направление вибраций, при таком подходе, варьировать крайне сложно, поэтому в устройствах более высокого класса применяется Активная система FFB. В рулях это мотор, соединенный с колесом руля зубчатой или ременной передачей:
В джойстиках применяют два мотора — по осям X и Y:
Я не для красоты привожу эти картинки. Возможно кто-то захочет доработать свой «безответный» аппарат системой FFB и они могут послужить наглядным пособием для этого. Как видите, ничего заумно-хитрого здесь нет.
Итак, с механикой все понятно, управление моторами не представляет особой сложности, но нужно знать как и когда их включать/выключать. Требуется получить по шине USB информацию от компьютера. Обычный руль, джойстик, геймпад это HID-устройство, даже не требующее драйвера, они есть в системе, но для FFB все сложнее. Нужно либо представиться системе устройством, способным самостоятельно формировать сигнал управления мотором, получая от компьютера все данные (длина волны, амплитуда, фаза и т.д.), либо использовать драйвер-преобразователь.
В первом случае потребуется постоянно принимать большие объемы информации и иметь контроллер с функциями DSP. Кроме того, нужно глубоко изучить систему формирования сигнала для написания управляющей прошивки при том, что для выставления правильных коэффициентов для DSP потребуется оригинал для сравнения.
Во втором случае можно использовать драйвер готового устройства. Он сам выполнит все нужные преобразования, а нам останется только принимать мгновенные значения силы и направления вращения и подавать их на мотор.
Собственно изначально задача была недорого и без головной боли отремонтировать (переделать) сабж, поэтому выбираем второй вариант. И без стеснений берем драйвер от фирмы Logitech. К концу повествования мы создадим несколько рулей, но начнем с самой сложной модели — G25:
Модель топовая, имеет три педали и 22 кнопки управления. Точнее говоря, из-за рычага переключения передач их кажется меньше, но информация о его положении передается как отдельные кнопки, а нам для выбора схемы важно знать их максимальное число, поэтому запомним — 22 кнопки + 3 педали.
Вот мы и подошли к схемной реализации. Сначала определимся с контроллером:
В современных рулях, джойстиках применяют высокоскоростной протокол USB 2.0, но мы попробуем обойтись низкоскоростным 1.1. Во первых принимаемый/передаваемый объем информации не столь уж велик, а во вторых микроконтроллеры с аппаратным USB довольно дороги, да и конвертеры USB/RS232 тоже. Попробуем применить «ширпотреб» — ATmega8 с программным вариантом реализации USB.
Прежде чем составить схему управления мотором FFB, требуется выяснить, в каком виде драйвер выдает эту информацию. Естественно, никакой документации на него нигде нет, обращение в службу поддержки завершилось отказом — протокол обмена секрет фирмы. Пришлось создать макет устройства, пытаться передавать драйверу данные и изучать его ответы. После нескольких дней мучений удалось выяснить, что комбинация
11 08 ХХ 80 00 00 00
означает включение мотора FFB, при этом ХХ определяет силу и направление вращения. ХХ принимает значение от 0 до 255, при этом 128 — «начало координат», все, что меньше — вращение влево, больше- вращение вправо. Т.е. данные можно сразу подавать на 8-битный ШИМ с мостовой схемой включения мотора. Комбинация
13 00 00 00 00 00 00
означает выключение мотора. Это тоже важно, т.к. при ШИМ=128 мотор, конечно, не крутится, но ток через него идет и, если уж компьютер разрешает, то лучше ток отключать.
Итак со схемой теперь все понятно:
Чтобы меньше сверлить отверстий в плате, применим SMD резисторы и конденсаторы:
Прошивку контроллера напишем в среде Bascom-AVR . Для программной реализации USB воспользуемся библиотекой SWUSB.LBX . Для удобства работы оформим дескрипторы и константы USB отдельными файлами, соответственно Descriptors.inc и USB_config.inc .
Сразу зададим начальное состояние портов ввода/вывода:
Назначим выводы D+ и D- для USB (D+ должна быть на INT0):
Зададим PID и VID, соответствующие Logitech G25:
В нашем распоряжении всего 8 байт для передачи хосту, а устройство имеет , как мы помним, 22 кнопки, руль и три педали. Плюс к этому нужно еще передать байт «Combined Pedals» — как выяснилось, при активации/деактивации этой опции драйвер не передает никаких управляющих сигналов устройству и даже не пытается скомбинировать этот режим из имеющейся информации о педалях. Оригинального дескриптора достать не удалось, да он нам и не помог бы, ведь настоящий G25 работает в USB 2.0 и не ограничен пространством — может передавать до 64 байт за раз. Поэтому пришлось ограничить разрядность данных для педалей до 7 бит, а для руля до 12 бит, и репорт-дескриптор в финале получился таким:
Т.е. получилась дискретность педалей 0,78% , а руля 0,024% . Не так уж и плохо.
Для составления репорт-дескриптора можно воспользоваться справочником HID Usage Tables или специальной программой HID Descriptor tool.
Дескриптор продукта и изготовителя не важны, можно поставить любые — драйвер все равно вместо них подставит в систему название «Logitech G25».
В основной программе принимаем данные от хоста и по первому байту сортируем: если $11 (dec 17), то включаем мотор и выставляем ШИМ, если $13 (dec 19) — выключаем мотор:
Частоту ШИМ задаем 375кГц (12МГц/32), т.о. частота на выходе будет около1,5кГц (375/256):
Выше частоту выставлять не рекомендую — транзисторы моста начнут греться, т.к. для их раскачки применен самый примитивный вариант (для удешевления конструкции). При этом в близи среднего положения руля мотор воспроизводит частоту 1,5кГц и для борьбы с этим эффектом последовательно с мотором включен дроссель, а параллельно конденсатор. Если имеются в наличии, то лучше для раскачки применить стандартные драйверы верхнего и нижнего плеч CMOS, тогда частоту ШИМ можно повысить до максимума (47кГц), не опасаясь перегрева и исключить дроссель.
АЦП в ATmega8 10-разрядный, поэтому для получения 12-разрядного значения сложим 4 последовательных значения с потенциометра колеса руля, заодно таким образом уменьшив флуктуации сигнала:
Состояние кнопок определим, выставляя поочередно на линиях Row0. Row3 низкий уровень. Резисторы, включенные в линии кнопок, защищают порты контроллера от короткого замыкания при одновременном нажатии двух и более кнопок. Программно для этого так же предусмотрены защитные временные интервалы.
Разъем GEAR дублирует кнопки S1 и S2 — его наличие необязательно.
На вторую ножку разъема кнопок выведен порт С3 — сюда можно будет подключить светодиод (пока не задействовано).
Данные переключателя видов «HAT» перед передачей хосту нужно перевести в градусы. Дискретность — 45°, при этом отжатое состояние соответствует 360°. Кроме того, эти данные нужно вписать в свободный верхний нибл старшего байта колеса руля, т.к. мы так задали в дескрипторе:
Потенциометры педалей опрашиваем аналогично колесу руля, так же 4 раза для снижения флуктуаций, затем делим на 32 (сдвигом на 5 разрядов вправо). В результате получаем данные в масштабе 7 бит. Далее создаем «Combined Pedals» — если не нажата педаль «тормоза», то она равна данным педали «газа». Если нажат «тормоз», то равна его инверсии — так требует драйвер.
Далее следует пересортировать биты данных в соответствии с заданной очередностью в репорт-дескрипторе. Обычно такого делать не требуется, но в данном случае мы вынужденно пошли на такие сложности из-за стесненных условий. Зато мы уместили в пакете большой объем информации. После пересортировки передаем данные хосту:
Программа закончена, можно ее скомпилировать и зашить в контроллер.
Скачиваем драйвер с сайта Logitech, устанавливаем его и подключаем наше устройство. Драйвер определит его как G25, заходим в свойства, здесь можно протестировать поворот руля, нажатие педалей — все сразу отразится на экране. Кроме того, нажимая на кнопки, можно протестировать FFB — «езда по деревянному мосту», «лопнувшая покрышка», «взрыв».
Второй руль, который мы будем создавать — Logitech Driving Force™ Pro:
Это престижная модель с двумя педалями и переключателем передач на встроенной консоли. Передачи переключаются только «вперед/назад». На консоли руля больше кнопок, чем на G25, но их суммарное число меньше — 18. Такая конфигурация очень распространена среди рулей с FFB, поэтому прошивка под нее будет наиболее востребована для ремонта или апгрейда.
Схема остается прежняя, вместо отсутствующей педали сцепления подключим потенциометр чувствительности. С его помощью можно будет, не заходя в настройки, прямо во время игры подстроить силу воздействия FFB:
У нас освободились 11 бит, поэтому мы можем установить на педали разрядность в 8 бит, а на колесо руля — 14. Это повысило точность и плавность управления. Изменения в дескрипторе и программе здесь приводить не буду — их можно посмотреть в прилагаемых исходниках.
Теперь попробуем сделать геймпад. За основу возьмем Logitech Rumblepad 2 :
Здесь FFB вибрационного типа, т.е. установлены два вибромотора, направление вращения которых не регулируется, только скорость. Поэтому вместо мостовой схемы применяются просто ключевые транзисторы и два выхода ШИМ. В ATmega8 два выхода имеет Таймер1, они уже выведены на разъем. Кроме того, для одномоторного случая можно задействовать освободившийся выход Таймера2 и подавать на него мажоритарный уровень левого и правого моторов FFB:
Теперь, не меняя схему и прошивку, можно подключить либо один, либо два мотора, в зависимости от конструкции устройства.
Съем данных с потенциометров и кнопок аналогичен предыдущим. Репорт-дескриптор имеет незначительные изменения.
Пакет для отправки хосту имеет следующий вид:
Последний байт всегда равен 64, таково требование драйвера — это своеобразный пароль.
Вот теперь, собственно, и все. По аналогии с вышеизложенным можно сделать джойстик, самолетный штурвал и проч. В приложении все схемы, пример платы в формате Cadsoft Eagle , исходники и откомпилированные коды. Библиотеку SWUSB.LBX перед компиляцией следует поместить в каталог Lib.
P.S. Использование драйвера не противозаконно, у меня были сомнения на этот счет, поэтому я испросил разрешение у фирмы Logitech и ответ был таков: мы не можем запретить Вам такое использование, однако, в этом случае мы не несем никакой ответственности за . и т.д.
Последнюю версию драйвера можно скачать здесь.
Источник