#include <Joystick.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_MULTI_AXIS,
12, 0, true, true, true, false, false, false, false, false, false, false, false);
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Encoder pinleri
const int outA = 2;
const int outB = 3;
// Pot pinleri
const int GAS_POT = A1;
const int BRAKE_POT = A0;
//const int MOTOR_BRAKE_POT = A2;
volatile int encoder = 0;
int encoder_save = 0;
const int encoderMin = -896;
const int encoderMax = 896;
// Vites durumu
int gear = 0; // 0 = N
bool isMotorBrakeActive = false;
bool isStartOn = false;
// Keypad ayarları
const byte ROWS = 5;
const byte COLS = 5;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A', 'B'},
{'4', '5', '6', 'C', 'D'},
{'7', '8', '9', 'E', 'F'},
{'*', '0', '#', 'G', 'H'},
{'I', 'J', 'K', 'L', 'M'}
};
byte rowPins[ROWS] = {6, 7, 8, 9, 10};
byte colPins[COLS] = {11, 12, 13, A2, A3};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
void setup() {
Joystick.begin();
Joystick.setXAxisRange(0, 32767);
Joystick.setYAxisRange(0, 1023);
Joystick.setZAxisRange(0, 1023);
Joystick.setXAxis(16383);
pinMode(outA, INPUT_PULLUP);
pinMode(outB, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(outA), outAChange, CHANGE);
attachInterrupt(digitalPinToInterrupt(outB), outBChange, CHANGE);
lcd.init();
lcd.backlight();
}
void loop() {
// Direksiyon
noInterrupts();
int currentEncoder = encoder;
interrupts();
currentEncoder = constrain(currentEncoder, encoderMin, encoderMax);
if (encoder_save != currentEncoder) {
encoder_save = currentEncoder;
int mapped = map(currentEncoder, encoderMin, encoderMax, 0, 32767);
Joystick.setXAxis(mapped);
}
// Pedallar
Joystick.setYAxis(analogRead(GAS_POT));
Joystick.setZAxis(analogRead(BRAKE_POT));
// Fonksiyonlar
updateMotorBrake();
updateShortcuts();
handleKeypad();
updateLCD();
delay(5);
}
void outAChange() {
if (digitalRead(outA) == digitalRead(outB)) encoder++;
else encoder--;
}
void outBChange() {
if (digitalRead(outA) == digitalRead(outB)) encoder--;
else encoder++;
}
// Motor freni gazdan ayak çekilince ve potans değeri düşükse devreye girer
void updateMotorBrake() {
int gasValue = analogRead(GAS_POT);
int motorPot = analogRead(MOTOR_BRAKE_POT);
if (gasValue < 200 && motorPot < 512) {
if (!isMotorBrakeActive) {
Joystick.setButton(4, true);
isMotorBrakeActive = true;
}
} else {
if (isMotorBrakeActive) {
Joystick.setButton(4, false);
isMotorBrakeActive = false;
}
}
}
// Kısa yol tuşları (örn: dörtlü flaşör)
void updateShortcuts() {
// Örn: sinyaller aktifse dörtlü
if (Joystick.getButton(0) && Joystick.getButton(1)) {
Joystick.setButton(10, true);
} else {
Joystick.setButton(10, false);
}
}
// Keypad tuşlarıyla işlem
void handleKeypad() {
char key = keypad.getKey();
if (!key) return;
switch (key) {
case 'E': // Start/Stop
isStartOn = !isStartOn;
Joystick.setButton(6, isStartOn);
break;
case 'F': // Korna
Joystick.setButton(3, true);
delay(200);
Joystick.setButton(3, false);
break;
case '1'...'6': gear = key - '0'; break;
case '0': gear = 0; break;
}
}
// LCD'de menü ve vites durumu gösterimi
void updateLCD() {
lcd.setCursor(0, 0);
lcd.print("Vites: ");
if (gear == 0) lcd.print("N ");
else lcd.print(gear);
lcd.setCursor(0, 1);
lcd.print("Start: ");
lcd.print(isStartOn ? "Acik " : "Kapali");
lcd.setCursor(0, 2);
lcd.print("Motor Fren: ");
lcd.print(isMotorBrakeActive ? "ON " : "OFF");
}
D2
D3
D4
D5
D6