Своё рулевое управление (джойстик) для игр на Arduino
Компоненты и материалы
| Потенциометр 10 кОм | ×1 |
| Arduino UNO | ×1 |
| Макетная плата | ×1 |
Инструменты
- Лазерный резак
- Arduino Materia 101
- 3D-принтер
Программное обеспечение
- Arduino IDE
О проекте
Arduino Joystick + Flying Creation

В этой статье мы создадим руль, эмулирующий USB-джойстик. Можно использовать в Steam. Идея пришла, так как готовые симуляторы дорогие. Проект занял пару дней. Приветствуются предложения по улучшению!
Превращаем Arduino в контроллер
Прошиваем коммуникационный чип Arduino (ATmega16U2) специальной прошивкой UnoJoy, чтобы ПК видел устройство как USB-геймпад. Процедура безопасна и обратима.
- Скачайте последнюю версию библиотеки UnoJoy.
- Установите драйверы: запустите
InstallUnoJoyDrivers.batиз скачанной папки. - Установите инструмент ATmel FLIP (используется UnoJoy для прошивки).
Загрузка прошивки
- Переведите Arduino в режим DFU: замкните два контакта рядом с USB-разъёмом (см. фото).
- Запустите
TurnIntoAJoystick.batиз UnoJoy. - Отключите и подключите Arduino — теперь это Joystick.
- Для возврата: то же самое, но запустите
TurnIntoAnArduino.bat.
Простой контроллер

Нужен потенциометр 10 кОм на пине A0. Скопируйте UnoJoy.h в папку скетча.
Игра в Steam
Steam видит геймпад как Xbox 360. Для маппинга используйте x360ce (скачайте 32/64 бит в зависимости от игры). Положите x360ce.exe в папку с исполняемым файлом игры, запустите — он обнаружит USB Joystick.
Видео-туториал на моём YouTube-канале (ссылка в описании).
Исходный код (C/C++)
/* Arduino USB Joystick HID demo */
/* Author: Darran Hunt, Public Domain. Update by RICLAMER 25/03/2014 */
/* Для Arduino UNO (6 осей, 13 кнопок), совместимо с Mega. */
#undef DEBUG
#define NUM_BUTTONS 40
#define NUM_AXES 8
typedef struct joyReport_t {
int16_t axis[NUM_AXES];
uint8_t button[(NUM_BUTTONS + 7) / 8];
} joyReport_t;
joyReport_t joyReport;
uint8_t btn[12];
int fulloff = 0;
void setup() {
for (int portId = 2; portId < 13; portId++) {
pinMode(portId, INPUT_PULLUP);
}
Serial.begin(115200);
delay(200);
for (uint8_t ind = 0; ind < 8; ind++) joyReport.axis[ind] = ind * 1000;
for (uint8_t ind = 0; ind < sizeof(joyReport.button); ind++) joyReport.button[ind] = 0;
}
void sendJoyReport(struct joyReport_t *report) {
#ifndef DEBUG
Serial.write((uint8_t *)report, sizeof(joyReport_t));
#else
// Debug output
#endif
}
void setButton(joyReport_t *joy, uint8_t button) {
uint8_t index = button / 8;
uint8_t bit = button - 8 * index;
joy->button[index] |= 1 << bit;
}
void clearButton(joyReport_t *joy, uint8_t button) {
uint8_t index = button / 8;
uint8_t bit = button - 8 * index;
joy->button[index] &= ~(1 << bit);
}
void loop() {
for (int bt = 1; bt < 13; bt++) btn[bt] = digitalRead(bt + 1);
for (int on = 1; on < 13; on++) {
if (btn[on] == LOW) { setButton(&joyReport, on + 16); delay(1); }
if (btn[on] == HIGH) { clearButton(&joyReport, on + 16); }
}
for (uint8_t axis = 0; axis < 2; axis++) { // Только A0 (ось X)
joyReport.axis[axis] = map(analogRead(axis), 350, 700, -32768, 32767);
}
// Неиспользуемые оси обнуляем
joyReport.axis[2] = 0;
joyReport.axis[3] = 0;
joyReport.axis[4] = 0;
joyReport.axis[5] = 0;
joyReport.axis[6] = 0;
joyReport.axis[7] = 0;
sendJoyReport(&joyReport);
delay(35);
fulloff = 0;
}
3D-модели
volante_iDt4RqmPLZ.dwgvolante_idt4rqmplz_hakHRvVNYD.dxf
Схема

Производственный процесс
- Цифровые кости на Arduino: генератор случайных чисел с LCD-дисплеем и кнопкой
- Превращаем старую радиоуправляемую машину в джойстик-контролируемый болид на Arduino
- Строим Iron Man на Arduino: компоненты, сенсоры и пошаговый гайд
- Интерактивная игра с джойстиком и LED-обратной связью на Arduino
- Find Me: Умный поисковик вещей на Arduino и Bluetooth
- Сборка функционального 3D-печатного манипулятора на Arduino: пошаговое руководство
- DIY-контроллер увлажнителя на Arduino с реле: безопасная работа с высоким напряжением
- Бесконтактный термометрический шлюз для быстрого и точного скрининга
- NeoPixel Matrix Pong на Arduino Nano: неоновая игра Pong на матрице 15×10
- FM-радиоприемник на Arduino и модуле TEA5767