#include <math.h>

#define GESAMTSTEPS 2048000U 

//
// Struktur für Zahnrad Daten
struct stepDaten {
  unsigned long gesamtSteps;
  unsigned int zaehne;
  unsigned int zahnZaehler = 0;
  unsigned long stepsProZahn;
  unsigned long stepsErfolgt;
  int gesamtFehler;
  int korrekturWert;
  double korrekturStep;
};

struct stepDaten zahnrad;   // Modulglobal definieren

void setup() {

  Serial.begin(115200);


  for (unsigned int i = 350; i<=360; i++ ) {
    Serial.println("");
    Serial.println("---------------------");
    Serial.println("Nächstes Zahnrad");
    Serial.println("---------------------");
    Serial.println(""); 
    initZahnrad(i);
    Serial.print("Zahnrad Anzahl Zähne:");
    Serial.println(i);
    Serial.print("GesamtFehler      : ");
    Serial.println(zahnrad.gesamtFehler);
    Serial.print("Steps pro Zahn    : ");
    Serial.println(zahnrad.stepsProZahn);
    Serial.print("KorrekturStep     : ");
    Serial.println(zahnrad.korrekturStep);
    
    for (unsigned int i=0; i<zahnrad.zaehne;++i) {
      unsigned long stepsProZahn = naechsteSchrittFolge();
      zahnrad.stepsErfolgt += stepsProZahn;
      
      Serial.print("Summe Steps: ");
      Serial.print(zahnrad.stepsErfolgt);
      Serial.print(" Steps/Zahn: ");
      Serial.print(stepsProZahn);
      Serial.print(" zahnZaehler: ");
      Serial.println(zahnrad.zahnZaehler);
    }
  }
}

//
// Initialisieren der globalen Zahnrad Struktur
//
void initZahnrad(unsigned int zaehne) {
  zahnrad.gesamtSteps = GESAMTSTEPS;
  zahnrad.zaehne = zaehne;
  zahnrad.zahnZaehler = 0;
  zahnrad.stepsProZahn = round((double)zahnrad.gesamtSteps / zahnrad.zaehne);
  zahnrad.stepsErfolgt = 0;
  zahnrad.korrekturWert = 1;
  zahnrad.gesamtFehler = (long)zahnrad.stepsProZahn * zahnrad.zaehne - zahnrad.gesamtSteps;
  
  if (zahnrad.gesamtFehler) {
    if (zahnrad.gesamtFehler < 0) {
      zahnrad.gesamtFehler *= (-1);
      zahnrad.korrekturWert= -1;
    }
    zahnrad.korrekturStep = (double)zahnrad.gesamtSteps / zahnrad.gesamtFehler;
  } else {
    zahnrad.korrekturStep = 0;
  }
}

//
// Ermitteln der notwendigen Steps pro Zahnrad
// Bruchwerte werden durch "Korrektur-Steps" ausgeglichen
//
unsigned long naechsteSchrittFolge(void) {
  unsigned long erg;

  if (zahnrad.zaehne - zahnrad.zahnZaehler == 1) {
    erg = zahnrad.gesamtSteps - zahnrad.stepsErfolgt;
  } else if ( zahnrad.zahnZaehler && (zahnrad.stepsErfolgt % (unsigned long)zahnrad.korrekturStep < zahnrad.stepsProZahn) ) {
    erg = zahnrad.stepsProZahn - zahnrad.korrekturWert;
    Serial.println("Korrektur-Step-----");
  } else {
    erg = zahnrad.stepsProZahn;
  }
  zahnrad.zahnZaehler++;
  return erg;
}

void loop() {
  // put your main code here, to run repeatedly:

}