//#include <LiquidCrystal.h>  // use this library for the standard (non I2C) LCD
#include <LiquidCrystal_I2C.h>  // RH - use this library for LCD displays with I2C backpack
#include <Wire.h>  // RH - needed for the LCD I2C library.  SCL connects to pin A5.  SDA connects to pin A4.  Jumper the LED backlight pin on the I2C board
#include <Stepper.h>
#include <Servo.h>
#include <AccelStepper.h>
#include <AccelStepperWithDistance.h>
//LiquidCrystal lcd(1, 2, 4, 5, 6, 7);  // Use these pins for the 1602 lcd
LiquidCrystal_I2C lcd(0x27, 20, 4);  // RH - use this for I2C LCD.  Assumes default address of 0x27
int MenuNr = 0;   // Menu number
int PhotoNr = 1;  // The amount of photos that have to be taken
int pocitadlo = 0;
int Opak = 1;
int StrihCislo = 0;
bool Zavora = 0;
bool ZavoraReset = 0;
float PosuvNom = 0;
float PosuvSTP = 0;
float RucPos = 0;
float RucSTP = 0;
float newPos = 0;
float celkemL = 0;
float Korekce = 0;
bool Flag1 = 0;   // This flag is only active during 1 program cycle (prevents constantly adding/subtracting 1 to the menu number when the joystick is pushed to the side)
bool Flag2 = 0;   // This flag is only active during 1 program cycle (prevents constantly adding/subtracting 2 to the photo number when the joystick is pushed up or down)
bool Flag3 = 0;   // This flag is only active during 1 program cycle (prevents constantly adding/subtracting 1 to the RPM when the joystick is pushed up or down)
bool Flag4 = 0;   // This flag is only active during 1 program cycle (prevents constantly adding/subtracting 1 to the turn number when the joystick is pushed to the side)
bool Flag5 = 0;   // This flag is only active during 1 program cycle (prevents constantly adding/subtracting 1 to the RPM when the joystick is pushed up or down)
bool Flag6 = 0;   // This flag is only active during 1 program cycle to clear the lcd
int SwMenu = 0;   // Switch menu (Sub menu's in the main menu's)
bool StMenu = 0;   // Switch menu (Start menu's in the main menu's)
bool BtnFlag = 0;
bool StFlag = 0;
bool ZavFlag = 0;
bool FlagOp = 0;
//bool UP = 0;
//bool DOWN = 0;
//bool LEFT = 0;
//bool RIGHT = 0;
bool uchop = 0; // This flag is only active during 1 program cycle (prevents constantly adding of 1 to SwMenu when button is pressed)
String uchopCheck = "";
// RH - added variables for fast change & cancel modes
int FastChng = 0;  // indicates fast change value mode.  0 = off, 1 = delay mode, 2 = fast changing mode
const unsigned long FastDelay = 1000;  // delay mode time (before values change fast)
const unsigned long ShortInt = 100;  // short fast change interval
const unsigned long LongInt = 300;  // long fast change interval
const unsigned long BtnDelay = 2000;  // delay for button press to cancel operations.  Note this is an approximate delay, since stepper motor
// suspends all program execution until motor finishes its move
unsigned long SetTime = 0; // time value for fast change & button cancel modes.  Used to calculate time intervals
bool BtnCancelFlag = 0;
bool StCancelFlag = 0; // This flag is used to detect when button is pressed for canceling operations
bool MaxSwMenu = 0; // This flag is used for detecting when the maximum SwMenu is reached
bool StReady = 0;  // This flag is used for ready confirmation
bool CinCancelFlag = 0;  // This flag is used to trigger cinematic cancel.  1 = cancel cinematic operation
int StepPoll = 480;  // number of motor steps to poll for cinematic cancel (at 15 rpm)
int Cntr = 0;  // step counter for cinematic motor cancel
// RH - end of added variables

