Загрузка данных
#include <Keyboard.h>
// Пины джойстика
const int JOY_X_PIN = A0;
const int JOY_Y_PIN = A1;
// Пороги срабатывания джойстика
const int THRESHOLD = 400;
// Переменные для отслеживания состояния
bool wPressed = false;
bool aPressed = false;
bool sPressed = false;
bool dPressed = false;
// Пины кнопок (5-13)
const int buttonPins[] = {5, 6, 7, 8, 9, 10, 11, 12, 13};
const char keys[] = {'Q', 'E', 'R', 'F', 'Z', 'X', 'C', 'V', 'B'};
const int numButtons = 9;
bool buttonStates[numButtons];
unsigned long lastActivityTime = 0;
const unsigned long RESET_TIMEOUT = 5000;
unsigned long lastResetCheck = 0;
// ДЛЯ БОРЬБЫ С SHIFT
unsigned long lastShiftReset = 0;
const unsigned long SHIFT_RESET_INTERVAL = 1000; // Каждую секунду проверяем Shift
void setup() {
Serial.begin(9600);
Keyboard.begin();
for (int i = 0; i < numButtons; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
buttonStates[i] = false;
}
// МНОГОКРАТНЫЙ СБРОС при старте
forceResetAllModifiers();
delay(100);
forceResetAllModifiers();
delay(100);
forceResetAllModifiers();
Serial.println("Джойстик-клавиатура запущена (Shift fixed)");
}
void loop() {
checkAndResetIfNeeded();
forceResetShiftIfNeeded(); // КРИТИЧЕСКИ ВАЖНО для Shift
int xValue = analogRead(JOY_X_PIN);
int yValue = analogRead(JOY_Y_PIN);
processJoystick(xValue, yValue);
processButtons();
delay(5);
}
// СПЕЦИАЛЬНАЯ ФУНКЦИЯ для сброса модификаторов
void forceResetAllModifiers() {
// Принудительный сброс всех модификаторов
Keyboard.release(KEY_LEFT_SHIFT);
Keyboard.release(KEY_RIGHT_SHIFT);
Keyboard.release(KEY_LEFT_CTRL);
Keyboard.release(KEY_RIGHT_CTRL);
Keyboard.release(KEY_LEFT_ALT);
Keyboard.release(KEY_RIGHT_ALT);
Keyboard.release(KEY_LEFT_GUI);
Keyboard.release(KEY_RIGHT_GUI);
// Дополнительно: посылаем "пустой" отчет
Keyboard.write(0);
Serial.println("Сброс модификаторов (Shift/Ctrl/Alt)");
}
// Периодический сброс Shift
void forceResetShiftIfNeeded() {
unsigned long now = millis();
if (now - lastShiftReset > SHIFT_RESET_INTERVAL) {
// Проверяем, не залип ли Shift виртуально
Keyboard.release(KEY_LEFT_SHIFT);
Keyboard.release(KEY_RIGHT_SHIFT);
lastShiftReset = now;
}
}
void processJoystick(int x, int y) {
bool hasActivity = false;
// ВЕРТИКАЛЬ (W/S)
if (y < 512 - THRESHOLD) { // Вверх
if (!wPressed) {
// Перед нажатием - убеждаемся что Shift не зажат
Keyboard.release(KEY_LEFT_SHIFT);
Keyboard.release(KEY_RIGHT_SHIFT);
delay(1);
Keyboard.press('W');
wPressed = true;
hasActivity = true;
Serial.println("W");
}
} else if (y > 512 + THRESHOLD) { // Вниз
if (!sPressed) {
Keyboard.release(KEY_LEFT_SHIFT);
Keyboard.release(KEY_RIGHT_SHIFT);
delay(1);
Keyboard.press('S');
sPressed = true;
hasActivity = true;
Serial.println("S");
}
} else {
if (wPressed) {
Keyboard.release('W');
wPressed = false;
hasActivity = true;
}
if (sPressed) {
Keyboard.release('S');
sPressed = false;
hasActivity = true;
}
}
// ГОРИЗОНТАЛЬ (A/D)
if (x < 512 - THRESHOLD) { // Влево
if (!aPressed) {
Keyboard.release(KEY_LEFT_SHIFT);
Keyboard.release(KEY_RIGHT_SHIFT);
delay(1);
Keyboard.press('A');
aPressed = true;
hasActivity = true;
Serial.println("A");
}
} else if (x > 512 + THRESHOLD) { // Вправо
if (!dPressed) {
Keyboard.release(KEY_LEFT_SHIFT);
Keyboard.release(KEY_RIGHT_SHIFT);
delay(1);
Keyboard.press('D');
dPressed = true;
hasActivity = true;
Serial.println("D");
}
} else {
if (aPressed) {
Keyboard.release('A');
aPressed = false;
hasActivity = true;
}
if (dPressed) {
Keyboard.release('D');
dPressed = false;
hasActivity = true;
}
}
if (hasActivity) {
lastActivityTime = millis();
}
}
void processButtons() {
bool hasActivity = false;
for (int i = 0; i < numButtons; i++) {
bool currentState = (digitalRead(buttonPins[i]) == LOW);
if (currentState != buttonStates[i]) {
if (currentState) {
// Перед нажатием - сбрасываем Shift
Keyboard.release(KEY_LEFT_SHIFT);
Keyboard.release(KEY_RIGHT_SHIFT);
delay(1);
Keyboard.press(keys[i]);
Serial.print("Нажата: ");
Serial.println(keys[i]);
} else {
Keyboard.release(keys[i]);
Serial.print("Отпущена: ");
Serial.println(keys[i]);
}
buttonStates[i] = currentState;
hasActivity = true;
}
}
if (hasActivity) {
lastActivityTime = millis();
}
}
void resetAllKeys() {
// Сначала сбрасываем модификаторы
forceResetAllModifiers();
delay(10);
// Потом обычные клавиши
const char* regularKeys[] = {"W", "A", "S", "D", "Q", "E", "R", "F", "Z", "X", "C", "V", "B"};
for (int i = 0; i < 13; i++) {
Keyboard.release(regularKeys[i][0]);
}
// Сброс состояний
wPressed = false;
aPressed = false;
sPressed = false;
dPressed = false;
for (int i = 0; i < numButtons; i++) {
buttonStates[i] = false;
}
// Финальный сброс модификаторов
delay(10);
forceResetAllModifiers();
Serial.println("!!! ПОЛНЫЙ СБРОС ВСЕХ КЛАВИШ (включая Shift) !!!");
}
void checkAndResetIfNeeded() {
unsigned long now = millis();
if (now - lastResetCheck < 100) return;
lastResetCheck = now;
if (now - lastActivityTime > RESET_TIMEOUT) {
if (wPressed || aPressed || sPressed || dPressed) {
resetAllKeys();
lastActivityTime = now;
}
bool anyPressed = false;
for (int i = 0; i < numButtons; i++) {
if (buttonStates[i]) {
anyPressed = true;
break;
}
}
if (anyPressed) {
resetAllKeys();
lastActivityTime = now;
}
}
}