#include <LiquidCrystal.h>
#define stepPin 13 // Step pin, digital output for ball on cup
#define dirPin 12   //Dir pin, digital output for ball on cup
#define stepPinp 7 // Step pin, digital output for pin on plate
#define dirPinp 6   //Dir pin, digital output for pin on plate
#define VRX_PIN  A0 // Analog arduino pin connected to VRX pin
#define VRY_PIN  A1 // Analog arduino pin connected to VRY pin
int xValue = 0; // To store value of the X axis
int yValue = 0; // To store value of the Y axis

//
//LCD pins
int rsPin = 52; 
int ePin = 50;
int d4Pin = 48;
int d5Pin = 46;
int d6Pin = 44;
int d7Pin = 42;
LiquidCrystal LCD(rsPin,ePin,d4Pin,d5Pin,d6Pin,d7Pin);

//control
int push=3; // digital input on joystick

//calibration inputs
int dorazboc1=10;
int dorazboc2=9;
int dorazpon1=20;
int dorazpon2=21;





// helping variables
int i;      
int k;
int d;
int o;
int Speed;
long dist;
long ck2;
long ck;

 

void setup() {
  Serial.begin(9600);
  ck=0;
  ck2=0;
  { 
    //PIN setup
    pinMode(push, INPUT_PULLUP); //joystick push button
    pinMode(dorazboc1, INPUT_PULLUP); //switching contact normally off
    pinMode(dorazboc2, INPUT_PULLUP); //switching contact normally off
    pinMode(dorazpon1, INPUT);      //switching contact normally on
    pinMode(dorazpon2, INPUT);      //switching contact normally on
    pinMode(stepPin, OUTPUT);     
    pinMode(dirPin, OUTPUT);//1
    pinMode(stepPinp, OUTPUT);     
    pinMode(dirPinp, OUTPUT);//1
    digitalWrite(dirPin, HIGH);

// LCD view begin
 LCD.begin(20,4);
 LCD.clear();
  LCD.setCursor(7,1);
LCD.print("WELCOME");
delay(2000);
LCD.clear();
LCD.setCursor(6,0);
LCD.print("CYCLOPS");
LCD.setCursor(0,1);
LCD.print("TRIBO eye simulator");
 LCD.setCursor(0,2);
 LCD.print("Author: Lukas Snopek");
 delay(3000);
}}


