Загрузка данных


#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;
    }
  }
}