const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
const float step_per_mm = 25.0;
//int FullRev = 14336;                  // 1 full revolution of the big gear -> Small-Big gear ratio is 7:1
int rolePerMinute = 100;               // Adjustable range of 28BYJ-48 stepper is 0~17 rpm
int PhotoTaken = 0;                   // Amount of photo's that have been taken
int StepPerPhoto;                     // Amount of steps per photo (calculated -> see MenuNr 0/SwMenu 2)
int TurnNr = 1;                       // Amount of turns
int CurrentTurn = 0;                  // Stores current turn number
int Steps = 0;                        // Amount of individual steps the stepper motor has to turn
const int SW_pin = 8;
const int UPpin = 5; 
const int LEFTpin = 6;
const int RIGHTpin = 4;
const int DOWNpin = 3;// digital pin connected to switch output
const int X_pin = A0; // analog pin connected to X output
const int Y_pin = A1; // analog pin connected to Y output
const int St_pin = 10;
const int Zav_pin = 7;
// Define stepper motor connections and steps per revolution:
#define dirPin 12
#define stepPin 13
#define motorInterfaceType 1
//#define stepsPerRevolution 200

//Stepper myStepper(stepsPerRevolution, 12, 13);  // Use these pins for the stepper motor
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
void setup() {
  //lcd.begin(16, 2);                   //Lcd setup for standard (non I2C) LCD connection
  lcd.init();                         // RH - I2C LCD init command
  lcd.backlight();                    // RH - I2C LCD turn backlight on
  pinMode(SW_pin, INPUT);             //Set pushbutton as input
  digitalWrite(SW_pin, HIGH);
  pinMode(St_pin, INPUT_PULLUP);             //Set pushbutton as input
  pinMode(UPpin, INPUT_PULLUP);
  pinMode(DOWNpin, INPUT_PULLUP);
  pinMode(LEFTpin, INPUT_PULLUP);
  pinMode(RIGHTpin, INPUT_PULLUP);
  digitalWrite(St_pin, HIGH);        //Set SW_pin High
  pinMode(11, OUTPUT);
  pinMode(9, INPUT_PULLUP);
  pinMode(Zav_pin, INPUT_PULLUP);
  //myStepper.setSpeed(rolePerMinute);  //Set RPM of steppermotor

  // Set the maximum speed and acceleration:
  stepper.setMaxSpeed(800);
  stepper.setAcceleration(800);
  //Servo1.attach(3);                   //Attach servo to pin 3
  //Servo1.write(90);                   //Move servo to mid possition

  lcd.setCursor(0, 0);                //Startup screen start
  lcd.print("Automaticky posuv ");              //      """""      //
  lcd.setCursor(0, 1);                //      """""      //
  lcd.print("V1.0");                  //      """""      //
  //delay(1000);                        //      """""      //
  //lcd.clear();                        //      """""      //
  lcd.setCursor(0, 2);                //      """""      //
  lcd.print("Pracoviste 01");           //      """""      //
  lcd.setCursor(0, 3);                //      """""      //
  lcd.print("PP laser");         //      """""      //
  delay(2000);                        //      """""      //
  lcd.clear();                        //Startup screen end
  // Declare pins as output:
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(St_pin, INPUT);
  

}