void loop() {
 //xValue = analogRead(VRX_PIN);
// yValue = analogRead(VRY_PIN);
 i=1;                            //scrol ball reset
  ck=0;
  
//MAIN

 LCD.clear();
 LCD.setCursor(0,0);
LCD.print("CHOOSE CONFIGURATION");
LCD.setCursor(0,1);
LCD.print("BALL IN CUP");
LCD.setCursor(0,2);
LCD.print("PIN ON PLATE");
LCD.setCursor(0,3);
LCD.print("INFO");
LCD.setCursor(15,1);
LCD.print("<--");
//Choose menu
while(digitalRead(push)==HIGH){   //Scroling in menu
       if(analogRead(VRY_PIN)>700){
         i=i+1;{
          if (i>=4){
            i=1;
            delay(100);
             roler(i);
                 }
           else{
           roler(i);
           delay(100);
          }
        }
     }
  }

  //Choose of ball on cup
    if(i==1){   //program ball on cup
      LCD.clear();
      LCD.setCursor(1,(1));
      LCD.print("BALL IN CUP PROG");
      delay(1500);
      LCD.clear();
      LCD.setCursor(2,(1));
      o=110; //default cycle number
      LCD.print("NUMBER OF CYCLES");
      LCD.setCursor(9,(2));
      LCD.print(o);
      delay(1000);
      
  //Number of cycle choose
        while(digitalRead(push)==HIGH){
             
              if(analogRead(VRX_PIN)>800){
                   o=o+10;{
                   LCD.setCursor(0,(2));
                   LCD.print("                ");
                   LCD.setCursor(9,2);
                   LCD.print(o);
                   delay(10);
          }
      }
               if(analogRead(VRY_PIN)>800){
                    o=o+100;{
                    LCD.setCursor(2,(2));
                    LCD.print("                ");
                    LCD.setCursor(9,2);
                    LCD.print(o);
                    delay(10);
      }
    }
                   if(analogRead(VRY_PIN)<200){
                    o=o-100;{
                    LCD.setCursor(2,(2));
                    LCD.print("                ");
                    LCD.setCursor(9,2);
                    LCD.print(o);
                    delay(10);
      }
    }
                   if(analogRead(VRX_PIN)<200){
                    o=o-10;{
                    LCD.setCursor(2,(2));
                    LCD.print("                ");
                    LCD.setCursor(9,2);
                    LCD.print(o);
                    delay(10);
      }
    }
    delay(300);
    } 
    LCD.clear();
    d=500; //default set delay betwen blinks
    LCD.setCursor(0,(1));
    LCD.print("DELAY BETWEEN BLINKS");
    LCD.setCursor(7,(2));
    LCD.print(d);
    LCD.setCursor(14,(2));
    LCD.print("ms");
    delay(1000);
       //delay between blinks choose
          while(digitalRead(push)==HIGH){
                if(analogRead(VRX_PIN)>800){
                  d=d+10;{
                  delay(10);
                  LCD.setCursor(0,(2));
                  LCD.print("             ");
                  LCD.setCursor(7,(2));
                  LCD.print(d);
       }
      }
                if(analogRead(VRY_PIN)>800){
                  d=d+100;{
                  delay(10);
                  LCD.setCursor(0,(2));
                  LCD.print("             ");
                  LCD.setCursor(7,(2));
                  LCD.print(d);
       }
      }                if(analogRead(VRX_PIN)<200){
                  d=d-10;{
                  delay(10);
                  LCD.setCursor(0,(2));
                  LCD.print("             ");
                  LCD.setCursor(7,(2));
                  LCD.print(d);
       }
      }                if(analogRead(VRY_PIN)<200){
                  d=d-100;{
                  delay(10);
                  LCD.setCursor(0,(2));
                  LCD.print("             ");
                  LCD.setCursor(7,(2));
                  LCD.print(d);
       }
      }

      
      delay(300);       
    } 
delay(300);
    LCD.clear();
    Speed=60; // default set speed
    LCD.setCursor(6,(1));
    LCD.print("SPEED");
    LCD.setCursor(7,(2));
    LCD.print(Speed);
    LCD.setCursor(12,(2));
    LCD.print("mps");
    delay(1000);
    //Choose speed 
          while(digitalRead(push)==HIGH){
                if(analogRead(VRX_PIN)>800){
                   Speed=Speed+1;{
                   delay(10);
                   LCD.setCursor(0,(2));
                   LCD.print("         ");
                   LCD.setCursor(7,(2));
                   LCD.print(Speed);
                   }}
                 if(analogRead(VRY_PIN)>800){
                   Speed=Speed+10;{
                   delay(10);
                   LCD.setCursor(0,(2));
                   LCD.print("            ");
                   LCD.setCursor(7,(2));
                   LCD.print(Speed);
                   }}
                 if(analogRead(VRX_PIN)<200){
                   Speed=Speed-1;{
                   delay(10);
                   LCD.setCursor(0,(2));
                   LCD.print("            ");
                   LCD.setCursor(7,(2));
                   LCD.print(Speed);
                   }}
                 if(analogRead(VRY_PIN)<200){
                   Speed=Speed-10;{
                   delay(10);
                   LCD.setCursor(0,(2));
                   LCD.print("            ");
                   LCD.setCursor(7,(2));
                   LCD.print(Speed);
                   }}
    delay(500);
    }
    LCD.clear();
    LCD.setCursor(0,(0));
    LCD.print("NUMBER OF CYCLES");
    LCD.setCursor(3,(1));
    LCD.print(o);
    LCD.setCursor(1,(2));
    LCD.print("DELAY BETWEEN BLINK ");
    LCD.setCursor(1,(3));
    LCD.print(d);
    LCD.setCursor(7,(3));
    LCD.print("ms");
    delay(4000);
    LCD.clear();
    LCD.setCursor(2,(1));
    LCD.print("START IN:");
    delay(1000);
    LCD.setCursor(13,(1));
    LCD.print("3");
    delay(1000);
    LCD.setCursor(15,(1));
    LCD.print("2");
    delay(1000);
    LCD.setCursor(17,(1));
    LCD.print("1");
    delay(1000);
    LCD.clear();
    LCD.setCursor(6,(1));
    LCD.print("WORKING");
    LCD.setCursor(9,(2));
    LCD.print(o);
    LCD.setCursor(8,(2));
    LCD.print("/");
    delay(3000);
    Calibboc();
    delay(1000);
    ball1();
    LCD.clear();
    LCD.setCursor(1,(0));
    LCD.print("FINISH");
    LCD.setCursor(1,2);
    LCD.print("PRESS PUSH TO");
    LCD.setCursor(6,3);
    LCD.print("CONTINUE");
    while(digitalRead(push)==HIGH){
      delay(10);
    }
    }
    delay(1000);
    // END of ball on cup choose
     

    //pin on plate choose menu
    if(i==2){
   LCD.clear();
      LCD.setCursor(3,(1));
      LCD.print("PIN ON PLATE");
      delay(1500);
      LCD.clear();
      LCD.setCursor(2,(1));
      o=110; //default cycle number
      LCD.print("NUMBER OF CYCLES");
      LCD.setCursor(9,(2));
      LCD.print(o);
      delay(1000);
      
  //Number of cycle choose
        while(digitalRead(push)==HIGH){
             
              if(analogRead(VRX_PIN)>800){
                   o=o+10;{
                   LCD.setCursor(0,(2));
                   LCD.print("                ");
                   LCD.setCursor(9,2);
                   LCD.print(o);
                   delay(10);
          }
      }
               if(analogRead(VRY_PIN)>800){
                    o=o+100;{
                    LCD.setCursor(2,(2));
                    LCD.print("                ");
                    LCD.setCursor(9,2);
                    LCD.print(o);
                    delay(10);
      }
    }
                   if(analogRead(VRY_PIN)<200){
                    o=o-100;{
                    LCD.setCursor(2,(2));
                    LCD.print("                ");
                    LCD.setCursor(9,2);
                    LCD.print(o);
                    delay(10);
      }
    }
                   if(analogRead(VRX_PIN)<200){
                    o=o-10;{
                    LCD.setCursor(2,(2));
                    LCD.print("                ");
                    LCD.setCursor(9,2);
                    LCD.print(o);
                    delay(10);
      }
    }
    delay(300);
    } 
    LCD.clear();
    d=500; //default set delay betwen blinks
    LCD.setCursor(0,(1));
    LCD.print("DELAY BETWEEN BLINKS");
    LCD.setCursor(7,(2));
    LCD.print(d);
    LCD.setCursor(14,(2));
    LCD.print("ms");
    delay(1000);
       //delay between blinks choose
          while(digitalRead(push)==HIGH){
                if(analogRead(VRX_PIN)>800){
                  d=d+10;{
                  delay(10);
                  LCD.setCursor(0,(2));
                  LCD.print("             ");
                  LCD.setCursor(7,(2));
                  LCD.print(d);
       }
      }
                if(analogRead(VRY_PIN)>800){
                  d=d+100;{
                  delay(10);
                  LCD.setCursor(0,(2));
                  LCD.print("             ");
                  LCD.setCursor(7,(2));
                  LCD.print(d);
       }
      }                if(analogRead(VRX_PIN)<200){
                  d=d-10;{
                  delay(10);
                  LCD.setCursor(0,(2));
                  LCD.print("             ");
                  LCD.setCursor(7,(2));
                  LCD.print(d);
       }
      }                if(analogRead(VRY_PIN)<200){
                  d=d-100;{
                  delay(10);
                  LCD.setCursor(0,(2));
                  LCD.print("             ");
                  LCD.setCursor(7,(2));
                  LCD.print(d);
       }
      }

      
      delay(300);       
    } 
delay(300);
    LCD.clear();
    Speed=60; // default set speed
    LCD.setCursor(6,(1));
    LCD.print("SPEED");
    LCD.setCursor(7,(2));
    LCD.print(Speed);
    LCD.setCursor(12,(2));
    LCD.print("mps");
    delay(1000);
    //Choose speed 
          while(digitalRead(push)==HIGH){
                if(analogRead(VRX_PIN)>800){
                   Speed=Speed+1;{
                   delay(10);
                   LCD.setCursor(0,(2));
                   LCD.print("         ");
                   LCD.setCursor(7,(2));
                   LCD.print(Speed);
                   }}
                 if(analogRead(VRY_PIN)>800){
                   Speed=Speed+10;{
                   delay(10);
                   LCD.setCursor(0,(2));
                   LCD.print("            ");
                   LCD.setCursor(7,(2));
                   LCD.print(Speed);
                   }}
                 if(analogRead(VRX_PIN)<200){
                   Speed=Speed-1;{
                   delay(10);
                   LCD.setCursor(0,(2));
                   LCD.print("            ");
                   LCD.setCursor(7,(2));
                   LCD.print(Speed);
                   }}
                 if(analogRead(VRY_PIN)<200){
                   Speed=Speed-10;{
                   delay(10);
                   LCD.setCursor(0,(2));
                   LCD.print("            ");
                   LCD.setCursor(7,(2));
                   LCD.print(Speed);
                   }}
    delay(500);
    }
    LCD.clear();
    dist=40; // 400max  default distance
    LCD.setCursor(6,(1));
    LCD.print("DISTANCE");
    LCD.setCursor(7,(2));
    LCD.print(dist);
    LCD.setCursor(12,(2));
    LCD.print("mm");
    delay(300);
    while(digitalRead(push)==HIGH){
                 if(analogRead(VRX_PIN)>800){
                   dist=dist+1;{
                   delay(10);
                   LCD.setCursor(0,(2));
                   LCD.print("           ");
                   LCD.setCursor(7,(2));
                   LCD.print(dist);
                   }}
                 if(analogRead(VRY_PIN)>800){
                     dist=dist+10;{
                   delay(10);
                   LCD.setCursor(0,(2));
                   LCD.print("           ");
                   LCD.setCursor(7,(2));
                   LCD.print(dist);
                   }}
                 if(analogRead(VRX_PIN)<200){
                     dist=dist-1;{
                   delay(10);
                   LCD.setCursor(0,(2));
                   LCD.print("           ");
                   LCD.setCursor(7,(2));
                   LCD.print(dist);
                   }}
                 if(analogRead(VRY_PIN)<200){
                    dist=dist-10;{
                   delay(10);
                   LCD.setCursor(0,(2));
                   LCD.print("           ");
                   LCD.setCursor(7,(2));
                   LCD.print(dist);
                   }}
                   delay(300);
    }
    

    






    LCD.clear();
    LCD.setCursor(0,(0));
    LCD.print("NUMBER OF CYCLES");
    LCD.setCursor(3,(1));
    LCD.print(o);
    LCD.setCursor(1,(2));
    LCD.print("DELAY BETWEEN BLINK ");
    LCD.setCursor(1,(3));
    LCD.print(d);
    LCD.setCursor(7,(3));
    LCD.print("ms");
    delay(4000);
    LCD.clear();
    LCD.setCursor(2,(1));
    LCD.print("START IN:");
    delay(1000);
    LCD.setCursor(13,(1));
    LCD.print("3");
    delay(1000);
    LCD.setCursor(15,(1));
    LCD.print("2");
    delay(1000);
    LCD.setCursor(17,(1));
    LCD.print("1");
    delay(1000);
    LCD.clear();
    LCD.setCursor(6,(1));
    LCD.print("WORKING");
    LCD.setCursor(9,(2));
    LCD.print(o);
    LCD.setCursor(8,(2));
    LCD.print("/");
    delay(3000);
    Calibpon();
    pinonplate();
    LCD.clear();
    LCD.setCursor(1,(0));
    LCD.print("FINISH");
    LCD.setCursor(1,2);
    LCD.print("PRESS PUSH TO");
    LCD.setCursor(6,3);
    LCD.print("CONTINUE");
    while(digitalRead(push)==HIGH){
      delay(10);
    }// pin on plate end
   delay(10000);
  }
  if(i==3){
    LCD.clear();
    LCD.setCursor(1,(2));
   LCD.print("ERROR 503");
   delay(10000);
  }
  }

  
