// WS
// Arduino Nano generator to drive the coil
// Panasonic Minas A5 200w motor, 1000p/r

int sensorPin = A0;                // Potentiometer input
int outPin = 10;                   // Oscillator output, Step signal (PUL)
int startPin = 2;                  // Generator start input
int speedPin = 9;                  // Input for selecting High and Low speed
int accPin = 4;                    // Input for slowing down the coil speed at the beginning and end of the layer
int a = 0;                         // Flag for f calculation
int tm = 5;                        // Acceleration time variable
unsigned int x = 0;                // Potentiometer value variable
unsigned int y = 0;                // Potentiometer value variable
unsigned int f = 1;                // Potentiometer value tracking variable
unsigned int speed = 0;            // Multiplier for High and Low speed
float acc = 1;                     // Divider for deceleration mode
unsigned long frq = 0;             // Frequency at the generator output
unsigned long previousMicros = 0;  // Cycle time variable
bool f_acc = 1;                    // Flag for one-time calculation of the divisor acc

void setup() {
  pinMode(outPin, OUTPUT);
  pinMode(startPin, INPUT);
  pinMode(speedPin, INPUT);
  pinMode(accPin, INPUT);
  digitalWrite(startPin, LOW);
  digitalWrite(speedPin, LOW);
  digitalWrite(accPin, LOW);
}

void loop() {
  // Stop spindle rotation at near-zero potentiometer values
  if (digitalRead(startPin) == HIGH && x > 2) {
    tone(10, frq);
  }
  if (x <= 2) {
    noTone(10);
    f = 1;
  }
  // Stop spindle rotation at near-zero potentiometer values

  y = analogRead(sensorPin);
  x = y / acc;
  frq = f * speed;

  if (digitalRead(startPin) == LOW) {
    noTone(10);
    f = 1;
    f_acc = 1;
  }
  
  if (digitalRead(speedPin) == HIGH) {
    speed = 60;  // Maximum spindle revolutions with 4:1 reduction and 1000p/r are equal to: f * speed / 4 / 1000p/r = 1024 * 60 / 4 / 1000 ~ 15 revolutions per second or 900RPM.
    tm = 200;    // Acceleration time variable. The smaller it is, the faster the spindle accelerates / decelerates
  } else {
    speed = 30;  // Maximum spindle revolutions with 4:1 reduction and 1000p/r are equal to: f * speed / 4 / 1000p/r = 1024 * 60 / 4 / 1000 ~ 15 revolutions per second or 900RPM.
    tm = 300;    // Acceleration time variable. The smaller it is, the faster the spindle accelerates / decelerates
  }

  // Calculate the divider for approximately the same deceleration speed
  if (digitalRead(accPin) == HIGH && f_acc == 1) {
    f_acc = 0;
    if (speed == 60 && y > 17) { acc = (y * speed) / 1000; }
    if (speed == 30 && y > 34) { acc = (y * speed) / 1000; }
  }
  if (digitalRead(accPin) == LOW) {
    acc = 1;
    f_acc = 1;
  }
  // Calculate the divider for approximately the same deceleration speed

  if (micros() - previousMicros >= tm && digitalRead(startPin) == HIGH) {
    if (f < x && a == 1) {
      f = f + 1;
    }

    if (f > x && a == 1) {
      f = f - 1;
    }

    if (f == x) {
      a = 0;
    } else {
      a = 1;
    }
    previousMicros = micros();
  }
}
