// WS
// Генератор Arduino Nano для привода катушки
// Двигатель Panasonic Minas A5 200w, 1000p/r

int sensorPin = A0;                // Вход потенциометра
int outPin = 10;                   // Выход генератора, сигнал Step (PUL)
int startPin = 2;                  // Вход старта генератора
int speedPin = 9;                  // Вход для выбора High и Low speed
int accPin = 4;                    // Вход для замедления скорости вращения катушки в начале и конце слоя
int a = 0;                         // Флаг для расчета f
int tm = 5;                        // Переменная времени ускорения
unsigned int x = 0;                // Переменная значения потенциометра
unsigned int y = 0;                // Переменная значения потенциометра
unsigned int f = 1;                // Переменная слежения значения потенциометра
unsigned int speed = 0;            // Множитель для High и Low speed
float acc = 1;                     // Делитель для режима замедления
unsigned long frq = 0;             // Частота на выходе генератора
unsigned long previousMicros = 0;  // Переменная времени цикла
bool f_acc = 1;                    // Флаг для одноразового расчета делителя 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() {
  // Остановка вращения шпинделя при околонулевых значениях потенциометра
  if (digitalRead(startPin) == HIGH && x > 2) {
    tone(10, frq);
  }
  if (x <= 2) {
    noTone(10);
    f = 1;
  }
  // Остановка вращения шпинделя при околонулевых значениях потенциометра

  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;  // Максимальные обороты шпинделя с учетом редукции 4:1 и кол-вом импульсов на оборот мотра 1000p/r равны: f * speed / 4 / 1000p/r = 1024 * 60 / 4 / 1000 ~ 15 оборотов в секунду или 900RPM
    tm = 200;    // Переменная времени ускорения. Чем меньше, тем быстрее разгон / торможение шпинделя
  } else {
    speed = 30;  // Максимальные обороты шпинделя с учетом редукции 4:1 и кол-вом импульсов на оборот мотра 1000p/r равны: f * speed / 4 / 1000p/r = 1024 * 30 / 4 / 1000 ~ 7.5 оборотов в секунду или 450RPM
    tm = 300;    // Переменная времени ускорения. Чем меньше, тем быстрее разгон / торможение шпинделя
  }

  // Расчет делителя для приблизительно одинаковой скорости замедления
  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;
  }
  // Расчет делителя для приблизительно одинаковой скорости замедления

  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();
  }
}
