Last active
March 30, 2021 06:29
-
-
Save S60Team/8dbf742d80aa9aa5834351c107bc78fc to your computer and use it in GitHub Desktop.
Простой руль для ПК: Руль энкодер, Газ, Тормоз, Сцепление, Установка угла поворота руля, матрица кнопок 4 на 4 - библиотека NicoHood (HID)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Простой руль для ПК: | |
Основан на: https://is.gd/gyverwheel и https://is.gd/udubon | |
Изменён: Гендель Владимир aka S60Team | |
Скачай и поставь библиотеки: | |
https://github.com/PaulStoffregen/Encoder | |
https://github.com/NicoHood/HID | |
https://github.com/Chris--A/Keypad | |
*/ | |
// Подключаем геймпад (джойстик): | |
// Библиотека поддерживает 32 кнопки, 1 крестовину, 6 осей (X,Y,Z,Rz,Rx,Ry) | |
#include "HID-Project.h" | |
// | |
// Указываем Оси: | |
#define Axe_Throttle A0 // Газ | |
#define Axe_Brake A1 // Тормоз | |
#define Axe_Clutch A2 // Сцепление | |
#define Axe_HBrake A3 // Ручной тормоз | |
#define BTN_CAL 2 // Кнопка калибровки | |
// | |
// Подключаем энкодер (360): | |
#include <Encoder.h> | |
long encVal; // Значения энкодера | |
Encoder myEnc(0, 1); // Пины энкодера | |
// | |
// Матрица кнопок (4x4): https://is.gd/k4pgga | |
#include <Keypad.h> | |
#define ROWS 4 | |
#define COLS 4 | |
byte buttons[ROWS][COLS] = { | |
{15,14,13,12}, | |
{11,10,9,8}, | |
{7,6,5,4}, | |
{3,2,1,0} | |
}; | |
byte rowPins[ROWS] = {10,9,8,7}; // Строки 4,3,2,1 | |
byte colPins[COLS] = {6,5,4,3}; // Столбцы 4,3,2,1 | |
Keypad buttbx = Keypad(makeKeymap(buttons), rowPins, colPins, ROWS, COLS); | |
// | |
// Переменные значений осей: | |
int16_t Axis1_ = 0, Axis2_ = 0, Axis3_ = 0, Axis4_ = 0; | |
// Переменные ВКЛ определения осей: | |
bool handbrake_present = true, throttle_present = true; | |
bool brake_present = true, clutch_present = true; | |
// Переменная режима угла поворота руля: | |
bool racing_mode = false; | |
// | |
void setup() { | |
pinMode(13, OUTPUT); // Встроенный светодиод | |
digitalWrite(13, LOW); // Встроенный светодиод ВЫКЛ | |
pinMode(BTN_CAL, INPUT_PULLUP); // Кнопка сброса позиции энкодера | |
if(digitalRead(BTN_CAL) == HIGH){ | |
digitalWrite(13, LOW); | |
racing_mode = false;} // Кнопка сброса ВЫКЛ. Режим симулятора | |
else{ | |
digitalWrite(13, HIGH); | |
racing_mode = true;} // Кнопка сброса ВКЛ. Гоночный режим | |
// | |
// Циклы для указания цифровых пинов как вход для обработки нажатия кнопок: | |
pinMode(11, INPUT_PULLUP); // 11,12 | |
pinMode(12, INPUT_PULLUP); | |
for (int thisPin = 14; thisPin < 17; thisPin++) { | |
pinMode(thisPin, INPUT_PULLUP); // 14, 15, 16 | |
} | |
// Инициализация джойстика: | |
Gamepad.begin(); | |
// Определяем, подключены ли педали и ручник к аналоговым входам: | |
int16_t ap1 = analogRead(Axe_Throttle), | |
ap2 = analogRead(Axe_Brake), | |
ap3 = analogRead(Axe_Clutch), | |
ap4 = analogRead(Axe_HBrake); | |
delay(10); | |
if(abs(ap1-analogRead(Axe_Throttle)) > 10){ throttle_present = false; } | |
if(abs(ap2-analogRead(Axe_Brake)) > 10){ brake_present = false; } | |
if(abs(ap3-analogRead(Axe_Clutch)) > 10){ clutch_present = false; } | |
if(abs(ap4-analogRead(Axe_HBrake)) > 10){ handbrake_present = false; } | |
} | |
// | |
void loop() { | |
// Сбрасываем значение осей: (на всякий случай) | |
Axis1_ = 0, Axis2_ = 0, Axis3_ = 0, Axis4_ = 0; | |
// Руль энкодером (360ppr): | |
int16_t rotMax = 0; // обнуляем макс. значение поворота | |
int16_t rotMid = (rotMax>>1); // середина руля | |
if(racing_mode == false){ // Если не зажата кнопка сброса (пин 2): | |
// rotMax это Значение поворота, вычисляется по (ppr*4*угол поворота)/360 | |
// 4320=1080°, 3600=900°, 1440=360°, 1080=270°, 720=180° | |
rotMax = 3600; | |
rotMid = (rotMax>>1);} | |
// Если зажата кн. калибровки и кн. на пин 9: 600° | |
else if(racing_mode == true && digitalRead(9) == LOW){ | |
rotMax = 2400; | |
rotMid = (rotMax>>1);} | |
// Если зажата кн. калибровки и кн. на пин 10: 270° | |
else if(racing_mode == true && digitalRead(10) == LOW){ | |
rotMax = 1080; | |
rotMid = (rotMax>>1);} | |
// Если зажата кн. калибровки: 180° | |
else{ | |
rotMax = 720; | |
rotMid = (rotMax>>1);} | |
// Сброс позиции энкодера кнопкой на пине 2: | |
if(!digitalRead(BTN_CAL)){ myEnc.write(rotMid); } | |
encVal = myEnc.read() - rotMid; // Читаем показания энкодера | |
encVal = (encVal * 65535) / rotMax; // Вычисляем поворот | |
encVal = constrain(encVal, -32768, 32767); // Указываем границы значений | |
Gamepad.xAxis(encVal); // Записываем значения в ось. | |
// | |
// Педаль Газа: | |
if (throttle_present == true) { | |
Axis1_ = analogRead(Axe_Throttle); | |
Axis1_ = map(Axis1_,0,1023,-32768,32767); | |
Gamepad.rxAxis(Axis1_);} | |
else{Gamepad.rxAxis(0);} | |
// | |
// Педаль Тормоза: | |
if (brake_present == true) { | |
Axis2_ = analogRead(Axe_Brake); | |
Axis2_ = map(Axis2_,0,1023,-128,127); | |
Gamepad.zAxis(Axis2_);} | |
else{Gamepad.zAxis(0);} | |
// | |
// Педаль Сцепления: | |
if (clutch_present == true) { | |
Axis3_ = analogRead(Axe_Clutch); | |
Axis3_ = map(Axis3_,0,1023,-128,127); | |
Gamepad.rzAxis(Axis3_);} | |
else{Gamepad.rzAxis(0);} | |
// | |
// Ручной тормоз: | |
if (handbrake_present == true) { | |
Axis4_ = analogRead(Axe_HBrake); | |
Axis4_ = map(Axis4_,0,1023,-32768,32767); | |
Gamepad.ryAxis(Axis4_);} | |
else{Gamepad.ryAxis(0);} | |
// | |
// Матрица кнопок 4на4: https://is.gd/k4pgga | |
if (buttbx.getKeys()){ | |
for (int i = 0; i < LIST_MAX; i++) { | |
if ( buttbx.key[i].stateChanged ) { | |
switch (buttbx.key[i].kstate) { | |
// IDLE, PRESSED, HOLD, или RELEASED | |
case PRESSED: | |
Gamepad.press(buttbx.key[i].kchar); | |
break; | |
case RELEASED: | |
Gamepad.release(buttbx.key[i].kchar); | |
break; } } } | |
} | |
// Leonardo: Пины: 11,12 | |
if(!digitalRead(11)){ Gamepad.press(17); } | |
else{ Gamepad.release(17); } | |
if(!digitalRead(12)){ Gamepad.press(18); } | |
else{ Gamepad.release(18); } | |
// | |
// Пины: 14, 15, 16 (ещё кнопки!) | |
if(!digitalRead(14)){ Gamepad.press(19); } | |
else{ Gamepad.release(19); } | |
if(!digitalRead(15)){ Gamepad.press(20); } | |
else{ Gamepad.release(20); } | |
if(!digitalRead(16)){ Gamepad.press(21); } | |
else{ Gamepad.release(21); } | |
// | |
// Отправляем значения в ПК: | |
Gamepad.write(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment