#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <AccelStepper.h>

// Підключення I2C LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Піни для енкодера
#define ENCODER_CLK 11
#define ENCODER_DT 12
#define ENCODER_SW 13

// Піни для крокових двигунів
#define STEP_PIN_X 8
#define DIR_PIN_X 7
#define STEP_PIN_Y 5
#define DIR_PIN_Y 6
#define ENABLE_PIN_X 9
#define ENABLE_PIN_Y 3

AccelStepper stepperX(AccelStepper::DRIVER, STEP_PIN_X, DIR_PIN_X);
AccelStepper stepperY(AccelStepper::DRIVER, STEP_PIN_Y, DIR_PIN_Y);

// Змінні для роботи меню
int menuIndex = 0;
int lastStateCLK;
int currentStateCLK;
int buttonState;
unsigned long lastButtonPress = 0;

// Структура меню
const char* menu[] = {"Move", "Settings", "Disable steppers"};
const char* moveMenu[] = {"Start", "Stop", "Back"};
const char* settingsMenu[] = {"Stepper X", "Stepper Y", "Back"};
const char* stepperMenu[] = {"Direction", "Speed", "Steps", "Back"};
const char* disableMenu[] = {"Disable X", "Disable Y", "Back"};

int currentMenuLevel = 0; // 0 - головне меню, 1 - підменю, і т.д.
const char** currentMenu = menu;
int menuSize = 3;

void setup() {
  lcd.init();
  lcd.backlight();
  pinMode(ENCODER_CLK, INPUT);
  pinMode(ENCODER_DT, INPUT);
  pinMode(ENCODER_SW, INPUT_PULLUP);

  pinMode(ENABLE_PIN_X, OUTPUT);
  pinMode(ENABLE_PIN_Y, OUTPUT);
  digitalWrite(ENABLE_PIN_X, LOW); // Увімкнути драйвер X
  digitalWrite(ENABLE_PIN_Y, LOW); // Увімкнути драйвер Y

  stepperX.setMaxSpeed(1000);
  stepperX.setAcceleration(500);

  stepperY.setMaxSpeed(1000);
  stepperY.setAcceleration(500);

  lastStateCLK = digitalRead(ENCODER_CLK);

  lcd.setCursor(0, 0);
  lcd.print("Welcome!");
  delay(2000);
  lcd.clear();
  displayMenu();
}

void loop() {
  // Читання стану енкодера
  currentStateCLK = digitalRead(ENCODER_CLK);

  // Якщо стан змінився
  if (currentStateCLK != lastStateCLK && currentStateCLK == LOW) {
    if (digitalRead(ENCODER_DT) != currentStateCLK) {
      menuIndex++;
    } else {
      menuIndex--;
    }

    // Обмеження індексу меню
    menuIndex = constrain(menuIndex, 0, menuSize - 1);
    displayMenu();
  }

  lastStateCLK = currentStateCLK;

  // Читання кнопки енкодера
  buttonState = digitalRead(ENCODER_SW);

  if (buttonState == LOW) {
    if (millis() - lastButtonPress > 300) {
      lastButtonPress = millis();

      // Обробка вибору меню
      handleMenuSelection();
    }
  }

  stepperX.run();
  stepperY.run();
}

void displayMenu() {
  lcd.clear();
  lcd.print(currentMenu[menuIndex]);
}

void handleMenuSelection() {
  if (currentMenuLevel == 0) {
    // Головне меню
    if (menuIndex == 0) {
      currentMenu = moveMenu;
      menuSize = 3;
      currentMenuLevel++;
    } else if (menuIndex == 1) {
      currentMenu = settingsMenu;
      menuSize = 3;
      currentMenuLevel++;
    } else if (menuIndex == 2) {
      currentMenu = disableMenu;
      menuSize = 3;
      currentMenuLevel++;
    }
  } else {
    // Підменю
    if (strcmp(currentMenu[menuIndex], "Back") == 0) {
      if (currentMenu == moveMenu || currentMenu == settingsMenu || currentMenu == disableMenu) {
        currentMenu = menu;
        menuSize = 3;
        currentMenuLevel--;
      } else if (currentMenu == stepperMenu) {
        currentMenu = settingsMenu;
        menuSize = 3;
        currentMenuLevel--;
      }
    } else {
      // Виконання дій в підменю
      if (currentMenu == moveMenu) {
        executeMoveAction(menuIndex);
      } else if (currentMenu == settingsMenu) {
        currentMenu = stepperMenu;
        menuSize = 4;
        currentMenuLevel++;
      } else if (currentMenu == disableMenu) {
        executeDisableAction(menuIndex);
      }
    }
  }
  displayMenu();
}

void executeMoveAction(int action) {
  lcd.clear();
  if (action == 0) {
    lcd.print("Start Moving");
    stepperX.move(1000);
    stepperY.move(1000);
  } else if (action == 1) {
    lcd.print("Stopped");
    stepperX.stop();
    stepperY.stop();
  }
  delay(2000);
  lcd.clear();
}

void executeDisableAction(int action) {
  lcd.clear();
  if (action == 0) {
    lcd.print("X Disabled");
    digitalWrite(ENABLE_PIN_X, HIGH); // Вимкнути драйвер X
  } else if (action == 1) {
    lcd.print("Y Disabled");
    digitalWrite(ENABLE_PIN_Y, HIGH); // Вимкнути драйвер Y
  }
  delay(2000);
  lcd.clear();
}
A4988
A4988