// KONEC LOOP




void roler(int ii){
LCD.setCursor(15,(1));
LCD.print("    ");
LCD.setCursor(15,(2));
LCD.print("    ");
LCD.setCursor(15,3);
LCD.print("    ");
LCD.setCursor(15,ii);
LCD.print("<--");
delay(600);
}


void ball1()  {//program na beh ball on cup
 for (k = 0;k <= o;k++){//počet cyklů
 
    digitalWrite(dirPin, HIGH);//rozběh
    for (int i = 500; i >= Speed;i-=8) {
      
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(i);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(i);
    }

   for (int t = 0; t <= 130; t++) {
    digitalWrite(stepPin, HIGH);//konst rychlost
    delayMicroseconds(Speed);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(Speed);
    }
    for (int l = Speed; l <= 500; l+=8) {
    digitalWrite(stepPin, HIGH);//zpomalení
    delayMicroseconds(l);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(l);
    }
    delay(50);
    digitalWrite(dirPin, LOW);
    for (int i = 500; i >= Speed; i-=8) {//rozbeh druhy smer
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(i);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(i);
    }

   for (int t = 0; t <= 128 ;  t++) {//konst beh druhy smer
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(Speed);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(Speed);
    }
    for (int l = Speed; l <= 500; l+=8) {//zpomaleni na 0
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(l);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(l);
    }
    LCD.setCursor(4,(2));
    LCD.print(k);
    delay(d);//pauza mezi mrknutím
    
    }
    delay(5000);
 


}

