Как написать драйвер для геймпада
Поводом для этой статьи явился, принесенный мне на ремонт, руль 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
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 и ответ был таков: мы не можем запретить Вам такое использование, однако, в этом случае мы не несем никакой ответственности за . и т.д.
На игровых выставках разработчики Objects in Space показывали демо своей игры с контроллером на кокпите огромного космического корабля. Он был дополнен загорающимися кнопками, аналоговыми приборами, световыми индикаторами состояния, переключателями и т.д… Это сильно влияет на погружение в игру:
На сайте игры выложен туториал по Arduino с описанием коммуникационного протокола для подобных контроллеров.
Я хочу создать то же самое для своей игры
В этом примере я потрачу примерно 40 долларов, чтобы добавить красивые, большие и тяжёлые переключатели на кокпит симулятора гонок. Основные затраты связаны с этими самыми переключателями — если бы я использовал простые переключатели/кнопки, то цена была в два раза ниже! Это настоящее оборудование, способное выдерживать 240 Вт мощности, а я буду пускать по ним только примерно 0,03 Вт.
Предупреждение: я решил сэкономить, поэтому оставляю ссылку на дешёвый китайский веб-сайт, где закупаю кучу разных компонентов/инструментов. Один из недостатков покупки компонентов по дешёвке заключается в том, что часто у них нет никакой документации, поэтому в статье я решу и эту проблему.
Основные компоненты
-
— $9
- гоночная панель переключателей зажигания — $26
- Куча соединительных проводов («male to male», «male to female», и т.д. ) — $2
Рекомендуемые инструменты
- Паяльник (стоит выбирать хороший, но с работой справится и дешёвый)
- Припой (с канифолью 60/40 — с ним легко работать, хотя он и вреден для окружающей среды..)
- Термоусадочная трубка (и промышленный фен, фен для волос или зажигалка) или изолента
(и стержни к нему), или какая-нибудь эпоксидная смола - Кусачки/плоскогубцы для зачистки проводов, или просто ножницы, если нужно сэкономить.
Программное обеспечение
- Arduino IDE для программирования процессора Arduino
- Для создания контроллера, отображающегося как настоящий аппаратный USB-контроллер/джойстик:
- FLIP для прошивки нового firmware в USB-контроллер Arduino
- Библиотека arduino-usb на github
- Моя библиотека ois_protocol на github
, если вы хотите использовать контроллер как виртуальный USB-контроллер/джойстик.
Предупреждение
Я изучал электронику в старшей школе, научился пользоваться паяльником, узнал, что красные провода нужно соединять с красными, а чёрные с чёрными… Вольты, амперы, сопротивление и связывающие их уравнения — вот и всё, чем исчерпывалось моё формальное обучение электронике.
Для меня это был обучающий проект, поэтому в нём могут быть плохие советы или ошибки!
Работаем с переключателями без документации.
Как сказано выше, я покупаю дешёвые детали у розничного продавца с низкой маржей, поэтому первым делом нужно разобраться, как работают эти переключатели/кнопки.
Простая двухконтактная кнопка/переключатель
С кнопкой всё просто — в ней нет светодиодов и всего два контакта. Переключаем мультиметр в режим непрерывности/прозвонки () и касаемся щупами разных контактов — на экране будет отображаться OL (open loop, разомкнутая цепь): это означает, что между двумя щупами нет соединения. Затем нажимаем на кнопку, по-прежнему касаясь щупами контактов — на экране теперь должно отобразиться что-то типа 0.1Ω и мультиметр начнёт пищать (сообщая о том, что между щупами присутствует очень низкое сопротивление — замкнутая цепь).
Теперь мы знаем, что при нажатии кнопки цепь замыкается, а при отжатии — размыкается. На схеме это можно обозначить как простой выключатель:
Подключаем переключатель к Arduino
Найдите на плате Arduino два контакта: помеченный GND и помеченный «2» (или любым другим произвольным числом — это контакты ввода-вывода общего назначения, которыми мы можем управлять через ПО).
Если мы подключим переключатель таким образом, а потом прикажем Arduino сконфигурировать контакт «2» как контакт INPUT, то получим цепь, показанную слева (на рисунке ниже). При нажатии кнопки контакт 2 будет напрямую соединяться с землёй / 0V, а при отжатии контакт 2 не будет соединён ни с чем. Это состояние (ни с чем не соединён) называется «floating» (состояние с высоким импедансом) и, к сожалению, это не очень хорошее состояние для наших целей. Когда мы считываем данные с контакта в ПО (с помощью digitalRead(2)), получаем LOW, если контакт заземлён, и непредсказуемый результат (LOW или HIGH), если контакт находится в состоянии floating!
Разработчикам ПО порядок может показаться обратным — при нажатии кнопки мы считываем false / LOW, а при отжатии — true / HIGH.
Можно сделать и наоборот, но у процессора есть только встроенные подтягивающие резисторы и нет утягивающих вниз резисторов, поэтому мы будем придерживаться этой модели.
Простейшая программа для Arduino, которая считывает состояние переключателя и сообщает PC о его состоянии, выглядит примерно так, как показано ниже. Вы можете нажать кнопку загрузки в Arduino IDE, а затем открыть Serial Monitor (в меню Tools), чтобы увидеть результаты.
Другие переключатели почти без документации.
Светодиодный переключатель с тремя контактами
К счастью, на основных переключателях моей панели есть пометки трёх контактов:
Я не полностью уверен, как он работает, поэтому мы снова переключим мультиметр в режим непрерывности и коснёмся всех пар контактов при включенном и отключенном переключателе… однако на этот раз мультиметр вообще не пищит, когда мы касаемся щупами [GND] и [+] при «включенном» переключателе! Единственная конфигурация, при которой мультиметр пищит (обнаруживает соединение) — когда переключатель «включен», а щупы находятся на [+] и [lamp].
Светодиод внутри переключателя блокирует измерения непрерывности, поэтому из проведённых выше проверок мы можем предположить, что LED подключен непосредственно к контакту [GND], а не к контактам [+] и [lamp]. Далее мы переключим мультиметр в режим проверки диодов (символ ) и снова проверим пары контактов, но на этот раз важна полярность (красный и чёрный щуп). Теперь если мы соединим красный щуп с [lamp], а чёрный — с [GND], то светодиод загорится, а на мультиметре отобразится 2.25V. Это прямое напряжение диода, или минимальное напряжение, необходимое для его включения. Вне зависимости от положения переключателя, 2.25V от [lamp] к [GND] заставляет LED загореться. Если мы соединим красный щуп с [+], а чёрный — с [GND], то светодиод загорится только при включённом переключателе.
Из этих показаний мы можем предположить, что внутренности этого переключателя выглядят примерно как на схеме ниже:
- [+] и [lamp] замыкаются накоротко, когда переключатель включен/замкнут.
- Положительное напряжение от [lamp] к [GND] всегда зажигает светодиод.
- Положительное напряжение от [+] к [GND] зажигает светодиод только при включенном/замкнутом переключателе.
Честно говоря, о присутствии резистора здесь можно только догадываться. Светодиод должен быть соединён с соответствующим резистором, чтобы ограничивать подаваемый на него ток, или он сгорит. Мой не сгорел и похоже, что работает правильно. На форуме веб-сайта продавца я нашёл пост, в котором говорится об установленном резисторе, поддерживающем работу до 12 В, и это сэкономило мне время на проверку/вычисления подходящего резистора.
Подключаем переключатель к Arduino
Проще всего использовать переключатель с Arduino, проигнорировав контакт [lamp]: подключить [GND] к GND в Arduino и соединить [+] с одним из пронумерованных контактов Arduino, например 3.
Если мы сконфигурируем контакт 3 как INPUT_PULLUP (так же, как и для предыдущей кнопки), то придём к показанному ниже результату. Слева вверху показано значение, которое мы будем получать, выполнив «digitalRead(3)» в коде Arduino.
Когда переключатель включен/замкнут, мы считываем LOW и светодиод загорается! Для использования такого переключателя в данной конфигурации мы можем использовать тот же код Arduino, что и в примере с кнопкой.
Проблемы этого решения
После подключения к Arduino полная цепь выглядит так:
Однако здесь мы можем увидеть, что при замыкании переключателя кроме небольшого ограничивающего ток резистора перед LED (я предполагаю, что его сопротивление 100 Ом) есть и ещё и подтягивающий резистор на 20 кОм, который ещё больше снижает величину тока, текущего через светодиод. Это означает, что хотя цепь и работает, светодиод будет не очень ярким.
Ещё один недостаток этой схемы в том, что у нас нет программного контроля над LED — он включён, когда включён переключатель, и отключен в противоположном случае.
Можно посмотреть, что случится, если мы подключим контакт [lamp] или к 0V, или к +5V.
Если [lamp] подключен к 0V, то светодиод постоянно отключен (вне зависимости от позиции переключателя), а распознавание позиции Arduino всё равно выполняется. Это позволяет нам при желании программно отключать LED!
Если [lamp] подключен к +5V, то светодиод постоянно включен (вне зависимости от позиции переключателя), однако распознавание позиции Arduino поломано — с контакта всегда будет считываться HIGH.
Подключаем этот переключатель к Arduino правильно
Мы можем преодолеть описанные выше ограничения (низкий ток/яркость светодиода и отсутствие программного контроля над светодиодом), написав больше кода! Чтобы разрешить конфликт между возможностью управления светодиодом и сломанным из-за него распознаванием позиции, мы можем разделить две задачи по времени, то есть временно отключать LED при считывании контакта датчика (3).
Сначала подключим контакт [lamp] к ещё одному контакту Arduino общего назначения, например, к 4, чтобы можно было управлять lamp.
Чтобы создать программу, которая будет правильно считывать позицию переключателя и управлять светодиодом (мы заставим его мигать), нам достаточно просто отключать светодиод перед считыванием состояния переключателя. Светодиод будет отключаться всего на доли миллисекунд, поэтому мерцание не должно быть заметно:
В Arduino Mega контакты 2-13 и 44-46 могут использовать функцию analogWrite, которая на самом деле не создаёт напряжения от 0V до +5V, а аппроксимирует его при помощи прямоугольной волны. При желании можно использовать её для управления яркостью светодиода! Этот код заставит свет пульсировать, а не просто мерцать:Подсказки по сборке
Пост и так уже довольно большой, так что я не буду добавлять ещё и туториал по пайке, можете его загуглить!
Однако приведу самые базовые советы:
- При соединении проводов с большими металлическим контактами сначала убедитесь, что паяльник нагрелся и какое-то время нагревайте и металлический контакт. Смысл пайки заключается в образовании постоянного соединения созданием сплава, но если горячей является только одна часть соединения, то у вас запросто может получиться «холодное соединение», которое выглядит как соединение, но на самом деле не соединено.
- При соединении двух проводов наденьте сначала на один из них кусок термоусадочной трубки — после соединения трубку надеть будет нельзя. Это кажется очевидным, но я постоянно это забываю и мне приходится использовать вместо трубки изоленту… Протяните термоусадочную трубку подальше от соединения, чтобы она не нагрелась раньше времени. Проверив паянное соединение сдвиньте на него трубку и нагрейте её.
- Тонкие маленькие соединительные провода, которые я упоминал в начале, хорошо подходят для соединений без пайки (например, при подключении к Arduino!), но довольно хрупкие. После пайки используйте для их закрепления клеевой пистолет и устраните из самого соединения все напряжения. Например, красные провода на показанном ниже снимке при работе можно случайно потянуть, поэтому после пайки я зафиксировал их каплей горячего клея:
Но после заливки этого firmware в Arduino устройство становится USB-джойстиком и перестаёт быть Arduino. Поэтому чтобы перепрограммировать его, нужно заново перепрошить исходную firmware Arduino. Эти итерации довольно мучительны — загружаем код Arduino, прошиваем firmware джойстика, тестируем, прошиваем firmware arduino, повторяем…
Пример программы для Arduino, которую можно использовать с этим firmware, показан ниже — он конфигурирует три кнопки в качестве вводов, считывает их значения, копирует значения в структуру данных, ожидаемую этим firmware, а затем отправляет данные. Смыть, намылить, повторить.
Если у вас есть контроль над игрой, с которой должно взаимодействовать устройство, то в качестве альтернативы можно общаться с контроллером напрямую — нет необходимости делать его видимым для ОС как джойстик! В начале поста я упомянул Objects In Space; именно такой подход использовали её разработчики. Они создали простой коммуникационный ASCII-протокол, позволяющий контроллеру и игре общаться друг с другом. Достаточно просто перечислить последовательные порты системы (они же COM-порты в Windows; кстати, посмотрите, как ужасно это выглядит на C), найти порт, к которому подключено устройство с названием «Arduino», и начать считывать/записывать ASCII по этой ссылке.
На стороне Arduino мы просто используем функции Serial.print, которые применялись в показанных выше примерах.
Она содержит код на C++, который можно интегрировать в игру и использовать её в качестве «сервера», и код Arduino, который можно выполнять в контроллере, чтобы использовать его в качестве «клиента».
Настраиваем Arduino
В example_hardware.h я создал классы, чтобы абстрагировать отдельные кнопки/переключатели; например, «Switch» — это простая кнопка из первого примера., а «LedSwitch2Pin» — переключатель с управляемым светодиодом из второго примера.
Код примера для моей панели кнопок находится в example.ino.
В качестве небольшого примера давайте допустим, что у нас есть единственная кнопка, которую нужно отправлять в игру, и один управляемый игрой светодиод. Необходимый код Arduino выглядит так:
Настраиваем игру
Код игры написан в стиле «single header». Для импорта библиотеки включим в игру oisdevice.h.
Для перечисления COM-портов и создания соединения с конкретным устройством можно использовать такой код:
Получив экземпляр OisDevice, нужно регулярно вызывать его функцию-член Poll (например, в каждом кадре), можно получать текущее состояние вывода контроллера с помощью DeviceOutputs(), использовать события устройства с помощью PopEvents() и отправлять устройству значения с помощью SetInput().Пример приложения, делающего всё это, можно найти здесь: example_ois2vjoy/main.cpp.
Чтобы контроллер мог работать в других играх (часть 2), нужно установить собственное firmware и одну программу Arduino, но чтобы контроллер полностью программировался игрой, мы использовали стандартное firmware Arduino и другую программу Arduino. Но что если мы хотим иметь обе возможности одновременно?
Пример приложения, на который я давал ссылку выше (ois2vjoy), решает эту проблему.
Это приложение общается с OIS-устройством (программа из части 3), а затем на PC преобразует эти данные в обычные данные контроллера/джойстика, которые потом передаются в виртуальное устройство контроллера/джойстика. Это означает, что можно позволить своему контроллеру постоянно использовать библиотеку OIS (другое firmware не требуется), а если мы захотим использовать его как обычный контроллер/джойстик, то просто запустим на PC приложение ois2vjoy, выполняющее преобразование.
Надеюсь, кому-то эта статья показалась полезной или интересной. Спасибо, что дочитали до конца!
Если вам стало любопытно, то я приглашаю вас поучаствовать в развитии библиотеки ois_protocol! Думаю, будет здорово разработать единый протокол для поддержки всевозможных самодельных контроллеров в играх и стимулировать игры к прямой поддержке самодельных контроллеров!
В данной статье описан процесс написания простейшего драйвера, который выводит скан-коды нажатых клавиш.
Также в данной статье описан процесс настройки рабочего места для написания драйверов.
Если Вам интересно, прошу под кат.Подготовка стенда
Установка необходимого ПО для написания простейшего драйвера
- Windows DDK (Driver Development Kit);
- VMware Workstation или Virtual Box;
- Windows XP;
- Visual Studio 2005;
- DDKWizard;
- KmdManager
- DebugView;
Настройка рабочего места
Установка DDK
Установка предельно проста. Единственное на что необходимо обратить внимание — это диалог, в котором Вам предлагается выбрать компоненты, которые будут установлены. Настоятельно рекомендую отметить всю документацию и примеры.
Установка и настройка Microsoft® Visual Studio 2005
Установка Microsoft® Visual Studio 2005 ничем не сложнее установки DDK. Если Вы будете использовать её только для написания драйверов, то когда инсталлятор спросит какие компоненты необходимо установить, выберите только Visual C++.
Далее можно установить Visual Assist X. С помощью этой программы (аддона) можно будет легко настроить подсказки для удобного написания драйверов.
После установки Visual Assist X в Visual Studio 2005 появится новое меню VAssistX. Далее в этом меню: Visual Assist X Options -> Projects -> C/C++ Directories -> Platform: Custom, Show Directories for: Stable include files . Нажимаем Ins или на иконку добавить новую директорию и в появившейся строке, если у вас Windows XP вписываем %WXPBASE%\inc\ddk\wxp .Установка и настройка DDKWizard
- Создать системные (рекомендуется) или пользовательские переменные со следующими именами и значением, которое соответствует пути к DDK
Версия DDK Имя переменной Путь по умолчанию Windows XP DDK WXPBASE C:\WINDDK\2600 Windows 2003 Server DDK WNETBASE C:\WINDDK\3790.1830 Windows Vista/Windows 2008 Server WDK WLHBASE Windows 7/Windows 2008 Server R2 WDK W7BASE
Например, если я использую Windows XP DDK, то я должен создать переменную WXPBASE со значением, которое соответствует пути к DDK. Так как я не изменял путь установки, то значение у меня будет C:\WINDDK\2600. - Скопируйте скачанный скрипт ddkbuild.cmd, например, в папку с DDK. У меня это C:\WINDDK\.
- Добавьте в конец системной переменной Path путь к скрипту ddkbuild.cmd.
Установка необходимого ПО для запуска драйверов
- DebugView (link) — это утилитка, которая позволяет просматривать отладочный вывод как режима пользователя так и режима ядра.
- KmdManager (link) — утилита динамической загрузки/выгрузки драйверов
Постановка задачи
Задача: написать драйвер, который будет выводить в дебаг скан-коды нажатых клавиш и их комбинаций.
Немного теории
- драйверы классов;
- минидрайверы;
- функциональные драйверы;
- фильтрующие драйверы.
Необязательно определять все возожные функции в своем драйвере, но он обязательно должен содержать DriverEntry и AddDevice .
IRP — это структура, которая используется драйверами для обмена данными.
- верхние фильтрующие драйверы;
- нижние фильтрующие драйверы.
Отличия между верхними и нижними фильтрующими драйверами
Через верхние фильтрующие драйверы проходят все запросы, а это значит, что они могут изменять и/или фильтровать информацию, идущую к функциональному драйверу, ну и далее, возможно, к устройству.
Пример использования верхних фильтрующих драйверов:
Фильтр-хук драйвер, который устанавливает свою хук-функцию для системного драйвера IpFilterDirver, для отслеживания и фильтрации траффика. Такие драйверы используются в брандмауэрах.Через нижние фильтрующие драйверы проходит меньше запросов потому что большинство запросов выполняет и завершает функциональный драйвер.
Проблемы синхронизации
В драйвере, который мы будем писать, есть несколько «проблемных» секций. Для нашего драйвера вполне достаточно использования ассемблерных вставок:
Префикс lock позволяет безопасно выполнить идущую за ним команду. Она блокирует остальные процессоры, пока выполняется команда.
Экшен
Для начала необходимо включить заголовочные файлы «ntddk.h», «ntddkbd.h»
Также необходимо описать структуру DEVICE_EXTENSIONОбъект pLowerDO это объект устройства, который находится ниже нас в стеке. Он нужен нам для того чтобы знать кому дальше отправлять IRP-пакеты.
Еще для работы нашего драйвера нам нужна переменная, в которой будет храниться количество не завершенных запросов.Начнем с функции, которая является главной точкой входа нашего драйвера.
theDriverObject – объект драйвера, содержит указатели на все необходимые операционной системе функции, которые мы должны будем инициализировать.
ustrRegistryPath – имя раздела в реестре, где хранится информация о данном драйвере.
Для начала необходимо объявить и обнулить переменные:Далее, как я и писал выше, нужно инициализировать указатели на функции
Функция DispatchRead будет обрабатывать запросы на чтение. Она будет вызываться, когда нажата или отпущена клавиша клавиатуры.
Функция DriverUnload вызывается, когда драйвер уже не нужен и его можно выгрузить из памяти, или когда пользователь сам выгружает драйвер. В данной функции должна производиться «зачистка», т.е. освобождаться ресурсы, которые использовались драйвером, завершаться все незавершенные запросы и т.д.
Функция DispatchThru это функция-заглушка. Все что она делает это передача IRP-пакета следующему драйверу (драйверу который находится под нашим в стеке, т.е. pLowerDO из DEVICE_EXTENSION ).
Далее мы вызываем нашу функцию, для создания и установки нашего устройства в стек устройств:Эту функцию я опишу чуть ниже.
Возвращаем status , в котором, если функция InstallFilter завершилась удачей, хранится значение STATUS_SUCCESS .
Переходим к функции InstallFilter . Вот её прототип:Эта функция создает объект устройства, настраивает его и включает в стек устройств поверх \\Device\\KeyboardClass0
pKeyboardDevice – это объект устройсва, которое мы должны создать.
Вызываем IoCreateDevice для создания нового устройства- Первый аргумент это объект драйвера, который мы получили как параметр функции InstallFilter. Он передается в IoCreateDevice для того чтобы установить связь между нашим драйвером и новым устройством.
- Третий параметр это имя устройства
- Четвертый параметр это тип устройства
- Пятый параметр это флаги, которые обычно устанавливаются для запоминающих устройств.
- Шестой параметр описывает можно ли открывать манипуляторы устройства в количестве больше одного. Если FALSE можно открыть только один манипулятор. Иначе можно открыть любое количество манипуляторов.
- Седьмой параметр это память, в которой будем сохранен созданный объект устройства.
Флаги, которые мы устанавливаем для нашего устройства, должны быть эквивалентными флагам устройства, поверх которого мы включаемся в стек.
Далее мы должны выполнить преобразования имени устройства, которое мы включаем в стек.Функция IoAttachDevice внедряет наше устройство в стек. В pdx->pLowerDO будет храниться объект следующего (нижнего) устройства.
Далее разберем функцию DispatchRead с прототипом:
Данная функция будет вызываться операционной системой при нажатии или отпускании клавиши клавиатуры
Увеличиваем счетчик незавершенных запросовПеред тем как передать запрос следующему драйверу мы должны настроить указатель стека для драйвера. IoCopyCurrentIrpStackLocationToNext копирует участок памяти, который принадлежит текущему драйверу, в область памяти следующего драйвера.
Когда запрос идет вниз по стеку в нем еще нет нужных нам данных, поэтому мы должны задать функцию, которая вызовется, когда запрос будет идти вверх по стеку с нужными нам данными.где ReadCompletionRoutine наша функция.
Передаем IRP следующему драйверу:Теперь разберем функцию, которая будет вызываться каждый раз при завершении IRP . Прототип:
Структура PKEYBOARD_INPUT_DATA используется для описания нажатой клавиши.
Проверяем, удачно завершен запрос или нет
Чтобы достать структуру KEYBOARD_INPUT_DATA нужно обратиться к системному буферу IRP -пакета.
Узнаем количество клавиш
И выводим каждую клавишу:
И не забываем уменьшать количество не обработанных запросов
Возвращаем статус запроса
Разберем функцию завершения работы. Прототип:
Извлекаем устройство из стека:
Проверяем есть незавершенные запросы или нет. Если мы выгрузим драйвер без этой проверки, при первом нажатии на клавишу после выгрузки будет БСоД.
Как запустить драйвер и просмотреть отладочную информацию
Для запуска драйвера я использовал утилиту KmdManager. Для просмотра отладочной информации использовалась утилита DbgView.
P. S. Статью писал давно, ещё на третьем курсе, сейчас уже почти ничего не помню. Но если есть вопросы, постараюсь ответить.
P. P. S. Прошу обратить внимание на комментарии, в частности на этот- Вы не можете создать новую тему
- Вы не можете ответить в тему
Программирование драйверов устройств для чайников
Введение
В этой теме я планирую дать серию уроков, которые позволят любому человеку получить базовое представление о том, как устроена система взаимодействия прикладного ПО и драйверов ОС Windows, научиться читать исходные коды существующих драйверов устройств или написать свой собственный драйвер, работающий с его собственным устройством.
Также эти уроки могут помочь аудитории владельцев видеокарт с графическими чипами, произведенными компанией 3dfx, разобраться в доступных исходных кодах драйверов этих видеокарт. Упомянутые исходники могут быть с наименьшим количеством переделок откомпилированы под Windows XP/Windows 2003 Server, которые и будут являться основной целевой системой. В более современной Windows Vista/7 несколько изменилась модель драйверов, наиболее сильно это затронуло графическую подсистему. Это означает, что для их корректной работы придется переписать весьма значительную часть кода. Кроме того, под х64 версиями Vista/7 и более старших операционных систем просто так нельзя загрузить драйвер, не имеющей цифровой подписи. Подпись стоит порядка 500 долларов в год (150, если найти купон на скидку), их не любят давать частным лицам и даже небольшим организациям. Кроме того, если в подписанном драйвере обнаружится уязвимость и ей воспользуются хакеры – то подпись данного [почти всегда юридического] лица аннулируется и у него возникают проблемы с получением новой. Еще есть такая процедура, как WHQL-сертификация, но ее я вообще не собираюсь пока здесь обсуждать.
Весьма приветствуется, если другие люди будут давать здесь свои собственные уроки, не выходящие за пределы темы. Также здесь можно задавать любые вопросы, предлагать свои идеи для следующих уроков и отписываться об своих удачных/неудачных результатах.
Для начала работы требуется иметь некоторое знакомство с любым языком программирования. Думаю, для этого вполне достаточно школьного / вузовского курса для непрограммистов. Если же в современных программах образования знакомство с программированием не было предусмотрено/за давностью лет курс забыт или просто что-то непонятно – отписывайтесь в теме, я напишу другие уроки, подробней раскрывающие непонятную тему.
Хотелось бы также видеть уроки по работе с драйверами для Windows 9x. Например, для AALchemy есть драйвер для Windows XP. Но вот для Windows 9x - нет.
Урок 0. Установка и настройка программного обеспечения
Список используемого программного обеспечения:
Все используемое мною программное обеспечение – на английском языке. В большинстве случаев можно использовать и русские версии, но может возникнуть путаница в командах или другие проблемы с совместимостью. Для начала работы потребуется компьютер с установленной обычной 32-разрядной Windows XP/2003. Продвинутые пользователи могут пользоваться необычной – отладочной, она же - checked build. Эта версия показывает больше информации при отладке устройств. Обычная же версия Windows носит название free build. Компьютер для экспериментов может быть как реальным, так и виртуальным. Разрабатываемые программы я буду проверять на одной реальной машине и одной виртуальной. На обоих установлен Windows Server 2003 R2 Enterprise Edition c SP2. Виртуальная машина запущена под VMWare Workstation 8.0.2.
Установка Visual Studio
Я буду использовать Visual Studio 2010 Ultimate. В принципе, ставить ее не обязательно, так как все необходимые инструменты, включая компилятор и заголовки есть и в WDK. Но для написания прикладных программ, в особенности для новичка, она намного удобней вызова компилятора из консоли. Если ее все же планируется установить, то лучше делать это перед установкой WDK.
Рис 0.1 – Выбор пакетов в установщике Visual StudioУстановка WDK
Монтируем скачанный iso-образ аналогично тому, как это было сделано с Visual Studio. Запускаем KitSetup.exe, на этапе выбора пакетов устанавливаем галочки в соответствии с рисунком:
Рис 0.2 – Выбор пакетов в установщике WDKУстанавливать Visual Studio и WDK не обязательно на той же машине, на которой планируется проверять работу программ. Для проверки я поставил их на реальной машине с Windows 7 х64 и откомпилировал драйвер, который заработал под Windows 2003 Server х86.
Создаем на диске каталог для проектов, учитывая вышеописанные рекомендации (без пробелов и русских букв), например C:\Projects. Запускаем Visual Studio, открываем настройки (меню Tools/Option), выбираем в дереве «Projects and Solutions/General», в параметре Projects location выбираем/указываем созданный каталог.Также настоятельно рекомендую установить Far Manager 2 и работать через него. Его преимущество над Windows/Total Commander'ами и Explorer'ами в том, что через него нормально видно содержимое консоли (команда ctrl + O), куда выдается полезная информация при компиляции и запуске консольных программ. Путь установки желательно записать в переменную PATH.
В дальнейшем рассмотрим и драйверы для Windows 9x. Для этого потребуется другое программное обеспечение, но программирование драйверов для Windows 9x проще.
Геймпады являются незаменимым помощником для геймеров. Они могут иметь разные названия – игровой контроллер, джойстик, геймпад – но они выполняют одну функцию: подключить игрока к игровой приставке.
Геймпад состоит из нескольких кнопок и до двух джойстиков, позволяющих пользователю управлять объектами в видеоиграх.
Хотя портативные игровые системы поставляются со встроенным геймпадом, некоторые геймпады предназначены для подключения к компьютеру через USB-соединение.
Это стало серьезной проблемой для пользователей, которые обновились до Windows 10, поскольку последняя операционная система, похоже, не распознает существующие геймпады для некоторых пользователей.
Более опытные пользователи считают, что проблема в том, что Microsoft заменила оригинальные драйверы оборудования при установке Windows 10.
Другие пользователи сообщают, что проблема связана с тем, что драйвер оборудования не имеет цифровой подписи. Тем не менее, другие столкнулись с проблемой после перехода на Windows 10, когда геймпад был подключен к компьютеру.
Другими словами, ошибку можно было бы предотвратить, если бы периферийное устройство было отключено во время выполнения обновления.
Но для тех, кто уже испытывает проблему, мы постараемся предоставить лучшие решения.
Мы уже много писали о проблемах с геймпадом. Добавьте эту страницу в закладки, если она понадобится вам позже.
Что делать, если USB-геймпад не распознается на ПК
Многие геймеры предпочитают использовать геймпады на своих ПК, однако иногда могут возникнуть проблемы с вашим геймпадом. Говоря о проблемах геймпада, вот некоторые из распространенных проблем, о которых сообщили пользователи:
- USB-геймпад не распознается Windows 10, 8, 7 . Эта проблема может возникать в любой версии Windows, и даже если вы не используете Windows 10, вам следует попробовать некоторые из наших решений, поскольку они все совместим со старыми версиями Windows.
- Геймпад не обнаруженWindows 10 . Если ваш геймпад не обнаружен в Windows 10, скорее всего, проблема связана с драйвером. Чтобы устранить проблему, обновите драйверы геймпада и проверьте, помогает ли это.
- Обычный геймпад не распознан . Обычные геймпады могут иногда сталкиваться с этой проблемой. Чтобы устранить проблему, обязательно обновите их драйверы из диспетчера устройств.
- Геймпад для Xbox не распознается – Windows 10 совместима с контроллерами Xbox, но иногда могут возникать проблемы. Мы уже рассматривали проблемы с контроллером Xbox в Windows 10 в одной из наших предыдущих статей, поэтому обязательно ознакомьтесь с ними для получения дополнительной информации.
- Геймпад не работает в играх, ПК . Если вы столкнулись с этой проблемой, вполне вероятно, что ваш контроллер настроен неправильно. Кроме того, проблема также может быть в драйверах геймпада, поэтому держите их в курсе.
- Геймпад отсутствует в диспетчере устройств . Если геймпад отсутствует в диспетчере устройств, возможно, он не распознается вашей системой. Чтобы решить эту проблему, вам нужно найти любые неизвестные устройства в диспетчере устройств и обновить их драйверы.
Решение 1. Запустите средство устранения неполадок оборудования и устройств.
Нераспознанный геймпад в Windows 10 может возникнуть из-за конфликтующих драйверов. Чтобы устранить проблему, перезагрузите компьютер и подключите геймпад. Теперь запустите средство устранения неполадок оборудования и устройств, выполнив следующие действия:
- Нажмите Ключ Windows + I , чтобы открыть приложение Настройки . Когда откроется Приложение настроек , перейдите в раздел Обновление и безопасность .
- Выберите «Устранение неполадок» в меню слева. Теперь на правой панели выберите Оборудование и устройства и нажмите Запустить кнопку устранения неполадок .
- Следуйте инструкциям на экране для устранения неполадок.
После устранения неполадок проверьте, устранена ли проблема.
Решение 2 – Загрузите последнюю версию драйвера геймпада
Иногда игровые планшеты могут не работать с Windows 10, поскольку был заменен старый драйвер устройства. Загрузка и установка последней версии драйвера с веб-сайта производителя может помочь решить проблему.
Если обновленный драйвер недоступен, попробуйте загрузить и установить доступный драйвер в режиме совместимости с Windows 8 или Windows 7. Этот метод запускает драйвер, используя предыдущие настройки, когда он нормально работал с Windows.
Вот пошаговая инструкция по установке последней версии драйвера в режиме совместимости:
- Загрузите последнюю версию драйвера и щелкните правой кнопкой мыши файл установки, чтобы найти свойства .
- На вкладке совместимости нажмите Запустить эту программу в режиме совместимостидля и выберите операционную систему до обновления Windows 10 из раскрывающегося меню.
- Завершите процесс установки и перезагрузите компьютер после завершения.
Ознакомьтесь с этим полным руководством, чтобы стать экспертом по обновлению драйверов!
Автоматическое обновление драйверов (рекомендуется сторонний инструмент)
Загрузка и установка драйверов вручную – это процесс, который несет в себе риск установки неправильного драйвера, что может привести к серьезным неисправностям.
Мы настоятельно рекомендуем вам автоматически обновить драйвер с помощью инструмента Обновление драйверов Tweakbit .
Этот инструмент одобрен Microsoft и Norton Antivirus, и после нескольких тестов наша команда пришла к выводу, что это наиболее автоматизированное решение. Вот как использовать это программное обеспечение:
- Загрузите и установите средство обновления драйверов TweakBit
- После установки программа начнет сканирование вашего компьютера на наличие устаревших драйверов автоматически. Driver Updater проверит установленные вами версии драйверов по своей облачной базе данных последних версий и порекомендует правильные обновления. Все, что вам нужно сделать, это дождаться завершения сканирования.
- По завершении сканирования вы получите отчет обо всех проблемных драйверах, найденных на вашем ПК. Просмотрите список и посмотрите, хотите ли вы обновить каждый драйвер по отдельности или все сразу. Чтобы обновить один драйвер за раз, нажмите ссылку «Обновить драйвер» рядом с именем драйвера. Или просто нажмите кнопку «Обновить все» внизу, чтобы автоматически установить все рекомендуемые обновления.
Примечание.Некоторые драйверы необходимо установить в несколько этапов, поэтому вам придется нажмите кнопку «Обновить» несколько раз, пока все его компоненты не будут установлены.
Отказ от ответственности : некоторые функции этого инструмента не являются бесплатными.
Решение 3 – Отключите другие устройства
Иногда Windows может не обнаружить ваш геймпад из-за перегрузки устройств, подключенных к вашей машине. Попробуйте отсоединить другие устройства plug-and-play и посмотрите, сохраняется ли проблема.
Кроме того, если вы используете USB-концентратор, обязательно отсоедините геймпад от USB-концентратора и подключите его непосредственно к компьютеру.
В некоторых редких случаях другие устройства, подключенные к вашему концентратору, могут создавать помехи вашему контроллеру, вызывая проблему.
Наконец, вы также можете попробовать подключить контроллер к другому USB-порту. Ваш контроллер не может использовать всю полосу пропускания порта USB 3.0, поэтому обязательно подключите его к порту USB 2.0 на вашем ПК.
Решение 4. Не допускайте автоматического отключения подключенных устройств на компьютере.
Если после выполнения описанных выше действий Windows по-прежнему не распознает ваш геймпад, попробуйте запретить системе автоматически отключать определенные устройства.
- Откройте Диспетчер устройств и разверните Контроллеры последовательной шины USB .
- Щелкните правой кнопкой мыши корневой USB-концентратор и выберите Свойства -> Управление питанием и снимите все флажки, в которых указано Разрешить компьютеру выключать это устройство для экономии энергии .
Решение 5 – Отключить геймпад
Если ваш геймпад не распознается в Windows 10, вы можете решить эту проблему, просто отключив и включив контроллер. Это может заставить Windows повторно инициализировать устройство и установить необходимые драйверы.
Чтобы отключить ваше устройство, вам просто нужно сделать следующее:
- Откройте Диспетчер устройств и найдите свой геймпад.
- Нажмите его правой кнопкой мыши и выберите в меню Отключить .
- Откроется диалоговое окно подтверждения. Выберите Да , чтобы отключить его.
- Теперь подождите несколько секунд, снова нажмите правую кнопку мыши на отключенном геймпаде и выберите в меню Включить .
После включения геймпада Windows распознает его и попытается установить для него необходимые драйверы.
Решение 6 – Измените настройки вашего плана
По словам пользователей, иногда ваш геймпад может не распознаваться в Windows 10. В этом случае вам необходимо изменить настройки выборочной приостановки USB.
Вы можете сделать это, изменив расширенные настройки вашего плана питания.
Это не сложно, и вы можете сделать это, выполнив следующие действия:
После этого проблема с вашим геймпадом должна быть решена.
План питания постоянно меняется? Решите проблему легко с нашим подробным руководством!
Решение 7. Установите универсальные драйверы USB-концентраторов.
Если ваш геймпад не распознается в Windows 10, возможно, проблема в драйверах USB-концентратора.
Ваш компьютер имеет несколько встроенных USB-концентраторов, и если у вас возникнут проблемы с драйверами, вы можете столкнуться с этой проблемой.
- Откройте Диспетчер устройств и найдите USB Root Hub . У вас должно быть несколько таких устройств на вашем ПК.
- Щелкните правой кнопкой мыши устройство USB Root Hub и выберите Обновить драйвер .
- Выберите Просмотреть мой компьютер для поиска драйверов .
- Теперь нажмите Позвольте мне выбрать из списка доступных драйверов на моем компьютере .
- Выберите USB Root Hub в списке и нажмите Далее .
- Теперь повторите шаги 2-5 для всех драйверов USB Root Hub .
Кроме того, вы также можете скачать необходимые драйверы от производителя вашей материнской платы и проверить, решают ли они вашу проблему.
Решение 8 – Переустановите ваш геймпад
Если у вас есть проблемы с геймпадом, попробуйте переустановить его. Иногда в вашей системе может возникать сбой, приводящий к возникновению этой и подобных проблем.
Однако вы можете решить эту проблему, просто переустановив геймпад. Для этого просто выполните следующие действия:
- Откройте Диспетчер устройств и найдите свой геймпад в списке. Нажмите его правой кнопкой мыши и выберите Удалить устройство .
- Когда появится диалоговое окно подтверждения, нажмите Удалить .
После удаления драйвера перезагрузите компьютер. После перезагрузки ПК Windows установит отсутствующие драйверы, и проблема должна быть решена.
Решение 9 – Проверьте, правильно ли работает ваш контроллер
Если ваш контроллер не распознается, возможно, он не работает. Иногда ваш USB-кабель может сломаться, и это может привести к этой проблеме.
Чтобы проверить, правильно ли работает ваш контроллер, мы советуем вам подключить его к другому ПК и посмотреть, работает ли он.
Если контроллер работает на другом ПК без каких-либо проблем, проблема, скорее всего, связана с вашей системой. С другой стороны, если другой компьютер не может распознать контроллер, скорее всего, проблема в самом контроллере.
Если вы можете, обязательно попробуйте контроллер на ПК с Windows 8 или 7. Если контроллер работает в этих системах, это означает, что производитель не выпустил совместимый драйвер для Windows 10.
Невозможность использовать ваш геймпад в Windows 10 может быть проблемой, но мы надеемся, что вы решили эту проблему с помощью одного из наших решений.
Примечание редактора . Этот пост был первоначально опубликован в ноябре 2016 года и с тех пор был полностью переработан и обновлен для обеспечения свежести, точности и полноты.
Читайте также: