/*
*/
#include <LiquidCrystal_I2C.h>
#include <TimerOne.h>
#include <AccelStepper.h>
#define POTI                   A0
#define ENCODER_CLK            A1
#define ENCODER_DT             A2
#define ENCODER_ENTER          A3
#define SDA                    A4
#define SCL                    A5
#define RX                      2
#define TX                      3
#define FUSSSCHALTER            4 
#define FUSSTASTER              5
#define DREHRICHTUNG            6
#define RELAY                   9
#define PUL                    10
#define DIR                    11
LiquidCrystal_I2C lcd( 0x27, 16, 2);
bool statePULS;
float rpm = 1.0;
int lastClk = HIGH;
AccelStepper stepper( 1, PUL, DIR );     // 1 = Easy Driver interface
void setup() {
  Serial.begin(115200);
  Serial.println("\n\nSteuerung A.Burger 2024 v1.0\n");
  pinMode(ENCODER_CLK,   INPUT_PULLUP);
  pinMode(ENCODER_DT,    INPUT_PULLUP);
  pinMode(ENCODER_ENTER, INPUT_PULLUP);
  pinMode(PUL, OUTPUT);
  pinMode(DIR, OUTPUT);
  pinMode(FUSSSCHALTER,  INPUT_PULLUP);
  pinMode(FUSSTASTER,    INPUT_PULLUP);
  pinMode(DREHRICHTUNG,  INPUT_PULLUP);
  pinMode(RELAY, OUTPUT);
  lcd.init();
  lcd.backlight();
  lcd.clear();
  //lcd.cursor();
  lcd.setCursor(0, 0);
  lcd.noCursor();
}
void showMenu(int pos) {
  lcd.clear();
  switch(pos) {
    case 1:
      lcd.setCursor(0, 1); lcd.print("FOTODREHTELLER>1");
      lcd.setCursor(0, 0); lcd.print("WICKELMASCHINE 2");
      break;
    case 2: 
      lcd.setCursor(0, 1); lcd.print("FOTODREHTELLER 1");
      lcd.setCursor(0, 0); lcd.print("WICKELMASCHINE>2"); 
      break;
    case 3: 
      lcd.setCursor(0, 0); lcd.print("DREHTELLER    >3");
      lcd.setCursor(0, 1); lcd.print("-              4");
      break;
    case 4: 
      lcd.setCursor(0, 0); lcd.print("DREHTELLER     3");
      lcd.setCursor(0, 1); lcd.print("-             >4");
      break;
  }
  Serial.println(pos);
}
int getMenuValue() {
  static int pos=1;
  int lastClk = HIGH;
  while (digitalRead(ENCODER_ENTER)==LOW) { }
  showMenu(pos);
  while(true) {
    int newClk = digitalRead(ENCODER_CLK);
    if (newClk != lastClk) {
      // There was a change on the CLK pin
      lastClk = newClk;
      int dtValue = digitalRead(ENCODER_DT);
      if (newClk == LOW && dtValue == HIGH) {
        //Serial.println("Rotated clockwise ⏩  ");
        if (--pos < 1) pos = 1;
      }
      if (newClk == LOW && dtValue == LOW) {
        //Serial.println("Rotated counterclockwise ⏪  "); 
        if (++pos > 4) pos = 4;  
      }
      showMenu(pos);  
    } 
    if (digitalRead(ENCODER_ENTER)==LOW) {     
      while (digitalRead(ENCODER_ENTER)==LOW) { }
      delay(100);
      return(pos);
    }
  }
}
void loop() {
  switch(getMenuValue()) {
    case 1:
      Serial.println("Fotodrehteller");
      fotodrehteller();
      break;
    case 2:
      Serial.println("Wickelmaschine");
      wickelmaschine();
      break;
    case 3:
      Serial.println("Drehteller");
      drehteller();
      break;
    case 4:
      Serial.println("Frei");
      break;
  }
}
String status() {
  static String s;
  s  = (digitalRead(FUSSSCHALTER) ? "fs" : "FS "); s += " ";
  s += (digitalRead(FUSSTASTER) ? "ft" : "FT "); s += " ";
  s += (digitalRead(DREHRICHTUNG) ? "cw" : "CCW");
  return s;
}
//-----------------------------------------------------------------------------------
void fotodrehteller() {
//-----------------------------------------------------------------------------------
  long gesamtsteps     = 2000;
  long aufnahmen       = 10;
  long steps           = gesamtsteps/aufnahmen;
  long aufnahme        = 1;
  long pause           = 2000;
  long aufnahmePause   = 10000;
  long fs_aktiv = 0;
  while(true) { 
    digitalWrite(RELAY, LOW);  digitalWrite(13, LOW); 
    Serial.println("\nX-Ray Fotodrehteller");
    Serial.println("Version 1.0\n");
    showData("FOTODREHTELLER", "Version 1.0");
    delay(1000);
    getvalue("Fussschal.aktiv?", fs_aktiv, 0, 1, 1);
    getvalue("Aufnahmen? ", aufnahmen,   1, 2000,   1);
    getvalue("Ausloesezeit? ", pause,     500, 3000, 500);
    getvalue("Pause zw. Aufn.? ", aufnahmePause, 500, 30000, 500);
  
    showData("Start in 1 Minute", "");  
    delay(5000);
  
    if(digitalRead(FUSSSCHALTER) == LOW || digitalRead(FUSSTASTER) == LOW) {         
      while(aufnahme <= aufnahmen) {           
        Serial.print("Starte Aufnahme "); Serial.print(aufnahme); Serial.print(" / "); Serial.print(aufnahmen); Serial.print(" ");
        showData("Aufnahme", String(aufnahme)+" / "+ String(aufnahmen));
      
        digitalWrite(RELAY, HIGH); digitalWrite(13, HIGH); 
        delay(pause);
        digitalWrite(RELAY, LOW);  digitalWrite(13, LOW);
        
        Serial.print("ok  "); 
        lcd.setCursor(9, 1); lcd.print("ok     ");
        delay(800);
        Serial.println("wait...  ");
        lcd.setCursor(9, 1); lcd.print("wait..."); 
        delay(aufnahmePause);
        if(digitalRead(FUSSSCHALTER) == HIGH || digitalRead(FUSSTASTER) == LOW  || digitalRead(ENCODER_ENTER) == LOW ) {
          showData("Abbruch!", ""); 
          delay(800); 
          return;
        }
      
        aufnahme++;
        //stepper.move(digitalRead(DREHRICHTUNG)==LOW ? -steps : steps);
        //stepper.runToPosition();
      }
      Serial.println("Stop");
      lcd.setCursor(9, 1); lcd.print("STOP   "); 
      aufnahme = 1;  
      while (digitalRead(ENCODER_ENTER)==HIGH) { }
    }
  }
}
//-----------------------------------------------------------------------------------
void wickelmaschine() {
//-----------------------------------------------------------------------------------
  static int drehzahl = 1;
  long zeit;
  long fs_aktiv = 0;
  Serial.println("\nWickelmaschine");
  Serial.println("Version 1.0\n");
  
  lcd.clear();
  lcd.setCursor(0, 0); lcd.print(" WICKELMASCHINE");
  lcd.setCursor(0, 1); lcd.print("  Version 1.0");
  delay(1000);
  String s;
  
  getvalue("Fussschal.aktiv?", fs_aktiv, 0, 1, 1);
  showData("Drehzahl: " + String(drehzahl), status());
  
  stepper.setMaxSpeed(10000);                     // Set Max Speed of Stepper (Slower to get better accuracy)
  stepper.setAcceleration(1000);                  // Set Acceleration of Stepper
  
  while(true) {
    
    if (digitalRead(FUSSSCHALTER)==LOW || digitalRead(FUSSTASTER)==LOW) {
    
      int newClk = digitalRead(ENCODER_CLK);
      if (newClk != lastClk) {
        lastClk = newClk;
        int dtValue = digitalRead(ENCODER_DT);
        if (newClk == LOW && dtValue == HIGH) {
          //Serial.println("Rotated clockwise ⏩");
          if (++drehzahl > 1000) drehzahl = 10000;  
        }
        if (newClk == LOW && dtValue == LOW) {
          //Serial.println("Rotated counterclockwise ⏪");   
          if (--drehzahl < 0) drehzahl = 0;  
        }
       
        showData("Drehzahl: " + String(drehzahl), status());
     
      } 
      stepper.setSpeed( digitalRead(DREHRICHTUNG)==LOW ? drehzahl : -drehzahl );               
      stepper.runSpeed(); 
    }  else {
      stepper.setSpeed(0);  
      stepper.runSpeed(); 
    }
    if(micros() > zeit+1000000 ) {
      zeit = micros();
      showData("Drehzahl: " + String(drehzahl), status());
    }
    
  }
}
//-----------------------------------------------------------------------------------
void drehteller() {
//-----------------------------------------------------------------------------------
  static int drehzahl = 100;
  long fs_aktiv = 0;
  Serial.println("\nDrehteller");
  Serial.println("Version 1.0\n");
  
  lcd.clear();
  lcd.setCursor(0, 0); lcd.print("  DREHTELLER    ");
  lcd.setCursor(0, 1); lcd.print("  Version 1.0   ");
  delay(1000);
  
  stepper.setMaxSpeed(10000);                 // Set Max Speed of Stepper (Slower to get better accuracy)
  stepper.setAcceleration(1000);                  // Set Acceleration of Stepper
  String s;
  s  = (digitalRead(FUSSSCHALTER) ? "FSoff" : "FSon"); s += " ";
  s += (digitalRead(FUSSTASTER) ? "FToff" : "FTon"); s += " ";
  s += (digitalRead(DREHRICHTUNG) ? "DRoff" : "DRon");
  showData("Drehzahl: " + String(drehzahl), s);
  
  while(true) {
    
    if (digitalRead(FUSSSCHALTER)==LOW || digitalRead(FUSSTASTER)==LOW) {
    
      int newClk = digitalRead(ENCODER_CLK);
      if (newClk != lastClk) {
        lastClk = newClk;
        int dtValue = digitalRead(ENCODER_DT);
        if (newClk == LOW && dtValue == HIGH) {
          //Serial.println("Rotated clockwise ⏩");
          if (++drehzahl>1000) drehzahl=10000; 
        }
        if (newClk == LOW && dtValue == LOW) {
          //Serial.println("Rotated counterclockwise ⏪"); 
          if (--drehzahl<0) drehzahl=0; 
        }
        s = (digitalRead(FUSSSCHALTER) ? "FSoff" : "FSon"); s += " ";
        s += (digitalRead(FUSSTASTER) ? "FToff" : "FTon"); s += " ";
        s += (digitalRead(DREHRICHTUNG) ? "DRoff" : "DRon");
       
        showData("Drehzahl: " + String(drehzahl), s);
      } 
      if(digitalRead(FUSSSCHALTER) == HIGH || digitalRead(FUSSTASTER) == LOW  || digitalRead(ENCODER_ENTER) == LOW ) {
          showData("Abbruch!", ""); 
          delay(800); 
          return;
      }
      stepper.setSpeed( digitalRead(DREHRICHTUNG)==LOW ? -drehzahl : drehzahl );               
      stepper.runSpeed(); 
    }  else {
      stepper.setSpeed(0);  
      stepper.runSpeed(); 
    }
  }
}
//-----------------------------------------------------------------------------------
void showData(String s1, String s2) {
//-----------------------------------------------------------------------------------
  lcd.clear();
  lcd.setCursor(0, 0); lcd.print(s1);
  lcd.setCursor(0, 1); lcd.print(s2);
}
//-----------------------------------------------------------------------------------
void getvalue(String s1, long &value, long min_value, long max_value, long steps) {
//-----------------------------------------------------------------------------------
  showData(s1, String(value));
  while(true) {
    int newClk = digitalRead(ENCODER_CLK);
    if (newClk != lastClk) {
      // There was a change on the CLK pin
      lastClk = newClk;
      int dtValue = digitalRead(ENCODER_DT);
      if (newClk == LOW && dtValue == HIGH) {
        //Serial.println("Rotated clockwise ⏩  ");
        value = value + steps;
        if (value > max_value) value = max_value;  
      }
      if (newClk == LOW && dtValue == LOW) {
        // Serial.println("Rotated counterclockwise ⏪  "); 
        value = value - steps;
        if (value < min_value) value = min_value;
      }
      showData(s1, String(value));
    } 
    if (digitalRead(ENCODER_ENTER)==LOW) {     
      while (digitalRead(ENCODER_ENTER)==LOW) { }
      break;
    }
  }
}
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------