void pinonplate()  {//program na beh pin on plate
  int ot=dist*400;
  
 for (k = 0;k <= o;k++){//počet cyklů
 
    digitalWrite(dirPinp, HIGH);//rozběh
    for (int i = 1000; i >= Speed;i-=5 ) {
      
    digitalWrite(stepPinp, HIGH);
    delayMicroseconds(i);
    digitalWrite(stepPinp, LOW);
    delayMicroseconds(i);
    }

   for (int t = 0; t <= ot; t++) {
    digitalWrite(stepPinp, HIGH);//konst rychlost
    delayMicroseconds(Speed);
    digitalWrite(stepPinp, LOW);
    delayMicroseconds(Speed);
    }
    for (int l = Speed; l <= 1000; l+=5) {
    digitalWrite(stepPinp, HIGH);//zpomalení
    delayMicroseconds(l);
    digitalWrite(stepPinp, LOW);
    delayMicroseconds(l);
    }
    delay(50);
    digitalWrite(dirPinp, LOW);
    for (int i = 1000; i >= Speed; i-=5) {//rozbeh druhy smer
    digitalWrite(stepPinp, HIGH);
    delayMicroseconds(i);
    digitalWrite(stepPinp, LOW);
    delayMicroseconds(i);
    }

   for (int t = 0; t <= (ot-2) ;  t++) {//konst beh druhy smer
    digitalWrite(stepPinp, HIGH);
    delayMicroseconds(Speed);
    digitalWrite(stepPinp, LOW);
    delayMicroseconds(Speed);
    }
    for (int l = Speed; l <= 1000; l+=5) {//zpomaleni na 0
    digitalWrite(stepPinp, HIGH);
    delayMicroseconds(l);
    digitalWrite(stepPinp, LOW);
    delayMicroseconds(l);
    }
    LCD.setCursor(4,(2));
    LCD.print(k);
    delay(d);//pauza mezi mrknutím
    
    }
    delay(1000);
}
void Calibboc() //do pin 9,10 cerne kabely + oraznzovy do ground
{
 
digitalWrite(dirPin, HIGH);
while(digitalRead(dorazboc1) == LOW) { 
digitalWrite(stepPin, HIGH);//konst rychlost
delayMicroseconds(700);
digitalWrite(stepPin, LOW);
delayMicroseconds(700);
ck=ck+1;
}
digitalWrite(dirPin, LOW);
while(digitalRead(dorazboc2) == LOW) {
digitalWrite(stepPin, HIGH);//konst rychlost
delayMicroseconds(700);
digitalWrite(stepPin, LOW);
delayMicroseconds(700);
ck2=ck2+1;
}
ck2=(ck2/2);
digitalWrite(dirPin, HIGH);
for (long dpk = 0; dpk < ck2 ; dpk++) {//konst beh druhy smer
digitalWrite(stepPin, HIGH);
delayMicroseconds(700);
digitalWrite(stepPin, LOW);
delayMicroseconds(700); 
}

digitalWrite(dirPin, LOW);//rozběh do clalibrace
    for (int x = 500; x >= Speed;x-=8 ) {
      
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(x);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(x);
    }

   for (int y = 0; y <= 64; y++) {
    digitalWrite(stepPin, HIGH);//posun
    delayMicroseconds(Speed);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(Speed);
    }
 
    

}
void Calibpon() //do pin on plate
{
 int pul=dist*200;
digitalWrite(dirPinp, HIGH);
while(digitalRead(dorazpon1) == LOW) { 
digitalWrite(stepPinp, HIGH);//konst rychlost
delayMicroseconds(500);
digitalWrite(stepPinp, LOW);
delayMicroseconds(500);
ck=ck+1;
}
digitalWrite(dirPinp, LOW);
while(digitalRead(dorazpon2) == LOW) {
digitalWrite(stepPinp, HIGH);//konst rychlost
delayMicroseconds(500);
digitalWrite(stepPinp, LOW);
delayMicroseconds(500);
ck2=ck2+1;
}
ck2=(ck2/2);
digitalWrite(dirPinp, HIGH);
for (long dpk = 0; dpk < ck2 ; dpk++) {//konst beh druhy smer
digitalWrite(stepPinp, HIGH);
delayMicroseconds(500);
digitalWrite(stepPinp, LOW);
delayMicroseconds(500); 
}
digitalWrite(dirPinp, LOW);//rozběh do clalibrace
    for (int x = 700; x >= Speed;x-=5 ) {
      
    digitalWrite(stepPinp, HIGH);
    delayMicroseconds(x);
    digitalWrite(stepPinp, LOW);
    delayMicroseconds(x);
    }

   for (int y = 0; y <= pul; y++) {
    digitalWrite(stepPinp, HIGH);//posun
    delayMicroseconds(Speed);
    digitalWrite(stepPinp, LOW);
    delayMicroseconds(Speed);
    }


}