void loop() {
  int XValue = analogRead(X_pin);     // Read the analog value from The X-axis from the joystick
  int YValue = analogRead(Y_pin);     // Read the analog value from The Y-axis from the joystick
  int SwValue = digitalRead(SW_pin);  // Read the digital value from The Button from the joystick
  int StValue = digitalRead(St_pin);  // Read the digital value from The Button Starter
  bool UP = digitalRead(UPpin);
  bool DOWN = digitalRead(DOWNpin);
  bool LEFT = digitalRead(LEFTpin);
  bool RIGHT = digitalRead(RIGHTpin);
  int uchop = digitalRead(9);
  int ZavValue = digitalRead(Zav_pin);

  if (ZavValue == 0) {
    Zavora = 1;
    ZavoraReset = 0;
  }
  if (ZavValue == 1) {
    ZavoraReset = 1;
  }

  if (uchop == 0) {
    uchopCheck = "OK ";
    //StMenu = 0;
  }
  if (uchop == 1) {
    uchopCheck = "!!!";
    StMenu = 0;
  }
  if (MenuNr < 0) { //This sets the min number of menu's
    MenuNr = 0;
  }
  else if ( MenuNr > 2) { //This sets the max numbers of menu's
    MenuNr = 2;
  }

  if (RIGHT == 0  && Flag1 == 0 && SwMenu == 0) { //if the joystick is pushed to the right side and flag1 is 0 then 1 will be added to the menu number (purpose of the flag -> see comment Flags above)
    MenuNr = MenuNr + 1;
    Flag1 = 1;
    lcd.clear();
  }

  if (LEFT == 0 && Flag1 == 0 && SwMenu == 0) { //if the joystick is pushed to the left side and flag1 is 0 then 1 will be subtracted from the menu number (purpose of the flag -> see comment Flags above)
    MenuNr = MenuNr - 1;
    Flag1 = 1;
    lcd.clear();
  }

  if (RIGHT == 1 && LEFT == 1 && Flag1 == 1) { //if joystick is at neutral possition, flag1 is set to 0 (purpose of the flag -> see comment Flags above)
    Flag1 = 0;
  }


  if (SwValue == 0 && BtnFlag == 0 && MaxSwMenu == 0) { //if the button is pressed and the flag is 0 -> add 1 to menu
    SwMenu = SwMenu + 1;
    BtnFlag = 1;
    BtnCancelFlag = 0;
    lcd.clear();
  }

  if (SwValue == 1 && BtnFlag == 1) { //if the button is not pressed and the flag is 0 -> Reset the flag (purpose of the flag -> see comment Flags above)
    BtnFlag = 0;
  }

  if (StValue == 0 && StFlag == 0 ) { //if the button is pressed and the flag is 0 -> add 1 to menu
    StMenu = 1;
    StFlag = 1;
    StCancelFlag = 0;
    lcd.clear();
  }

  if (StValue == 1 && StFlag == 1) { //if the button is not pressed and the flag is 0 -> Reset the flag (purpose of the flag -> see comment Flags above)
   StFlag = 0;
   StMenu = 0;
  }
  if (StValue == 1 && StFlag == 0) { //if the button is not pressed and the flag is 0 -> Reset the flag (purpose of the flag -> see comment Flags above)
    StMenu = 0;
  }
  //***********************************************Menu0***********************************************//
  if (MenuNr == 0) { //Menu0 program
    if (SwMenu == 0) { //Info screen /PRE-LAUNCH
      //MaxSwMenu = 0;
      RucPos = 0;
      lcd.setCursor(0, 0);
      lcd.print("|__|");
      lcd.setCursor(5, 0);
      lcd.print(PosuvNom);
      lcd.setCursor(0, 1);
      lcd.print("## #");
      lcd.setCursor(5, 1);
      lcd.print(StrihCislo);
      lcd.print ("/");
      lcd.print(Opak);
      //lcd.setCursor(0, 2);
      //lcd.print("_|__");
      //lcd.setCursor(5, 2);
      //lcd.print(newPos);
      lcd.setCursor(11, 0);
      lcd.print("+/-");
      lcd.setCursor(16, 0);
      lcd.print(Korekce);
      lcd.setCursor(11, 1);
      lcd.print("|__");
      lcd.setCursor(15, 1);
      lcd.print(newPos / step_per_mm);
      lcd.setCursor(0, 2);
      lcd.print("VVVV");
      lcd.setCursor(5, 2);
      lcd.print(uchopCheck);
      lcd.setCursor(15, 2);
      lcd.print(StMenu);

      lcd.setCursor(0, 3);
      lcd.print("|->   POZICE   START");

    }
  }
  if (SwMenu == 1 && MenuNr == 0) { //Rucni posuv
    StMenu = 0;
    lcd.setCursor(0, 0);
    lcd.print("Rucni posuv [mm]");
    lcd.setCursor(0, 1);
    lcd.print("~|__:");
    lcd.setCursor(7, 1);
    lcd.print(RucPos);
    lcd.setCursor(8, 3);
    lcd.print("OK");

    if (FastChng == 0) {  // RH - if not in fast change mode, update set time
      SetTime = millis();
    }

    if (YValue < 400 && Flag2 == 0) { //joystick up -> Add 2 to number of photo's
      RucPos = RucPos - 0.01;
      Flag2 = 1;
      FastChng = 1;
      lcd.clear();
    }
    if (YValue > 600 && Flag2 == 0) { //joystick down -> Subtract 2 from number of photo's
      RucPos = RucPos + 0.01;
      Flag2 = 1;
      FastChng = 1;
      lcd.clear();
    }
    if (YValue > 399 && YValue < 599 && Flag2 == 1) { //if the Y-axis is back at it's neutral possition -> Flag3 = 0 -> Prevents constant adding or subtracting of 2
      Flag2 = 0;
      FastChng = 0;
    }

    if (YValue < 400 && FastChng == 1) {  // RH - if joystick up is held for > the fast delay time, then enter fast change mode
      if ((millis() - SetTime) > FastDelay) {
        FastChng = 2;
        SetTime = millis();  // update the set time
      }
    }

    if (YValue > 600 && FastChng == 1) {  // RH - if joystick down is held for > the fast delay time, then enter fast change mode
      if ((millis() - SetTime) > FastDelay) {
        FastChng = 2;
        SetTime = millis();  // update the set time
      }
    }

    if (YValue < 400 && FastChng == 2) {  // RH - we are in fast change mode, so we want to update the values quickly, proportional between
      if ((millis() - SetTime) > (LongInt - (400 - YValue) * (LongInt - ShortInt) / 400)) {  // ShortInt and LongInt based on joystick deflection
        RucPos = RucPos - 0.02;
        SetTime = millis();
        lcd.clear();
      }
    }

    if (YValue > 600 && FastChng == 2) {  // RH - same for joystick down in fast change mode
      if ((millis() - SetTime) > (LongInt - (YValue - 600) * (LongInt - ShortInt) / 400)) {
        RucPos = RucPos + 0.02;
        SetTime = millis();
        lcd.clear();
      }
    }
    if (XValue < 400 && Flag1 == 0) { //joystick up -> Add 2 to number of photo's
      RucPos = RucPos + 1;
      Flag1 = 1;
      FastChng = 1;
      lcd.clear();
    }
    if (XValue > 600 && Flag1 == 0) { //joystick down -> Subtract 2 from number of photo's
      RucPos = RucPos - 1;
      Flag1 = 1;
      FastChng = 1;
      lcd.clear();
    }
    if (XValue > 399 && XValue < 599 && Flag1 == 1) { //if the Y-axis is back at it's neutral possition -> Flag3 = 0 -> Prevents constant adding or subtracting of 2
      Flag1 = 0;
      FastChng = 0;
    }
    //POSUV PO 10 MM
    if (XValue < 400 && FastChng == 1) {  // RH - if joystick up is held for > the fast delay time, then enter fast change mode
      if ((millis() - SetTime) > FastDelay) {
        FastChng = 2;
        SetTime = millis();  // update the set time
      }
    }

    if (XValue > 600 && FastChng == 1) {  // RH - if joystick down is held for > the fast delay time, then enter fast change mode
      if ((millis() - SetTime) > FastDelay) {
        FastChng = 2;
        SetTime = millis();  // update the set time
      }
    }
    if (XValue < 400 && FastChng == 2) {  // RH - we are in fast change mode, so we want to update the values quickly, proportional between
      if ((millis() - SetTime) > (LongInt - (400 - XValue) * (LongInt - ShortInt) / 400)) {  // ShortInt and LongInt based on joystick deflection
        RucPos = RucPos + 1;
        SetTime = millis();
        lcd.clear();
      }
    }

    if (XValue > 600 && FastChng == 2) {  // RH - same for joystick down in fast change mode
      if ((millis() - SetTime) > (LongInt - (XValue - 600) * (LongInt - ShortInt) / 400)) {
        RucPos = RucPos - 1;
        SetTime = millis();
        lcd.clear();
      }
    }

    RucSTP = step_per_mm * RucPos;

    stepper.moveTo(RucSTP + newPos);
    // Run to target position with set speed and acceleration/deceleration:
    stepper.runToPosition();
  }
  if (SwMenu == 2 && MenuNr == 0) { //Navrat
    newPos = newPos + RucSTP;
    StMenu = 0;
    SwMenu = 0;
    //MaxSwMenu = 1;
  }

  if (MenuNr == 1) { //Posuv program
    if (SwMenu == 0 && MenuNr == 1) { //Posuv overview
      StMenu = 0;
      lcd.setCursor(0, 0);
      lcd.print("Posuv plechu [mm]");
      lcd.setCursor(0, 1);
      lcd.print("|__|:");
      lcd.setCursor(7, 1);
      lcd.print(PosuvNom);
      lcd.setCursor(0, 2);
      lcd.print("## #:");
      lcd.setCursor(7, 2);
      lcd.print(Opak);
      lcd.setCursor(0, 3);
      lcd.print("<->    NASTAVENI");
    }
    if (SwMenu == 1) { //Posuv zadani hodnot
      //StReady = 0;
      lcd.setCursor(0, 0);
      lcd.print("Zadej posuv [mm]");
      lcd.setCursor(7, 1);
      lcd.print(PosuvNom);
      lcd.setCursor(8, 3);
      lcd.print("OK");

      if (FastChng == 0) {  // RH - if not in fast change mode, update set time
        SetTime = millis();
      }

      if (YValue < 400 && Flag2 == 0) { //joystick up -> Add 2 to number of photo's
        PosuvNom = PosuvNom - 0.01;
        Flag2 = 1;
        FastChng = 1;
        lcd.clear();
      }
      if (YValue > 600 && Flag2 == 0) { //joystick down -> Subtract 2 from number of photo's
        PosuvNom = PosuvNom + 0.01;
        Flag2 = 1;
        FastChng = 1;
        lcd.clear();
      }
      if (YValue > 399 && YValue < 599 && Flag2 == 1) { //if the Y-axis is back at it's neutral possition -> Flag3 = 0 -> Prevents constant adding or subtracting of 2
        Flag2 = 0;
        FastChng = 0;
      }

      if (YValue < 400 && FastChng == 1) {  // RH - if joystick up is held for > the fast delay time, then enter fast change mode
        if ((millis() - SetTime) > FastDelay) {
          FastChng = 2;
          SetTime = millis();  // update the set time
        }
      }

      if (YValue > 600 && FastChng == 1) {  // RH - if joystick down is held for > the fast delay time, then enter fast change mode
        if ((millis() - SetTime) > FastDelay) {
          FastChng = 2;
          SetTime = millis();  // update the set time
        }
      }

      if (YValue < 400 && FastChng == 2) {  // RH - we are in fast change mode, so we want to update the values quickly, proportional between
        if ((millis() - SetTime) > (LongInt - (400 - YValue) * (LongInt - ShortInt) / 400)) {  // ShortInt and LongInt based on joystick deflection
          PosuvNom = PosuvNom - 0.1;
          SetTime = millis();
          lcd.clear();
        }
      }

      if (YValue > 600 && FastChng == 2) {  // RH - same for joystick down in fast change mode
        if ((millis() - SetTime) > (LongInt - (YValue - 600) * (LongInt - ShortInt) / 400)) {
          PosuvNom = PosuvNom + 0.1;
          SetTime = millis();
          lcd.clear();
        }
      }
      if (XValue < 400 && Flag1 == 0) { //joystick up -> Add 2 to number of photo's
        PosuvNom = PosuvNom + 1;
        Flag1 = 1;
        FastChng = 1;
        lcd.clear();
      }
      if (XValue > 600 && Flag1 == 0) { //joystick down -> Subtract 2 from number of photo's
        PosuvNom = PosuvNom - 1;
        Flag1 = 1;
        FastChng = 1;
        lcd.clear();
      }
      if (XValue > 399 && XValue < 599 && Flag1 == 1) { //if the Y-axis is back at it's neutral possition -> Flag3 = 0 -> Prevents constant adding or subtracting of 2
        Flag1 = 0;
        FastChng = 0;
      }
      //POSUV PO 10 MM
      if (XValue < 400 && FastChng == 1) {  // RH - if joystick up is held for > the fast delay time, then enter fast change mode
        if ((millis() - SetTime) > FastDelay) {
          FastChng = 2;
          SetTime = millis();  // update the set time
        }
      }

      if (XValue > 600 && FastChng == 1) {  // RH - if joystick down is held for > the fast delay time, then enter fast change mode
        if ((millis() - SetTime) > FastDelay) {
          FastChng = 2;
          SetTime = millis();  // update the set time
        }
      }
      if (XValue < 400 && FastChng == 2) {  // RH - we are in fast change mode, so we want to update the values quickly, proportional between
        if ((millis() - SetTime) > (LongInt - (400 - XValue) * (LongInt - ShortInt) / 400)) {  // ShortInt and LongInt based on joystick deflection
          PosuvNom = PosuvNom + 1;
          SetTime = millis();
          lcd.clear();
        }
      }

      if (XValue > 600 && FastChng == 2) {  // RH - same for joystick down in fast change mode
        if ((millis() - SetTime) > (LongInt - (XValue - 600) * (LongInt - ShortInt) / 400)) {
          PosuvNom = PosuvNom - 1;
          SetTime = millis();
          lcd.clear();
        }
      }
      if (PosuvNom < 0) {   //Min posuv
        PosuvNom = 0;
      }
      if (PosuvNom > 500) { //Max posuv
        PosuvNom = 500;
      }
    }
    if (SwMenu == 2) { //Opakovani zadani hodnot
      //StReady = 0;
      lcd.setCursor(0, 0);
      lcd.print("Zadej pocet posuvu");
      lcd.setCursor(7, 1);
      lcd.print(Opak);
      lcd.setCursor(8, 3);
      lcd.print("OK");
      if (YValue < 400 && FlagOp == 0) { //joystick up -> Add 2 to number of photo's
        Opak = Opak - 1;
        FlagOp = 1;
        FastChng = 1;
        lcd.clear();
      }
      if (YValue > 600 && FlagOp == 0) { //joystick down -> Subtract 2 from number of photo's
        Opak = Opak + 1;
        FlagOp = 1;
        FastChng = 1;
        lcd.clear();
      }
      if (YValue > 399 && YValue < 599 && FlagOp == 1) { //if the Y-axis is back at it's neutral possition -> Flag3 = 0 -> Prevents constant adding or subtracting of 2
        FlagOp = 0;
        FastChng = 0;
      }




    }
    if (SwMenu == 3) { //Ulozeno
      StReady = 1;
      //StMenu = 0;
      SwMenu = 0;
      //MaxSwMenu = 1;
    }
  }
  if (MenuNr == 2) { //Korekce program
    if (SwMenu == 0) { //Korekce overview
      //MaxSwMenu = 0;
      lcd.setCursor(0, 0);
      lcd.print("Korekce posuvu [mm]");
      lcd.setCursor(0, 1);
      lcd.print("+/- :");
      lcd.setCursor(7, 1);
      lcd.print(Korekce);
      lcd.setCursor(0, 3);
      lcd.print("<-|    NASTAVENI");
    }
    if (SwMenu == 1) { //Posuv zadani hodnot
      //StReady = 0;
      lcd.setCursor(0, 0);
      lcd.print("Zadej korekci [mm]");
      lcd.setCursor(7, 1);
      lcd.print(Korekce);
      lcd.setCursor(8, 3);
      lcd.print("OK");

      if (FastChng == 0) {  // RH - if not in fast change mode, update set time
        SetTime = millis();
      }

      if (YValue < 400 && Flag2 == 0) { //joystick up -> Add 2 to number of photo's
        Korekce = Korekce - 0.01;
        Flag2 = 1;
        FastChng = 1;
        lcd.clear();
      }
      if (YValue > 600 && Flag2 == 0) { //joystick down -> Subtract 2 from number of photo's
        Korekce = Korekce + 0.01;
        Flag2 = 1;
        FastChng = 1;
        lcd.clear();
      }
      if (YValue > 399 && YValue < 599 && Flag2 == 1) { //if the Y-axis is back at it's neutral possition -> Flag3 = 0 -> Prevents constant adding or subtracting of 2
        Flag2 = 0;
        FastChng = 0;
      }

      if (YValue < 400 && FastChng == 1) {  // RH - if joystick up is held for > the fast delay time, then enter fast change mode
        if ((millis() - SetTime) > FastDelay) {
          FastChng = 2;
          SetTime = millis();  // update the set time
        }
      }

      if (YValue > 600 && FastChng == 1) {  // RH - if joystick down is held for > the fast delay time, then enter fast change mode
        if ((millis() - SetTime) > FastDelay) {
          FastChng = 2;
          SetTime = millis();  // update the set time
        }
      }

      if (YValue < 400 && FastChng == 2) {  // RH - we are in fast change mode, so we want to update the values quickly, proportional between
        if ((millis() - SetTime) > (LongInt - (400 - YValue) * (LongInt - ShortInt) / 400)) {  // ShortInt and LongInt based on joystick deflection
          Korekce = Korekce - 0.02;
          SetTime = millis();
          lcd.clear();
        }
      }

      if (YValue > 600 && FastChng == 2) {  // RH - same for joystick down in fast change mode
        if ((millis() - SetTime) > (LongInt - (YValue - 600) * (LongInt - ShortInt) / 400)) {
          Korekce = Korekce + 0.02;
          SetTime = millis();
          lcd.clear();
        }
      }
      if (XValue < 400 && Flag1 == 0) { //joystick up -> Add 2 to number of photo's
        Korekce = Korekce + 1;
        Flag1 = 1;
        FastChng = 1;
        lcd.clear();
      }
      if (XValue > 600 && Flag1 == 0) { //joystick down -> Subtract 2 from number of photo's
        Korekce = Korekce - 1;
        Flag1 = 1;
        FastChng = 1;
        lcd.clear();
      }
      if (XValue > 399 && XValue < 599 && Flag1 == 1) { //if the Y-axis is back at it's neutral possition -> Flag3 = 0 -> Prevents constant adding or subtracting of 2
        Flag1 = 0;
        FastChng = 0;
      }
      //POSUV PO 10 MM
      if (XValue < 400 && FastChng == 1) {  // RH - if joystick up is held for > the fast delay time, then enter fast change mode
        if ((millis() - SetTime) > FastDelay) {
          FastChng = 2;
          SetTime = millis();  // update the set time
        }
      }

      if (XValue > 600 && FastChng == 1) {  // RH - if joystick down is held for > the fast delay time, then enter fast change mode
        if ((millis() - SetTime) > FastDelay) {
          FastChng = 2;
          SetTime = millis();  // update the set time
        }
      }
      if (XValue < 400 && FastChng == 2) {  // RH - we are in fast change mode, so we want to update the values quickly, proportional between
        if ((millis() - SetTime) > (LongInt - (400 - XValue) * (LongInt - ShortInt) / 400)) {  // ShortInt and LongInt based on joystick deflection
          Korekce = Korekce + 1;
          SetTime = millis();
          lcd.clear();
        }
      }

      if (XValue > 600 && FastChng == 2) {  // RH - same for joystick down in fast change mode
        if ((millis() - SetTime) > (LongInt - (XValue - 600) * (LongInt - ShortInt) / 400)) {
          Korekce = Korekce - 1;
          SetTime = millis();
          lcd.clear();
        }
      }

    }

    if (SwMenu == 2) { //Ulozeno
      //StReady = 1;
      //StMenu = 0;
      SwMenu = 0;
      //MaxSwMenu = 1;
    }
  }
  if (StMenu == 1 && StReady == 1  && uchop == 0) { //Program started
    //MaxSwMenu = 0;
    lcd.clear();
    lcd.setCursor(3, 0);
    lcd.print("PROBIHA POSUV");
    lcd.setCursor(9, 1);
    lcd.print(PosuvNom);
    lcd.setCursor(9,2);
    
    if (StrihCislo < Opak) {
      PosuvSTP = step_per_mm * (PosuvNom + Korekce);
      newPos = newPos + PosuvSTP;
      stepper.moveTo(newPos);
      // Run to target position with set speed and acceleration/deceleration:
      stepper.runToPosition();

      delay(1000);
      StrihCislo = StrihCislo + 1;
      pocitadlo = pocitadlo + 1;
      //celkemL = celkemL + PosuvNom;
      lcd.clear();
      lcd.setCursor(7, 0);
      lcd.print("STRIH ");
      lcd.setCursor(8,1);
      lcd.print(StrihCislo);
      lcd.print ("/");
      lcd.print(Opak);
      digitalWrite(11, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(1000);                       // wait for a second
      digitalWrite(11, LOW);    // turn the LED off by making the voltage LOW
      delay(10);
      lcd.clear();
      StMenu = 1;
    }

    if (StrihCislo == Opak) { //If the amount of photos taken is equal to the amount of photos that have to be taken -> Program finished
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Program finished");
      delay(1000);
      lcd.clear();  //Rest parameters
      StrihCislo = 0;
      SwMenu = 0;
      MaxSwMenu = 0;
      StMenu = 0;
      Steps = 0;


    }

    
    }
  

}
A4988