Last active
March 30, 2021 06:30
-
-
Save S60Team/ae28179d7c751d0f55094d24256ef632 to your computer and use it in GitHub Desktop.
Простой руль для ПК: Руль энкодер, Газ, Тормоз, Сцепление, КПП, Установка угла поворота руля - библиотека 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 | |
КПП (5 пинов - 8 передач) основана на проекте: https://soo.gd/XRgt | |
3: X влево; 4: X вправо | |
5: X экстремально вправо | |
6: X вверх; 7: Y вниз. | |
Пины: 8,9,10,11,12, 14,15,16 - кнопки */ | |
// Подключаем геймпад (джойстик): | |
// Библиотека поддерживает 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 // Кнопка калибровки | |
// Подключаем энкодер: | |
//#define ENCODER_OPTIMIZE_INTERRUPTS | |
//#define ENCODER_USE_INTERRUPTS | |
#include <Encoder.h> | |
long encVal = 0; // Значения энкодера | |
Encoder myEnc(0, 1); // Пины энкодера | |
// Переменные значений осей: | |
int16_t Axis1_ = 0, Axis2_ = 0, Axis3_ = 0, Axis4_ = 0; | |
// Переменные ВКЛ определения осей: | |
bool handbrake_present = true, throttle_present = true; | |
bool brake_present = true, clutch_present = true; | |
// Перменные КПП: | |
int8_t Gear1Flg = 0, Gear2Flg = 0, Gear5Flg = 0, Gear6Flg = 0, Gear7Flg = 0, Gear8Flg = 0; | |
// Переменная режима угла поворота руля: | |
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;} // Кнопка сброса ВКЛ. Гоночный режим | |
// Циклы для указания цифровых пинов как вход для обработки нажатия кнопок: | |
for (int thisPin = 3; thisPin < 13; thisPin++) { // Leonardo: | |
pinMode(thisPin, INPUT_PULLUP); } // 3,4,5,6,7,8,9,10,11,12 | |
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; | |
// Руль энкодер: | |
int16_t rotMax = 0; // обнуляем макс. значение поворота | |
int16_t rotMid = (rotMax>>1); // середина руля | |
if(racing_mode == false){ // Если не зажата кнопка сброса (пин 2): | |
// rotMax это Значение поворота, например: | |
// 4320=1080°, 3600=900°, 1440=360°, 1080=270°, 720=180° | |
rotMax = 3600; | |
rotMid = (rotMax>>1);} | |
// Если зажата кн. калибровки и кн. на пин 10: 600° | |
else if(racing_mode == true && digitalRead(10) == LOW){ | |
rotMax = 2400; | |
rotMid = (rotMax>>1);} | |
// Если зажата кн. калибровки и кн. на пин 11: 270° | |
else if(racing_mode == true && digitalRead(11) == 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);} | |
// | |
// Коробка передач: | |
if(!digitalRead(3) && !digitalRead(6)){ | |
Gamepad.release(4); | |
Gamepad.press(1); | |
Gear1Flg = 1;} | |
else{ | |
Gamepad.release(1); | |
Gear1Flg = 0;} | |
if(!digitalRead(3) && !digitalRead(7)){ | |
Gamepad.release(3); | |
Gamepad.press(2); | |
Gear2Flg = 1;} | |
else{ | |
Gamepad.release(2); | |
Gear2Flg = 0;} | |
if(!digitalRead(4) && !digitalRead(6)){ | |
Gamepad.release(4); | |
Gamepad.press(5); | |
Gear5Flg = 1;} | |
else{ | |
Gamepad.release(5); | |
Gear5Flg = 0;} | |
if(!digitalRead(4) && !digitalRead(7)){ | |
Gamepad.release(3); | |
Gamepad.press(6); | |
Gear6Flg = 1;} | |
else{ | |
Gamepad.release(6); | |
Gear6Flg = 0;} | |
// Far right | |
if(!digitalRead(4) && !digitalRead(5) && !digitalRead(6)){ | |
Gamepad.release(4); | |
Gamepad.release(5); | |
Gamepad.press(7); | |
Gear7Flg = 1;} | |
else{ | |
Gamepad.release(7); | |
Gear7Flg = 0;} | |
if(!digitalRead(4) && !digitalRead(5) && !digitalRead(7)){ | |
Gamepad.release(3); | |
Gamepad.release(6); | |
Gamepad.press(8); | |
Gear8Flg = 1;} | |
else{ | |
Gamepad.release(8); | |
Gear8Flg = 0;} | |
if(!digitalRead(6) && Gear1Flg == 0 && Gear5Flg == 0 && Gear7Flg == 0){ Gamepad.press(3); } | |
else{ Gamepad.release(3); } | |
if(!digitalRead(7) && Gear2Flg == 0 && Gear6Flg == 0 && Gear8Flg == 0){ Gamepad.press(4); } | |
else{ Gamepad.release(4); } | |
// | |
for (int8_t thisPind = 8; thisPind < 13; thisPind++) { | |
if(!digitalRead(thisPind)){ Gamepad.press(thisPind+1); } | |
else{ Gamepad.release(thisPind+1); } } | |
// Пины: 14, 15, 16 (ещё 3 кнопки!) | |
for (int8_t thisPindd = 14; thisPindd < 17; thisPindd++) { | |
if(!digitalRead(thisPindd)){ Gamepad.press(thisPindd); } | |
else{ Gamepad.release(thisPindd); } } | |
// Отправляем значения в ПК: | |
Gamepad.write(); | |
// | |
delay(10); // а надо ли? | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment