// 
// modified from https://wokwi.com/projects/396715020656032769

#include <LiquidCrystal.h>
#include <AccelStepper.h>

// Define the pins for the LCD
const int rs = 8, en = 9, d4 = 4, d5 = 5, d6 = 6, d7 = 7, backlightPin = 10;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// Define the pin for the analog input
const int buttonPin = A0;

// Define the pins for the stepper motor driver
const int stepPin = 11;
const int dirPin = 12;

// Create a new instance of the AccelStepper class
AccelStepper stepper(1, stepPin, dirPin);

long currentValue = 0; // Stores the current value entered by the user
int currentDirection = 1; // Stores the current direction of the stepper motor (1: forward, -1: backward)
int defaultSpeed = 1000; // Default speed of the stepper motor

unsigned long lastActivityTime = 0; // Stores the time of the last activity in the secret menu
const unsigned long timeoutDuration = 10000; // Timeout duration (in milliseconds) for the secret menu

void setup() {
  // Set up the LCD
  lcd.begin(16, 2);

  // Set up the backlight pin for PWM
  pinMode(backlightPin, OUTPUT);
  analogWrite(backlightPin, 128); // Set backlight intensity to 50%

  // Set up the stepper motor
  stepper.setMaxSpeed(defaultSpeed); // Set the maximum speed of the stepper motor
  stepper.setAcceleration(200);

  // Print the initial value, direction, and default speed on the LCD
  printValueAndDirection();

  // Initialize Serial communication
  Serial.begin(115200);
}

void loop() {
  // Read analog input to determine the button state
  static int last = -1;
  int buttonState = analogRead(buttonPin);
  if (buttonState != last) {
    last = buttonState;
    // Print raw ADC reading to the serial console
    Serial.println(buttonState);

    switch (buttonState) {
      case 0 ... 49: // Right button
        handleRightButton();
        break;
      case 300 ... 400: // Up button
        handleUpButton();
        break;
      case 100 ... 150: // Down button
        handleDownButton();
        break;
      case 500 ... 620: // Left button
        handleLeftButton();
        break;
      case 720 ... 830: // Select button
        handleSelectButton();
        break;
      default: // No button press
        break;
    }

  }
  // Run the stepper motor
  stepper.run();
}

// Function to handle the right button press
void handleRightButton() {
  // Handle the right button press
  currentDirection = 1;
  printValueAndDirection();
}

// Function to handle the up button press
void handleUpButton() {
  // Handle the up button press
  incrementCurrentValue();
}

// Function to handle the down button press
void handleDownButton() {
  // Handle the down button press
  decrementCurrentValue();
}

// Function to handle the left button press
void handleLeftButton() {
  // Handle the left button press
  currentDirection = -1;
  printValueAndDirection();
}

// Function to handle the select button press
void handleSelectButton() {
  lcd.setCursor(13, 0);
  lcd.print("RUN");
  moveStepper(currentValue * currentDirection); // Move the stepper motor
  lcd.setCursor(13, 0);
  lcd.print("   ");
}

// Function to increment the value
void incrementCurrentValue() {
  currentValue++;
  if (currentValue > 9999) {
    currentValue = 0; // Wrap around if the value exceeds 9999
  }
  printValueAndDirection();
}

// Function to decrement the value
void decrementCurrentValue() {
  currentValue--;
  if (currentValue < 0) {
    currentValue = 9999; // Wrap around if the value goes below 0
  }
  printValueAndDirection();
}

// Function to print the value and direction on the LCD
void printValueAndDirection() {
  lcd.clear();
//  lcd.setCursor(0, 0);
  lcd.print(" Pocet kroku  ");
  lcd.setCursor(0, 1);
  if (currentDirection == 1) {
    lcd.print("   ");
    lcd.print(currentValue);
    lcd.print(" >>");
  } else {
    lcd.print("<< ");
    lcd.print(currentValue);
    lcd.print("   ");
  }
}

// Function to move the stepper motor
void moveStepper(long steps) {
  // Set the direction based on the sign of steps
  if (steps >= 0) {
    stepper.setSpeed(defaultSpeed); // Set the speed of the stepper motor
    stepper.move(steps); // Move the motor forward by 'steps' steps
  } else {
    stepper.setSpeed(-defaultSpeed); // Set the speed of the stepper motor (negative for reverse direction)
    stepper.move(steps); // Move the motor backward by 'steps' steps
  }
}
Buttons to AnalogBreakout
A4988