Fehlersuche bei einem Arduino Projekt

Probiere es doch einfach aus.
Nimm einen funktionierenden Code, baue 2 Fehler rein (einen den der Compiler merkt, falsch geschriebener Variablennamen und einen logischen, z.B. Indexüberschreitung in einem Array. Ich bin ja nicht mal so böse, die Indexüberschreitung per Pointer-Berechnung zu machen) und lass ChatGPT drauf los.
Wir sind sehr auf Deinen Erfahrungsbericht gespannt.

Gruß Tommy

So ich habe es angetestet.
chatGPT 4.0 kostet Geld also habe ich chatGPT 3.5 genommen

hier der "Gesprächsverlauf"

ch möchte das du in einenm C++-Code den Fehler findest

ChatGPT:

Natürlich, ich helfe dir gern beim Finden eines Fehlers in deinem C++-Code! Bitte teile den Code oder beschreibe den Fehler, damit ich dir gezielt weiterhelfen kann.

Du:

//------------------------------------------ // Motor vorwärts //------------------------------------------ void MotorVor(int Speed) { #if myDRIVE int SpeedOutput; SpeedOutput = 75 + Speed * 20; //erst ab ca 100 dreht der 12V Gleichstrommmotor analogWrite(MotorEnable_PIN, SpeedOutput); digitalWrite(Motorsteuerung_PIN1, HIGH); //Motor läuft vorwärts digitalWrite(Motorsteuerung_PIN2, LOW); #endif #if myDEBUG Serial.print(F("Motor vorwärts- mit ")); // Serial.print(SpeedOutput / 255 * 100); // Serial.println(F("%")); #endif }

ChatGPT:

Der C++-Code sieht grundsätzlich gut aus, aber es gibt ein paar potenzielle Probleme, die das erwartete Verhalten beeinflussen könnten. Schauen wir uns einige mögliche Fehlerquellen an:

  1. Berechnung von SpeedOutput:

cpp

Code kopieren

SpeedOutput = 75 + Speed * 20;

Hier wird SpeedOutput auf einen Wert gesetzt, der von Speed abhängt. Die Berechnung an sich könnte jedoch außerhalb des Bereichs von analogWrite (0 bis 255) liegen. Wenn Speed zu groß ist, könnte SpeedOutput Werte über 255 annehmen, was analogWrite zu einem unvorhersehbaren Verhalten führt.Lösung: Stelle sicher, dass der Wert auf den Bereich 0 bis 255 begrenzt wird, z.B. mit constrain():

cpp

Code kopieren

SpeedOutput = constrain(75 + Speed * 20, 0, 255);
  1. Fehlende Definition von myDRIVE und myDEBUG: Der Code verwendet bedingte Kompilation mit #if myDRIVE und #if myDEBUG. Wenn myDRIVE oder myDEBUG nicht definiert sind, wird der Code in den Blöcken ignoriert. Vergewissere dich, dass #define myDRIVE oder #define myDEBUG vor dem Code gesetzt ist, falls du die entsprechenden Funktionen aktivieren möchtest.
  2. Serial-Ausgabe der Geschwindigkeit (auskommentierter Code): Im myDEBUG-Block ist die Zeile, die den prozentualen Wert der Geschwindigkeit berechnen soll, auskommentiert:

cpp

Code kopieren

// Serial.print(SpeedOutput / 255 * 100);

Das könnte zu ungenauen Ergebnissen führen, da SpeedOutput / 255 * 100 aufgrund von Ganzzahldivision immer 0 ergibt, solange SpeedOutput kleiner als 255 ist. Verwende stattdessen:

cpp

Code kopieren

Serial.print((SpeedOutput * 100) / 255);

oder

cpp

Code kopieren

Serial.print((SpeedOutput / 255.0) * 100);

Dadurch erhältst du eine genaue Prozentanzeige.
4. Mögliche Fehlerquelle bei der Motorsteuerung: Vergewissere dich, dass die Pins MotorEnable_PIN, Motorsteuerung_PIN1, und Motorsteuerung_PIN2 korrekt initialisiert und definiert sind. Ein Fehler in der Pin-Definition könnte verhindern, dass der Motor wie erwartet läuft.

Falls du noch weitere Fragen oder Probleme hast, lass es mich gerne wissen!

Für zusätzliche Chat-Alternativen: hix.ai/chat.

Du:

Hier ist eine neue code-version. Bitte analysiere die Cde-Version auf Fehler

ChatGPT:

Gerne, poste einfach die neue Code-Version, und ich helfe dir bei der Fehlersuche!

Du:

Wie lange darf die längste eingabe sein die du akzeptierst?

ChatGPT:

Es gibt keine festgelegte maximale Länge, aber kürzere Abschnitte (idealerweise unter 500 Zeilen) sind einfacher und schneller zu analysieren. Falls der Code sehr lang ist, könntest du ihn auch in Teilen senden.

Ich helfe dir gerne, also sende einfach den Code, und wir sehen, wie wir am besten vorgehen!

Du:

Du hast schon zweimal gemeldet dass die Eingabe zu lang ist. Deswegen möchte ich von DIR wissen wie ich die eingabe am besten machen soll

ChatGPT:

Vielen Dank für die Klarstellung! Hier ist ein praktischer Ansatz, um effizient bei einer längeren C++-Fehlersuche vorzugehen:

  1. Code in Abschnitten senden: Falls möglich, teile den Code in logische Abschnitte auf (z. B. Funktionen, Klassen, oder einzelne Module), und sende diese nacheinander. Ich kann dir dann zu jedem Abschnitt eine Rückmeldung geben.
  2. Zentrale Problemstellen markieren: Falls du weißt, wo sich das Problem vermutlich befindet, schicke nur den relevanten Teil und beschreibe kurz den Kontext. Zum Beispiel: „Die Funktion MotorVor verursacht einen Fehler“ oder „Das Problem scheint im Setup-Bereich zu liegen.“
  3. Aussagekräftige Fehlermeldungen beifügen: Falls es konkrete Fehlermeldungen oder Warnungen gibt, kopiere diese mit in die Eingabe. Das hilft mir zu verstehen, was genau schiefläuft.

Ich freue mich auf deine nächste Nachricht!

Du:

Ich glaube nicht dass es ausreicht nur einen Teil des Codes zu senden. Wie kann ich dir einen Code der insgesamt 2132 Zeilen hat übermitteln?

ChatGPT:

Für einen Code dieser Länge wäre es am effizientesten, wenn du ihn auf einer externen Plattform hochlädst und mir den Link mitteilst. Hier sind einige Plattformen, die häufig für den Austausch von Code genutzt werden:

  1. GitHub Gist: Lade den Code als „Gist“ hoch. Du kannst auch festlegen, ob es öffentlich oder privat sein soll.
  1. Pastebin: Eine einfache Plattform zum Hochladen von Code und Text. Du kannst den Link dann hier teilen.
  1. Google Drive oder Dropbox: Speichere den Code als .cpp- oder .txt-Datei und erstelle einen freigegebenen Link. Achte darauf, dass die Berechtigungen zum Anzeigen für alle gesetzt sind, die den Link haben.
  2. Private Repositories: Wenn der Code sensibel ist und du ein GitHub- oder GitLab-Konto hast, könntest du den gesamten Code in einem privaten Repository hochladen und gezielt freigeben.

Lass mich wissen, wenn du Unterstützung beim Hochladen benötigst!

Du:

#define mySYSTEM 1 // 1= Arduino Every / 0 = ESP32#defin - Pastebin.com

ChatGPT:

1 Website durchsucht

Ich habe den Code geprüft und einige potenzielle Fehlerquellen gefunden:

  1. Bedingte Kompilierung (#if-Blöcke): Es gibt viele #if mySYSTEM, #if myDRIVE und #if useOTA-Blöcke. Stelle sicher, dass diese Makros korrekt definiert sind, da Teile des Codes sonst ausgelassen werden.
  2. Berechnung von PWM-Werten: Die PWM-Einstellungen könnten Plattformprobleme verursachen. Für ESP32 wird ledcWrite verwendet, aber auf einem Arduino könnte analogWrite nötig sein.
  3. Serial-Ausgabe in #if myDEBUG: Einige Serial.print-Aufrufe könnten bei Problemen hilfreich sein, falls Debugging aktiviert ist.

Weitere Fragen oder Details?

Du:

In einem der Untermenüs funktioniert die Ansteuerung des Schrittmotors nicht. In welchem Untermenü ist das und was muss am Code geändert werden damit die Schrittmotorsteuerung über den Drehenocder funktioniert?

ChatGPT:

Um den Schrittmotor in einem bestimmten Untermenü über den Drehencoder anzusteuern, überprüfe, ob in diesem Menü der Code zur Steuerung des Schrittmotors und das Einlesen des Drehencoders korrekt integriert sind. Häufige Ursachen für das Nicht-Ansprechen könnten sein:

  1. Falsches Menü-Erkennen: Stelle sicher, dass der Menücode den Drehencoder-Input im richtigen Kontext verarbeitet. Prüfe die Menübedingung oder Auswahlvariable, ob der Schrittmotorcode hier aktiviert ist.
  2. Fehlende Encoder-Abfrage: Der Code sollte im Menüabschnitt zyklisch die Encoderwerte lesen und die Position aktualisieren. Falls dies fehlt, ergänze eine Schleife oder Bedingung, die den Encoder kontinuierlich abfragt.
  3. Initialisierung und Freigabe: Stelle sicher, dass der Schrittmotor-Setup für den Menüpunkt initialisiert ist, und dass alle zugehörigen Pins oder Variablen (z. B. myDRIVE oder Motor_PIN) gesetzt sind.

Falls du spezifische Codeabschnitte zeigen kannst, die für den Schrittmotor und den Drehencoder verantwortlich sind, könnte ich präziser auf die Anpassungen eingehen.

Du:

Es handelt sich um die function PositionAnfahren()

ChatGPT:

In der Funktion PositionAnfahren() könnte der Schrittmotor eventuell nicht richtig auf den Drehencoder reagieren, wenn bestimmte Bedingungen oder Ansteuerungen fehlen. Hier sind Schritte, die du überprüfen solltest:

  1. Encoder-Input lesen: Stelle sicher, dass die Funktion PositionAnfahren() den Encoderwert regelmäßig abfragt und aktualisiert, um die gewünschte Position des Schrittmotors zu ermitteln.
  2. Schrittmotorsteuerung implementieren: Die Steuerung des Schrittmotors sollte innerhalb von PositionAnfahren() in Abhängigkeit der Encoder-Änderungen erfolgen. Beispielsweise:
  • Prüfe, ob der Encoderwert eine Bewegung des Schrittmotors erforderlich macht.
  • Rufe dann die notwendigen Motoransteuerungsbefehle auf, wie etwa Schritte und Richtung anpassen.
  1. Aktive Menüprüfung: Verifiziere, dass PositionAnfahren() nur dann aufgerufen wird, wenn das entsprechende Menü aktiv ist. Möglicherweise ist ein bedingter Block nötig, um die Funktion nur in diesem Menü auszuführen.
  2. Motoraktivierung sicherstellen: Kontrolliere, ob der Schrittmotor in dieser Funktion ordnungsgemäß aktiviert und angesteuert wird (z. B. über analogWrite für die Motor-Pins oder entsprechende Libraries).

Falls du spezifischen Code zur Funktion PositionAnfahren() zeigen kannst, kann ich gezieltere Hinweise geben!

Du:

MotorVor(neuePositionSmallRotary); for (int i = 1; i <= neuePositionSmallRotary; i++) { SpeedAnzeige = SpeedAnzeige + ">"; }

ChatGPT:

In deinem Code gibt es einige Punkte, die möglicherweise das Problem verursachen könnten:

  1. Ansteuerung des Schrittmotors mit MotorVor(neuePositionSmallRotary);:
  • Verifiziere, dass MotorVor() die Funktion für die Schrittmotorsteuerung korrekt aufruft und die Anweisung neuePositionSmallRotary als Zielposition interpretiert.
  • Falls MotorVor für einen Schrittmotor vorgesehen ist, stelle sicher, dass sie entsprechend programmiert ist, um Schritte statt kontinuierlicher Drehzahländerungen auszuführen, da Schrittmotoren häufig eine spezifische Anzahl an Schritten für die Zielposition benötigen.
  1. For-Schleife für SpeedAnzeige:
  • Die Schleife erstellt eine Art Fortschrittsanzeige, indem sie ">" wiederholt hinzufügt. Stelle sicher, dass neuePositionSmallRotary hier ein sinnvoller Wert ist, damit SpeedAnzeige korrekt und nicht übermäßig oft aktualisiert wird.
  1. Integriere Drehencoder-Updates in PositionAnfahren():
  • Überprüfe, ob die Drehencoder-Werte innerhalb dieser Funktion kontinuierlich abgefragt und verarbeitet werden. Wenn neuePositionSmallRotary nur einmal beim Aufruf gesetzt wird, verpasst der Code möglicherweise nachfolgende Encoder-Änderungen.
  1. Rückmeldungen und Debugging:
  • Füge Testausgaben (Serial.print) in die Schleife oder MotorVor ein, um sicherzustellen, dass der Code die erwartete Position ansteuert und dass PositionAnfahren() die richtigen Werte für den Schrittmotor setzt.

Eine detaillierte Überprüfung der Funktion MotorVor und eventueller Änderungen zur Encoder-Verarbeitung kann ebenfalls hilfreich sein.

Mein Fazit: Zum Teil hilfreich aber keinwegs Fehler gezielt gefunden und korrigiert .

Danke für Deinen Test.
Also viel Lärm um nichts.

Gruß Tommy

Sorry, wollte keine Grundsatz Diskussion anfangen. Hab gedacht es wäre eine Möglichkeit den Fehler zu finden. Ich schaffe es nicht ...

Hallo zusammen,

ich bin mit meinem Quellcode ein wenig weiter gekommen. Ich habe den Test mit dem Arduino Nano noch mal aufgebaut und im Quellcode die Servos rausgenommen, damit ich ihn hochladen kann.

/* Universalcode für den Ettimandl (ESP32)  und den EtVonSchleck (Arduino Nano)

  Copyright (C) 2021 Jeremias Bruker
  2021-01-03 Jeremias Bruker| Den Code kann jeder frei verwenden, ändern und hochladen wo er will,
                              solange er nicht seinen eigenen Namen drüber setzt, oder diesen kommerziell verwertet, beispielsweise
                              indem Etikettiermaschinen mit diesem Code versehen und verkauft werden.

  2021-01-03 Jeremias Bruker | initial version,
  2021-01-09 Martin Zahn     | Unterstützung ESP32+Schrittmotor hinzugefügt
  2021-01-16 Jeremias Bruker | Wahl zwischen Schrittmotor und Gleichstrommotor per myDRIVE
  2021-01-21 Johannes Kuder  | Ultraschallsensor anstatt Näherungssensor per mySensor
  2021-01-28 Jeremias Bruker | Etikettenlänge kann während des Labelvorgangs mit dem SmallRotary geändert werden - wird mit E+ oder E- angezeigt
                             | Stepperlaufrichtung kann per define angepasst werden
  2021-01-29 Johannes Kuder  | OTA-Funktionalität für ESP32
  2021-01-29 Jeremias Bruker | Grafik auf U8g2 umgestellt
  2021-02-03 Jeremias Bruker | Fußschalter implementiert
  2021-02-20 Jeremias Bruker | Große Werte können im Menü parallel mit Small und BigRotary verändert werden werden
  2021-02-23 Jeremias Bruker | Die Spannung bzw. Drehzahl des Lüfters kann nun per Software eingestellt werden
  2021-02-25 Jeremias Bruker | Gemeinsame EncoderLib (für Every und ESP32) & Abbruch über Rotary-Button während der Trockenzeit*/


//----------------------------------------------------------------
// Allgemeine Konfiguration DEBUG/GRAFIK/System Information
//----------------------------------------------------------------
#define mySYSTEM            1            // 1= Arduino Every / 0 = ESP32
#define myDEBUG             1            // 0 = Debug via Serial Monitor
#define myDRIVE             0            // 1 = Gleichstrommotor mit H-Brücke 0 = Schrittmotor
#define mySENSOR            0            // 1 = Ultraschallsensor 0 = kap. Näherungssensor
//---------------------------
#define useOTA              0            // 1 = OTA Funktionalität nutzen
#if useOTA
const char* ssid = "";
const char* password = "";
#endif
//---------------------------
#define StepperLaufrichtung 0           // 0 für senkrechten Aufbau 1 für waagerechten Aufbau
//----------------------------------------------------------------

const char Version[] = "2.6"; //02.03.2021

#if mySYSTEM
//----------------------------------------------------------------
// Pinbelegung Arduino Nano
//----------------------------------------------------------------
// Rotary Encoder klein für Menü-Steuerung
#define SmallRotary_PIN_SW               A0

#define TRIG_PIN                         A1    // falls Ultraschallsensor im Einsatz

#define Buzzer_PIN                       A2
// I2C-Display                           A4   // SDA
// I2C-Display                           A5   // SCL
#define FussSchalter                     A6
#define NaeherungsSensor_PIN             A7    // Ausgang Näherungsschalter oder Ausgang Ultraschallsensor
// Serial                                 0
// Serial                                 1
#define RotaryBig_PIN_A                   2
#define RotaryBig_PIN_B                   3

#define SmallRotary_PIN_A                 4
#define SmallRotary_PIN_B                 5

#define MiniLuefterEnable_PIN             6 //Speed PWM für Lüfter am Gleichstrommotorausgang B
#define MiniLuefter_PIN1                  7 //PinA Motorsteuerung für Lüfter 

#define Motorsteuerung_PIN1               8    // Schrittmotor-->  Motorsteuerung_PIN1 = Step   oder Gleichstrommotor--> Pin A
#define Motorsteuerung_PIN2               9    // Schrittmotor-->  Motorsteuerung_PIN2 = Dir    oder Gleichstrommotor--> Pin B
#define MotorEnable_PIN                   10    // Schrittmotor-->  Enable-Pin                    oder Gleichstrommotor--> Speed PWM MotorA

//----------------------------------------------------------------
#else
//----------------------------------------------------------------
// Pinbelegung ESP32
//----------------------------------------------------------------
#define MotorEnable_PIN                  14    // Schrittmotor-->  Enable-Pin    oder Gleichstrommotor--> Speed PWM
#define Motorsteuerung_PIN1              33    // Schrittmotor-->  Step          oder Gleichstrommotor--> Pin A
#define Motorsteuerung_PIN2              32    // Schrittmotor-->  Dir           oder Gleichstrommotor--> Pin B

// Rotary Encoder (Inkrementaler Drehgeber für Etikettenposition)
// Grün = A-Phase, Weiß = B-Phase, Rot = Vcc-Leistung +, Schwarz = V0
#define RotaryBig_PIN_A                  16      // A-Phase
#define RotaryBig_PIN_B                  17      // B-Phase


// Rotary Encoder klein für Menü-Steuerung
#define SmallRotary_PIN_SW               13
#define SmallRotary_PIN_A                35 // DT
#define SmallRotary_PIN_B                34 // CLK


// Servo
#define SERVO1_PIN                       19     // Servo für Stempel
#define SERVO2_PIN                       26     // Stempelposition 

// I2C-Display                           21: SDA
// I2C-Display                           22: SCL

// SPI-Display                           18: CLK
// SPI-Display                           19: MISO
// SPI-Display                           23: MOSI
// SPI-Display                            5: CS

#define Buzzer_PIN                       25
#define MiniLuefter_PIN1                  2
#define MiniLuefterEnable_PIN             18 //Speed PWM für Lüfter am Gleichstrommotorausgang B

// Start-Sensor
#define NaeherungsSensor_PIN             23  // Im Fall Ultraschallsensor: ECHO Pin

#define TRIG_PIN                          4  // falls Ultraschallsensor im Einsatz

#define FussSchalter                      5



// OTA
#if useOTA
#include <WiFi.h>
#endif
#if useOTA
#include <ESPmDNS.h>
#endif
#if useOTA
#include <WiFiUdp.h>
#endif
#if useOTA
#include <ArduinoOTA.h>
#endif
#endif
//----------------------------------------------------------------

//----------------------------------------------------------------
// gemeinsame Libs (Nano und ESP)
//----------------------------------------------------------------
#include <Arduino.h>
#include <Encoder.h>          // https://github.com/PaulStoffregen/Encoder
#if !myDRIVE
#include <AccelStepper.h> // für Schrittmotor. https://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html
#endif
//----------------------------------------------------------------


//----------------------------------------------------------------
// diverse ARduino Libs
//----------------------------------------------------------------
#if mySYSTEM
#include <EEPROM.h>           // aus dem Bibliotheksverwalter
#endif


//----------------------------------------------------------------


//----------------------------------------------------------------
// diverse ESP32 Libs
//----------------------------------------------------------------
#if !mySYSTEM
#include <Preferences.h>  // für EEPROM
#endif

#if !mySYSTEM
#include <ESP32Servo.h>
#endif
//----------------------------------------------------------------

//----------------------------------------------------------------
// DISPLAY
//----------------------------------------------------------------
#include <Wire.h>             // aus dem Bibliotheksverwalter 
#include <U8g2lib.h>      // aus dem Arduino-Bibliotheksverwalter
#if mySYSTEM
//OLED 1.3 128*64 Breite Version -------------------------------------------------------------------
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); //128*64 BreiteVersion
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
#else
//2.42 Oled 128*64 Große Version -------------------------------------------------------------------
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
#endif

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
//----------------------------------------------------------------



//----------------------------------------------------------------
// Konfiguration SmallRotary
//----------------------------------------------------------------
Encoder SmallRotary(SmallRotary_PIN_A, SmallRotary_PIN_B);

int LeseSmallRotaryWert()
{
  int Wert;
  Wert = SmallRotary.read() / 4;
  return Wert;
}

void SetzeSmallRotaryWert(int Wert)
{
  SmallRotary.write(Wert * 4);
}

//----------------------------------------------------------------


//----------------------------------------------------------------
// Konfiguration Bigrotary
//----------------------------------------------------------------
Encoder BigRotary(RotaryBig_PIN_A, RotaryBig_PIN_B);

int LeseBigRotaryWert()
{
  int Wert;
  Wert = BigRotary.read();
  return Wert;
}

void SetzeBigRotaryWert(int Wert)
{
  BigRotary.write(Wert);
}
//----------------------------------------------------------------


//----------------------------------------------------------------
// Konfiguration Schrittmotor
//----------------------------------------------------------------
#if !myDRIVE
AccelStepper stepper(1, Motorsteuerung_PIN1, Motorsteuerung_PIN2); // Motortyp, Motorsteuerung_PIN1, Motorsteuerung_PIN2
#endif


//----------------------------------------------------------------
// Konfiguration EEPROM ESP32
//----------------------------------------------------------------
#if !mySYSTEM
Preferences preferences;
#endif



//----------------------------------------------------------------
// Konfiguration Datentransfer via Serial / FTDI / USB
//----------------------------------------------------------------
#define Serial_Baudrate 115200
//----------------------------------------------------------------

//----------------------------------------------------------------
// Konfiguration Buzzer
//----------------------------------------------------------------
#define BUZZER_SHORT   1
#define BUZZER_LONG    2
#define BUZZER_SUCCESS 3
#define BUZZER_ERROR   4
//----------------------------------------------------------------

//----------------------------------------------------------------
// Variablen
//----------------------------------------------------------------

int hand_steps = 400; // variable Schrittweite, original 40
unsigned int n_pings = 10; // Anzahl Einzelmessungen Ultraschallsensor zur Mittelwertbildung
float Schwelle = 2;    // Grenzabstand in cm an dem Glas erkannt wird


volatile int PositionBigRotary;
int altePositionBigRotary   = 0;    // Def der "alten" RotaryPosition
volatile int PositionSmallRotary;
int altePositionSmallRotary = 0;  // Def der "alten" RotaryPosition
int neuePositionSmallRotary = 0;  // Def der "alten" RotaryPosition
bool altePositionNaeherung = HIGH;//kein Glas aufgelegt
long Fortschritt;
long AlterFortschritt = 0;
bool EinWertNeu = LOW; //Anzeiger, ob EEPROM beschrieben werden soll
bool HandModus = LOW;
char  Ausgabe[30];

//Menüwerte
unsigned int AktuellesEtikett = 0;
unsigned int Etikettenlaenge[] = {500 , 1000 , 2000 };
unsigned int ZeitBisDatumDruck[] = {250 , 500 , 1000 };
unsigned int Counter[] = {0 , 0 , 0}; // Anzahl der
bool MitBuzzer[] = {LOW, LOW, LOW}; //Soll der Buzzer aktiv sein
bool MitFuss[] = {LOW, LOW, LOW}; //Soll der Fußschalter aktiv sein
bool MitDruck[] = {LOW, LOW, LOW}; //Soll überhaupt auf das Etikett gedruckt werden?
unsigned int DruckTrockenZeit[]    = {1, 1, 1}; //Sekunden nach dem Druck warten, damit die Tinte trocknen kann
unsigned int MitLuft[]  = {0, 0, 0}; // Spannung des Lüfters in %(Versorgungsspannung Motor) 0 = inaktiv 10 = 100 %


// Schrittmotoreinstellungen
unsigned int MaxSpeed[] = {10, 10, 10};                   // Schrittmotor Maximalgeschwindigkeit, wird im Code mit 100 multipliziert
unsigned int Acceleration[] = {5, 5, 5};                  // Schrittmotor Beschleunigung (höher = schneller)  wird im Code mit 100 multipliziert
//int Speed = 1000;                                         // Schrittmotor Geschwindigkeit für Handbetrieb
int LastSteps = 20000;                      // Gefahrene Schritte des Schrittmotors beim letzten Etikettiervorgang
int LastStepsPrint = 18000;                 // Gefahrene Schritte des Schrittmotors beim letzten Etikettiervorgang
#if myDRIVE
int DriveJump = 2; //Menüpunkte vom Schrittmotor ausblenden
#else
int DriveJump = 0;
#endif

//################################################# SETUP #############################################

void setup() {
#if myDEBUG
  Serial.begin(Serial_Baudrate);
  Serial.println(Version);
#endif
  delay(100);

  ReadMem(); //Werte aus EE_Prom einlesen


  Wire.begin();
  //Wire.setClock(400000L);

  u8g2.begin();
  u8g2.enableUTF8Print();

  print_logo();


#if !mySYSTEM
  // OTA -------------------------------------------------
#if useOTA
#if myDEBUG
  Serial.println(F("OTA") );
#endif
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println( F("Reboot") );
    delay(5000);
    ESP.restart();
  }

  WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE); // required to set hostname properly
#if mySYSTEM
  WiFi.setHostname("EtVomSchleck");
#else
  WiFi.setHostname("EttiMandl");
#endif

  ArduinoOTA
  .onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH)
      type = "sketch";
    else // U_SPIFFS
      type = "filesystem";

#if myDEBUG
    Serial.println( F("update" + type) );
#endif

    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_courB12_tf);
    u8g2.setCursor(1, 15);
    u8g2.print("Receiving");
    u8g2.setCursor(1, 35);
    u8g2.print("OTA Update");
    u8g2.sendBuffer();
  })
  .onEnd([]() {
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_courB12_tf);
    u8g2.setCursor(1, 15);
    u8g2.print("Receiving");
    u8g2.setCursor(1, 35);
    u8g2.print("OTA Update");
    u8g2.setCursor(1, 55);
    u8g2.print("Done !");
    u8g2.sendBuffer();
  })
  .onProgress([](unsigned int progress, unsigned int total) {
#if myDEBUG
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
#endif
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_courB12_tf);
    u8g2.setCursor(1, 15);
    u8g2.print("Receiving");
    u8g2.setCursor(1, 35);
    u8g2.print("OTA Update");
    u8g2.setCursor(1, 55);
    u8g2.printf("Progress: %u%%\r", (progress / (total / 100)));
    u8g2.sendBuffer();
  })
  .onError([](ota_error_t error) {
#if myDEBUG
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR)
      Serial.println( F("NoAuth") );
    else if (error == OTA_BEGIN_ERROR)
      Serial.println( F("BeginFail"));
    else if (error == OTA_CONNECT_ERROR)
      Serial.println( F("Con.Fail") );
    else if (error == OTA_RECEIVE_ERROR)
      Serial.println( F("RcvFail") );
    else if (error == OTA_END_ERROR)
      Serial.println( F("EndFail") );
#endif
  });

  ArduinoOTA.begin();

#if myDEBUG
  Serial.println( F("OK") );
  Serial.print( F("IP") );
  Serial.println(WiFi.localIP());
#endif
#endif

  // Ende OTA
#endif

  //----------------------------------------------------------------
  //Setup Fußschalter
  //----------------------------------------------------------------
  pinMode(FussSchalter, INPUT_PULLUP);
  //----------------------------------------------------------------



#if myDRIVE
  //----------------------------------------------------------------
  //Setup Motorsteuerung
  //----------------------------------------------------------------

  digitalWrite(Motorsteuerung_PIN1, LOW);
  digitalWrite(Motorsteuerung_PIN2, LOW);
  pinMode(Motorsteuerung_PIN1, OUTPUT);
  pinMode(Motorsteuerung_PIN2, OUTPUT);
  pinMode(MotorEnable_PIN, OUTPUT);
  digitalWrite(MotorEnable_PIN, HIGH); // Kann erstmal aktiv sein
  //----------------------------------------------------------------
#else
  //----------------------------------------------------------------
  //Setup Schrittmotorsteuerung
  //----------------------------------------------------------------
  stepper.setEnablePin(MotorEnable_PIN);
  stepper.setPinsInverted(StepperLaufrichtung, false, true); // directioninvert, stepinvert, enableinvert
  stepper.setMaxSpeed(MaxSpeed[AktuellesEtikett] * 100); // Maximale Geschwindigkeit
  //stepper.setAcceleration(Acceleration[AktuellesEtikett]*100); // Beschleunigung
  //stepper.setCurrentPosition(0);
#endif
  //----------------------------------------------------------------


  //----------------------------------------------------------------
  // Setup MiniLuefter
  //----------------------------------------------------------------
  pinMode(MiniLuefter_PIN1, OUTPUT);
  pinMode(MiniLuefterEnable_PIN, OUTPUT);
  digitalWrite(MiniLuefter_PIN1, LOW);
#if mySYSTEM
  analogWrite(MiniLuefterEnable_PIN, MitLuft[AktuellesEtikett] * 25);
#else
  ledcSetup(0, 5000, 8);
  ledcAttachPin(MiniLuefterEnable_PIN, 0);
  ledcWrite(0, 125);
#endif

  //----------------------------------------------------------------


  //----------------------------------------------------------------
  //Setup MiniRotarySwitch
  //----------------------------------------------------------------
  pinMode(SmallRotary_PIN_SW, INPUT);
  //----------------------------------------------------------------



  //----------------------------------------------------------------
  // Konfiguration Buzzer
  //----------------------------------------------------------------
  pinMode(Buzzer_PIN, OUTPUT);
  if (MitBuzzer[0] || MitBuzzer[1] || MitBuzzer[2])
  {
    buzzer(BUZZER_LONG);
  }
  //----------------------------------------------------------------


  //----------------------------------------------------------------
  // Konfiguration Ultraschallsensor
  //----------------------------------------------------------------
  pinMode(TRIG_PIN, OUTPUT);

}   //-----------SETUP ENDE----------------------------------------------------------------



void loop()
{
#if !mySYSTEM
#if useOTA
  ArduinoOTA.handle();
#endif
#endif

  Einstellungsmenue(); //Mit RotarySwitch ins Menü rein
  Handsteuerung(); // Mit RotaryDrehen ---> Motor Vor und Motor zurück

  //------------------------------------------------------------
  // BEREIT-MODUS  Abfrage Näherungsschalter und eventuell Etikettieren!
  //------------------------------------------------------------

#if mySENSOR // Ultraschallsensor
  bool neuePositionNaeherung = !Ultraschallsensor(Schwelle);

#else // Abstandssensor
  bool neuePositionNaeherung = digitalRead(NaeherungsSensor_PIN);
#endif

  if (MitFuss[AktuellesEtikett])
  {
    if (!digitalRead(FussSchalter))  // Fußschalter wurde eventuell gedrückt
    {
      buzzer(BUZZER_LONG);
      if (!digitalRead(FussSchalter))  // Fußschalter wurde gedrückt !
      {
#if myDEBUG
        Serial.println(F("FußSPress"));
#endif
        Etikettieren();
        for (int i = 0; i <= 3; i++)
        {
          buzzer(BUZZER_LONG);
          delay(200);
        }
      }
    }
  }
  else if (neuePositionNaeherung != altePositionNaeherung)  // Sollte die neue Position ungleich der alten sein...
  {
    altePositionNaeherung = neuePositionNaeherung;
    if (neuePositionNaeherung == LOW)
    {
      buzzer(BUZZER_LONG);
#if myDEBUG
      Serial.println( F("GlasDetect") );
#endif
      if (neuePositionNaeherung == LOW) Etikettieren(); // Falls Glas immer noch liegt
      for (int i = 0; i <= 2; i++)
      {
        buzzer(BUZZER_SHORT);
        delay(200);
      }

    }
  }

}//ENDE LOOP-------------------------------------------------------



//----------------------------------------------------------------
// Etikettiervorgang
//----------------------------------------------------------------
void Etikettieren()
{
  SetzeBigRotaryWert(0); //RESET
  PositionBigRotary = 0;
  bool Gedruckt = LOW;
  int LiveLaengenWert = 0;

  DisplayEtikettieren(0); //Start mit 0 Prozent

#if !myDRIVE // Für Schrittmotor

  stepper.enableOutputs();
  stepper.setCurrentPosition(0);
  stepper.setAcceleration(Acceleration[AktuellesEtikett] * 100); // ggf brauch man das hier nicht nochmal.
  stepper.setMaxSpeed(MaxSpeed[AktuellesEtikett] * 100); // Maximale Geschwindigkeit
  stepper.moveTo(LastSteps * 1.02); //

  if (MitDruck[AktuellesEtikett]) stepper.moveTo(LastStepsPrint * 1.02);

#if myDEBUG
  Serial.println( F("Vorb.") );
  Serial.print( F("Acc") );
  Serial.println(Acceleration[AktuellesEtikett]);
  Serial.print( F("Speed") );
  Serial.println(MaxSpeed[AktuellesEtikett] * 100
                );
  Serial.print( F("LastStepsP:") );
  Serial.println(LastStepsPrint);
  Serial.print( F("LastSteps") );
  Serial.println(LastSteps);
#endif
#endif


  bool Notstop = LOW;
  MotorVor(11); //Starten

  altePositionSmallRotary = 0;
  SetzeSmallRotaryWert(0);

  bool LiveRotAenderung = false;
  bool RotAenderung = false;
  while (abs(PositionBigRotary) <= Etikettenlaenge[AktuellesEtikett]) //Etikettierung starten
  {

    bool FortschrittAenderung = false;
#if !myDRIVE
    stepper.run();
    if (stepper.speed() <= (MaxSpeed[AktuellesEtikett] * 100) / 4 && stepper.distanceToGo() < 20)
      stepper.setSpeed(MaxSpeed[AktuellesEtikett] * 100 / 4);
    stepper.runSpeed();
#endif

    neuePositionSmallRotary = LeseSmallRotaryWert();

    if (neuePositionSmallRotary != altePositionSmallRotary)
    {
      Etikettenlaenge[AktuellesEtikett] +=  neuePositionSmallRotary;
      LiveLaengenWert +=  neuePositionSmallRotary;
      SetzeSmallRotaryWert(0);
      LiveRotAenderung = true;
      RotAenderung = true;
    }


    Fortschritt = abs((((long)(PositionBigRotary) * 100) / (long)(Etikettenlaenge[AktuellesEtikett])));

#if mySYSTEM
    if (Fortschritt != AlterFortschritt || LiveRotAenderung == true) //Zeigt jeden Prozentfortschritt an
#else  //Der Schrittmotor wird gestört bei Grafikausgabe
    if (abs(Fortschritt - AlterFortschritt) >= 10 || LiveRotAenderung == true)  //Zeigt nur jeden zehnten Prozentfortschritt an
#endif
    {
      u8g2.setDrawColor(0);       //Zum Löschen der alten Zeichen
      u8g2.drawBox(0, 35, 128, 15); //Zum Löschen der alten Zeichen
      u8g2.setDrawColor(1);      //Zum Löschen der alten Zeichen

      if (RotAenderung)
      {
        u8g2.setCursor(1, 50);
        sprintf(Ausgabe, "E%d", LiveLaengenWert);
        u8g2.print(Ausgabe);
      }
      u8g2.setCursor(43, 50);
      sprintf(Ausgabe, "-->%3d\n%%", Fortschritt);
      u8g2.print(Ausgabe);
      u8g2.sendBuffer();
      LiveRotAenderung = false;
      AlterFortschritt = Fortschritt;
    }


    if ((digitalRead(SmallRotary_PIN_SW) == LOW)) //RotarySwitch während Etikettiervorgang als NOTSTOP
    {
      MotorStop();
#if myDEBUG
      Serial.println(F("Notstop"));
#endif
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_courB14_tf);
      u8g2.setCursor(10, 20);
      u8g2.print(F("ROTASTOP"));
      u8g2.setCursor(0, 50);
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.print(F("GlasRaus"));
      u8g2.sendBuffer();
      Notstop = HIGH;
      buzzer(BUZZER_ERROR);
      Entprellen();
      delay(1000);
      break;
    }  //NOTFALL AUS

    // eventuell Datum Drucken?
    if (MitDruck[AktuellesEtikett])
    {
      if (abs(PositionBigRotary) > ZeitBisDatumDruck[AktuellesEtikett] && Gedruckt == LOW)
      {
        if (MitLuft[AktuellesEtikett] > 0)
        {
#if !mySYSTEM
          ledcWrite(0, 125);
#endif
          analogWrite(MiniLuefterEnable_PIN, MitLuft[AktuellesEtikett] * 25);
          digitalWrite(MiniLuefter_PIN1, HIGH); //Lüfter starten
        }
#if myDEBUG
        Serial.print(F("Lüfter"));
#endif
#if !myDRIVE
        LastStepsPrint = stepper.currentPosition();
#endif

        MotorStop(); //warten bis gedruckt
        Drucken();
        Gedruckt = HIGH;
#if !myDRIVE
        stepper.moveTo((LastSteps) * 1.02);
#if myDEBUG
        Serial.println( F("Vorb.") );
        Serial.print( F("Acc") );
        Serial.println(Acceleration[AktuellesEtikett]);
        Serial.print( F("Speed") );
        Serial.println(MaxSpeed[AktuellesEtikett] * 100);
        Serial.print( F("LastStepsP") );
        Serial.println(LastStepsPrint);
        Serial.print( F("LastSteps") );
        Serial.println(LastSteps);
#endif
#endif

        DisplayEtikettieren(Fortschritt);
        MotorVor(11);
      }
    } // mit Druck ende

    altePositionBigRotary = PositionBigRotary;
    PositionBigRotary = LeseBigRotaryWert();
  } // while ende

#if !myDRIVE
  LastSteps = stepper.currentPosition();

#if myDEBUG
  Serial.print(F("Stepper steps"));
  Serial.println(LastSteps);
#endif
#endif

  MotorStop(); //Etikettierung beendet


#if !myDRIVE
  stepper.disableOutputs();
#endif


  //Falls Lüfter lief ---> abschalten
  digitalWrite(MiniLuefter_PIN1, LOW);
#if myDEBUG
  Serial.print(F("Lüfter0"));
#endif
  if (HandModus == LOW)  //Im Handbetrieb diesen Punkt überspringen
  {
    if (Notstop == LOW) //Der Vorgagng lief sauber durch
    {
      u8g2.setCursor(43, 50);
      sprintf(Ausgabe, "-->%3d\n%%", 100);
      u8g2.print(Ausgabe);
      u8g2.sendBuffer();
      delay (1000);
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_courB14_tf);
      u8g2.setCursor(25, 20);
      u8g2.print(F("FERTIG"));
      u8g2.setCursor(0, 50);
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.print(F("GlasRaus"));
      u8g2.sendBuffer();
      buzzer(BUZZER_SUCCESS);
      Counter[AktuellesEtikett]++;
    }

#if mySENSOR // Ultraschallsensor
    while (Ultraschallsensor(Schwelle) == HIGH); //GLAS liegt noch drauf
#else
    while (digitalRead(NaeherungsSensor_PIN) == LOW) //GLAS liegt noch drauf
#endif
    {
      delay (100);
    }
    delay (1000);
    if (LiveLaengenWert != 0) WriteMem(); //Etikettenlänge wurde live angepasst
    DisplayNeutral();
  }
}
//ENDE ETIKETTIERVORGANG------------------------------------------

void DisplayEtikettieren(int Fortschrittswert)
{
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_courB10_tf);
  u8g2.setCursor(0, 20);
#if mySYSTEM
  u8g2.print(F("EtVomSchleckn"));
#else
  u8g2.print(F("EttiMandln"));
#endif
  u8g2.setCursor(43, 50);
  if (Fortschrittswert > 100) sprintf(Ausgabe, "-->%3d\n%%", "");
  else sprintf(Ausgabe, "-->%3d\n%%", Fortschrittswert);
  u8g2.print(Ausgabe);
  u8g2.sendBuffer();
}

//----------------------------------------------------------------
// DIREKTE MOTORANSTEUERUNG: VORWÄRTS UND RÜCKWÄRTS ZUM JUSTIEREN
//----------------------------------------------------------------
void Handsteuerung()
{
  String SpeedAnzeige;
  neuePositionSmallRotary = LeseSmallRotaryWert();
  if (neuePositionSmallRotary != altePositionSmallRotary)
  {
    Serial.print("Neue Position SmallRotary: "); 
    Serial.println(neuePositionSmallRotary);
    
    u8g2.setDrawColor(0);
    u8g2.drawBox(0, 37, 128, 16); //löschen der Zeile
    u8g2.setDrawColor(1);
    u8g2.setCursor(1, 50);
    if  (neuePositionSmallRotary > 0)
    {

      if (neuePositionSmallRotary > 8)
      {
        SetzeSmallRotaryWert(9);
        neuePositionSmallRotary = 9;
      }
      SpeedAnzeige = String(neuePositionSmallRotary) + " ";
      MotorVor(neuePositionSmallRotary);
      for (int i = 1; i <= neuePositionSmallRotary; i++)
      {
        SpeedAnzeige = SpeedAnzeige + ">";
      }
    }
    else if (neuePositionSmallRotary < 0)
    {

      if (neuePositionSmallRotary < -8)
      {
        SetzeSmallRotaryWert(-9);
        neuePositionSmallRotary = -9;
      }
      SpeedAnzeige = String(-neuePositionSmallRotary) + " ";
      MotorRueck(-neuePositionSmallRotary);
      for (int i = -1; i >= neuePositionSmallRotary; i--)
      {
        SpeedAnzeige = SpeedAnzeige + "<";
      }
    }
    else
    {
      if (MitFuss[AktuellesEtikett]) SpeedAnzeige = "<FussT>";
      else SpeedAnzeige = "GlasDrauf";
      MotorStop();
    }



    u8g2.print(SpeedAnzeige);
    u8g2.sendBuffer();
    altePositionSmallRotary = neuePositionSmallRotary;
    PositionSmallRotary = neuePositionSmallRotary;
  }
#if !myDRIVE
  if (PositionSmallRotary != 0)
  {
    stepper.setEnablePin(MotorEnable_PIN);
    int SpeedOutput;
    if (PositionSmallRotary > 0) SpeedOutput = MaxSpeed[AktuellesEtikett] * 100 * PositionSmallRotary / 9;
    else SpeedOutput = -(MaxSpeed[AktuellesEtikett] * 100 * abs(PositionSmallRotary) / 9);
    stepper.setSpeed(SpeedOutput);
    stepper.runSpeed();
  }
  else stepper.disableOutputs();
#endif

}

//------------------------------------------
// Haltbarkeitsdatum Drucken
//------------------------------------------
void Drucken()
{
#if myDEBUG
  Serial.println(F("Stempeln"));
#endif

  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_courB12_tf);
  u8g2.setCursor(20, 20);
  u8g2.print("Stempeln");
  u8g2.setCursor(0, 50);
  u8g2.print("Warte...");
  u8g2.sendBuffer();


  // Warten zum Trocknen
  if (DruckTrockenZeit > 0)
  {
    unsigned long AktuelleZeit = millis();
    unsigned int  LetzteAnzeige;

    while (millis() - AktuelleZeit < (DruckTrockenZeit[AktuellesEtikett] * 1000))
    {
      unsigned int LaufZeit =  DruckTrockenZeit[AktuellesEtikett] - int((millis() - AktuelleZeit) / 1000);
      if (LaufZeit != LetzteAnzeige)
      {
        u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_courB12_tf);
        u8g2.setCursor(20, 20);
        u8g2.print("Stempeln");
        u8g2.setCursor(0, 50);
        u8g2.print("Warte...");
        u8g2.print(LaufZeit);
        u8g2.print("sec");
        u8g2.sendBuffer();
        LetzteAnzeige = LaufZeit;
      }
      if ((digitalRead(SmallRotary_PIN_SW) == LOW)) break; //Mit Rotary-Knopfdruck raus aus der Wartezeit
    }
    Entprellen();
  }
}
//----------------------------------------------------------------


//------------------------------------------
// Motor Stop
//------------------------------------------
void MotorStop()
{
#if myDRIVE
  digitalWrite(Motorsteuerung_PIN1, LOW);
  digitalWrite(Motorsteuerung_PIN2, LOW);
#endif

#if myDEBUG
  Serial.print(F("Motor Stop"));
#endif
}

#define myDRIVE 1 // oder 0, je nach Konfiguration

void MotorVor(int Speed) {
  #if myDRIVE
    int SpeedOutput = min(255, 75 + Speed * 20); // erst ab ca 100 dreht der 12V Gleichstrommotor
    Serial.print("MotorVor - Speed: ");
    Serial.println(Speed);
    Serial.print("SpeedOutput: ");
    Serial.println(SpeedOutput);
    analogWrite(MotorEnable_PIN, 255);
    digitalWrite(Motorsteuerung_PIN1, HIGH); // Motor läuft vorwärts
    digitalWrite(Motorsteuerung_PIN2, LOW);

    #if myDEBUG
      Serial.print(F("Motor vorwärts - mit "));
      Serial.print(SpeedOutput / 255 * 100);
      Serial.println(F("%"));
    #endif
  #endif
}


void MotorRueck(int Speed) {
  #if myDRIVE
    int SpeedOutput = 75 + Speed * 20; // Erst ab ca. 100 dreht der 12V Gleichstrommotor
    Serial.print("MotorRueck - Speed: ");
    Serial.println(Speed);
    Serial.print("SpeedOutput: ");
    Serial.println(SpeedOutput);
    analogWrite(MotorEnable_PIN, 255);
    digitalWrite(Motorsteuerung_PIN1, LOW);
    digitalWrite(Motorsteuerung_PIN2, HIGH);

    #if myDEBUG
      Serial.print(F("Motor rückwärts - mit "));
      Serial.println(SpeedOutput);
    #endif
  #endif
}




void DisplayNeutral()
{
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_courB14_tf);
  u8g2.setCursor(0, 20);
  u8g2.print(F("Etik."));
  u8g2.setFont(u8g2_font_courB08_tf);
  u8g2.print(" (");
  u8g2.print(AktuellesEtikett + 1);
  u8g2.print(")");
  u8g2.setCursor(0, 50);
  u8g2.setFont(u8g2_font_courB12_tf);
  if (MitFuss[AktuellesEtikett]) u8g2.print(F("<FussTaster>"));
  else u8g2.print(F("GlasRauf"));
  u8g2.sendBuffer();
}


//-----------------------------------------------------------------------------------------
//  // Menü Einstellungen
//-----------------------------------------------------------------------------------------
void Einstellungsmenue()
{
  if (digitalRead(SmallRotary_PIN_SW) == LOW)  //Rein ins Menü durch Tastendruck
  {
    //Hauptmenü
    int SpeicherAktuellesEtikett = AktuellesEtikett;
    Entprellen();

    altePositionSmallRotary = 99;
    SetzeSmallRotaryWert(AktuellesEtikett); //RESET
    while (digitalRead(SmallRotary_PIN_SW))
    {
      neuePositionSmallRotary = LeseSmallRotaryWert();
      if (neuePositionSmallRotary != altePositionSmallRotary)
      {
        if (neuePositionSmallRotary > 2)
        {
          neuePositionSmallRotary = 2;
          SetzeSmallRotaryWert(2);
        }
        if (neuePositionSmallRotary < 0)
        {
          neuePositionSmallRotary = 0;
          SetzeSmallRotaryWert(0);
        }
        altePositionSmallRotary = neuePositionSmallRotary;
        AktuellesEtikett = neuePositionSmallRotary;
        u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_courB08_tf);
        u8g2.setCursor(0, 10);
        u8g2.print(F("Einstellungen für"));
        u8g2.drawLine(0, 16, 128, 16); //horiz. Linie
        u8g2.setFontMode(0);

        for (int d = 1; d < 4; d++)
        {
          u8g2.setFont(u8g2_font_courB08_tf);
          sprintf(Ausgabe, "%d)", d);
          u8g2.setCursor(0, d * 15 + 15);
          if (d == AktuellesEtikett + 1)
          {
            u8g2.drawBox(0, d * 15 + 6, 10, 11);
            u8g2.setDrawColor(0);
          }
          u8g2.print(Ausgabe);
          u8g2.setDrawColor(1);
          u8g2.setFont(u8g2_font_courB10_tf);
          u8g2.setCursor(12, d * 15 + 15);
          u8g2.print(F("Etiketten"));
          u8g2.setFont(u8g2_font_courB08_tf);
          u8g2.setCursor(98, d * 15 + 15);
          sprintf(Ausgabe, "c:%d", Counter[d - 1]);
          u8g2.print(Ausgabe);
        }
        u8g2.sendBuffer();
        SetzeSmallRotaryWert(AktuellesEtikett); //RESET
      }
    } //while Taster nicht gedrückt
    //AktuellesEtikett = altePositionSmallRotary;
    // Ende Hauptmenü
    buzzer(BUZZER_SHORT);

    Entprellen();

    // Untermenü
    char* MenuePunkte[17] = { "Menü verlassen",     // 0
                              "Etikettenlänge",   // 1 + Wert
                              "Etikettenlänge", // 2 Untermenü
                              " Handbetrieb",       // 3 HANDMODUS falls der Näherungssensor nicht funktioniert
                              "    Buzzer",             // 4 Sound aktiv oder inaktiv
                              " Counterwert",       // 5
                              " Schrittmotor",   // 6 Speed
                              " Schrittmotor",   // 7 Acceleration
                              " Fußschalter",     //8 Aktiv Inaktiv
                              "   Drucken",           // 9 + Aktiv oder Inaktiv
                              "Druck-Position",     // 10 +Wert
                              "Druck-Position",// 11 Untermenü
                              "    Lüfter",           // 15 Inaktiv oder Spannung
                              " Trockenzeit"        // 16 WarteZeit nach Druck in Zehntelsekunden
                            };

    byte AktuellerMenuePunkt = 99;

    altePositionSmallRotary = 99;
    SetzeSmallRotaryWert(0); //RESET

    while (altePositionSmallRotary != 0) //bis Menü verlassen wird
    {

      while (digitalRead(SmallRotary_PIN_SW))
      {
        neuePositionSmallRotary = LeseSmallRotaryWert();
        if (neuePositionSmallRotary < 0)
        {
          neuePositionSmallRotary = 0;
          SetzeSmallRotaryWert(neuePositionSmallRotary);
        }
        if (neuePositionSmallRotary > 16)
        {
          neuePositionSmallRotary = 16;
          SetzeSmallRotaryWert(neuePositionSmallRotary);
        }

        if (MitDruck[AktuellesEtikett] == LOW) neuePositionSmallRotary = neuePositionSmallRotary % 10; //Drucken nicht aktiviert
        else neuePositionSmallRotary = neuePositionSmallRotary % 17;

        if (neuePositionSmallRotary == 6 && altePositionSmallRotary == 5) neuePositionSmallRotary += DriveJump;
        if (neuePositionSmallRotary == 7) neuePositionSmallRotary -=  DriveJump;

        if (neuePositionSmallRotary != altePositionSmallRotary)
        {
#if myDEBUG
          Serial.print(F("1neuePosRot:"));
          Serial.println(neuePositionSmallRotary);
#endif
          u8g2.clearBuffer();
          u8g2.setFont(u8g2_font_courB10_tf);
          u8g2.setCursor(5, 15);
          sprintf(Ausgabe, "DSatz (%d)", (AktuellesEtikett + 1));
          u8g2.print(Ausgabe);
          u8g2.drawLine(0, 20, 164, 20); //horiz. Linie
          u8g2.setCursor(1, 40);
          u8g2.print(MenuePunkte[neuePositionSmallRotary]);
          u8g2.setCursor(52, 60);

          if (neuePositionSmallRotary == 1) //Etikettenlänge
          {
            u8g2.print(Etikettenlaenge[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 2 || neuePositionSmallRotary == 11) //M)Etikettenlänge
          {
            u8g2.setCursor(1, 60);
            u8g2.print(F("man. anf."));
          }
          if (neuePositionSmallRotary == 3) //Handbetrieb
          {
            u8g2.setCursor(30, 60);
            u8g2.print(F("Inaktiv"));
          }
          if (neuePositionSmallRotary == 4) //Buzzer
          {
            u8g2.setCursor(12, 60);
            if (MitBuzzer[AktuellesEtikett] == LOW) u8g2.print(F("InAktiv"));
            else u8g2.print(F("Aktiv"));
          }
          if (neuePositionSmallRotary == 5) //Counter
          {
            u8g2.print(Counter[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 6) //SchrittMotor Speed
          {
            u8g2.setCursor(10, 60);
            u8g2.print(F("Speed"));
            u8g2.setCursor(90, 60);
            u8g2.print(MaxSpeed[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 7) //SchrittMotor Acceleration
          {
            u8g2.setCursor(10, 60);
            u8g2.print(F("Accel.:"));
            u8g2.setCursor(90, 60);
            u8g2.print(Acceleration[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 8) //Fußschalter
          {
            u8g2.setCursor(12, 60);
            if (MitFuss[AktuellesEtikett] == LOW) u8g2.print(F("InAktiv"));
            else u8g2.print(F("Aktiv"));
          }
          if (neuePositionSmallRotary == 9) //Drucken
          {
            u8g2.setCursor(12, 60);
            if (MitDruck[AktuellesEtikett] == LOW) u8g2.print(F("Deaktiviert"));
            else u8g2.print(F(" Aktiviert"));
          }
          if (neuePositionSmallRotary == 10) //Druckposition
          {
            u8g2.print(ZeitBisDatumDruck[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 15) //Lüfter
          {
            u8g2.setCursor(12, 60);
            if (MitLuft[AktuellesEtikett] == 0) u8g2.print(F("Deaktiviert"));
            else
            {
              u8g2.setCursor(48, 60);
              u8g2.print(MitLuft[AktuellesEtikett] * 10);
              u8g2.print(F("%"));
            }
          }
          if (neuePositionSmallRotary == 16)
          {
            u8g2.print(DruckTrockenZeit[AktuellesEtikett]);
            u8g2.print(F(" sec"));
          }
          u8g2.sendBuffer();
          altePositionSmallRotary = neuePositionSmallRotary;
          SetzeSmallRotaryWert(neuePositionSmallRotary);
        }
      } //while Taster nicht gedrückt
      buzzer(BUZZER_SHORT);
      Entprellen();

      // Ende Untermenü


      // Position 1 Etikettenlänge per Wert einstellen
      if  (altePositionSmallRotary == 1) WertAendern(Etikettenlaenge, MenuePunkte[neuePositionSmallRotary]);

      // Position 2 Etikettenlänge (durch Wert Position anfahren) einstellen
      if (altePositionSmallRotary == 2) PositionAnfahren();

      // Position 3 Handbetrieb
      if  (altePositionSmallRotary == 3) Handbetrieb();

      // Position 4 Buzzer generell de-/aktivieren
      if  (altePositionSmallRotary == 4) WertInAktivAendern(MitBuzzer, MenuePunkte[neuePositionSmallRotary]);

      // Position 5 Counter Reset
      if  (altePositionSmallRotary == 5)
      {
        int oldPositionSmallRotary = 99;
        bool ResetCounter = HIGH;
        SetzeSmallRotaryWert(0); //RESET

        while (digitalRead(SmallRotary_PIN_SW))
        {

          neuePositionSmallRotary = LeseSmallRotaryWert();
          if (neuePositionSmallRotary != oldPositionSmallRotary)
          {
            u8g2.drawBox(15, 48, 103, 14);
            u8g2.setDrawColor(0);
            if (!ResetCounter)
            {
              u8g2.setCursor(42, 60);
              u8g2.setDrawColor(0);
              u8g2.print(F("Reset"));
              ResetCounter = HIGH;
            }
            else
            {
              u8g2.setCursor(52, 60);
              u8g2.print(Counter[AktuellesEtikett]);
              ResetCounter = LOW;
            }
            u8g2.setDrawColor(1);
            u8g2.sendBuffer();

            oldPositionSmallRotary = neuePositionSmallRotary;
          }
        } //while Taster nicht gedrückt
        if (ResetCounter)
        {
          Counter[AktuellesEtikett] = 0;
          EinWertNeu = HIGH;  //EEPROM-Write aktiviert - ein Wert geändert
        }
        SetzeSmallRotaryWert(altePositionSmallRotary); // zurück an die richtige Stelle
        altePositionSmallRotary = 99;
        buzzer(BUZZER_LONG);
        Entprellen();
      }

      // Position 6 MaxSpeed
      if  (altePositionSmallRotary == 6) WertAendern(MaxSpeed, MenuePunkte[neuePositionSmallRotary]);

      // Position 7 Acceleration
      if  (altePositionSmallRotary == 7) WertAendern(Acceleration, MenuePunkte[neuePositionSmallRotary]);

      // Position 8 Fußschalter generell de-/aktivieren
      if  (altePositionSmallRotary == 8) WertInAktivAendern(MitFuss, MenuePunkte[neuePositionSmallRotary]);

      // Position 9 Druck de-/aktivieren
      if  (altePositionSmallRotary == 9) WertInAktivAendern(MitDruck, MenuePunkte[neuePositionSmallRotary]);

      // Position 10 ZeitBisDruck per Wert einstellen
      if  (altePositionSmallRotary == 10) WertAendern(ZeitBisDatumDruck, MenuePunkte[neuePositionSmallRotary]);

      // Position 11  ZeitBisDruck per Anfahren einstellen
      if  (altePositionSmallRotary == 11) PositionAnfahren();

      // Position 15 Lüfter de-/aktivieren bzw Spannung einstellen
      if  (altePositionSmallRotary == 15) WertAendern(MitLuft, MenuePunkte[neuePositionSmallRotary]);


    }

    //Menü verlassen
    if (SpeicherAktuellesEtikett != AktuellesEtikett) EinWertNeu = HIGH; //Falls nur Etikett geändert auch abspeichern

    if (EinWertNeu)
    {
      WriteMem(); //Daten nur sichern, falls es eine Änderung gab
      //MenueHeader();
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.setCursor(0, 60);
      u8g2.setFont(u8g2_font_courB08_tf);
      u8g2.print(F("Daten abspeichern..."));
      u8g2.sendBuffer();
      for (int p = 0; p < 3; p++)
      {
        buzzer(BUZZER_SHORT);
      }
      EinWertNeu = LOW; //Reset
    }

    Entprellen();
    DisplayNeutral();

    //Es geht in den BEREITmodus zurück
    altePositionSmallRotary = 0; //RESET
    SetzeSmallRotaryWert(0); //RESET
  }
}


void Entprellen()
{
  while (digitalRead(SmallRotary_PIN_SW) == LOW) //ENTPRELLEN
  {
    delay (100);
  }
}

void Handbetrieb()
{
  int oldPositionSmallRotary = 0;
  SetzeSmallRotaryWert(100); //RESET

  Entprellen();
  HandModus = HIGH;
  while (digitalRead(SmallRotary_PIN_SW) && HandModus) //Warte bis RotarySwitch gedrückt und Modus inaktiv
  {
    while (digitalRead(SmallRotary_PIN_SW)) //Warte bis RotarySwitch gedrückt und Modus aktiv
    {
      neuePositionSmallRotary = LeseSmallRotaryWert();
      if (neuePositionSmallRotary != oldPositionSmallRotary)
      {
        u8g2.drawBox(1, 48, 128, 14);
        u8g2.setDrawColor(0);
        if (HandModus)
        {
          HandModus = LOW;
          u8g2.setCursor(30, 60);
          u8g2.print("Inaktiv");
        }
        else
        {
          HandModus = HIGH;
          u8g2.setCursor(1, 60);
          u8g2.print("Press to Start");
        }
        u8g2.setDrawColor(1);
        u8g2.sendBuffer();
        oldPositionSmallRotary = neuePositionSmallRotary;
      }
    } //while Taster nicht gedrückt - innere While-Schleife
    //Tastendruck Auswerten
    Entprellen();
    if (HandModus)
    {
      Etikettieren(); //Vorgang von Hand gestartet
      Entprellen(); // falls Abbruch im Etikettiervorgang
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.setCursor(5, 15);
      sprintf(Ausgabe, "Datensatz (%d)", (AktuellesEtikett + 1));
      u8g2.print(Ausgabe);
      u8g2.drawLine(0, 20, 164, 20); //horiz. Linie
      u8g2.setCursor(1, 40);
      u8g2.print(F(" Handbetrieb"));
      u8g2.setCursor(1, 60);
      u8g2.drawBox(1, 48, 128, 14);
      u8g2.setDrawColor(0);
      u8g2.print("Press to Start");
      u8g2.setDrawColor(1);
      u8g2.sendBuffer();
      oldPositionSmallRotary = neuePositionSmallRotary;
    }
  } //äussere Whileschleife
  SetzeSmallRotaryWert(altePositionSmallRotary); // zurück an die richtige Stelle
  altePositionSmallRotary = 99;
  buzzer(BUZZER_LONG);
}



void WertAendern(unsigned int *Was, char * MenuePunkt)
{
  int AlterWasWert = Was[AktuellesEtikett];
  int oldPositionSmallRotary = 0;
  int oldPositionBigRotary = 0;

  SetzeSmallRotaryWert(Was[AktuellesEtikett]); //RESET
  SetzeBigRotaryWert(0);

  while (digitalRead(SmallRotary_PIN_SW))
  {
    neuePositionSmallRotary = LeseSmallRotaryWert();
    PositionBigRotary = LeseBigRotaryWert();
    if ((neuePositionSmallRotary >= 0) && (neuePositionSmallRotary <= 10000))
    {
      if (neuePositionSmallRotary != oldPositionSmallRotary || PositionBigRotary != oldPositionBigRotary)
      {
        Was[AktuellesEtikett] = neuePositionSmallRotary + PositionBigRotary;
#if myDEBUG
        Serial.print(F("neu"));
        Serial.println(Was[AktuellesEtikett]);
#endif
        u8g2.setFont(u8g2_font_courB10_tf);
        u8g2.setCursor(1, 40);
        u8g2.print(MenuePunkt);
        if (altePositionSmallRotary == 6 || altePositionSmallRotary == 7) u8g2.drawBox(80, 48, 108, 14);
        else u8g2.drawBox(10, 48, 108, 14);
        if (altePositionSmallRotary == 6)
        {
          u8g2.setCursor(10, 60);
          u8g2.print(F("Speed"));
          u8g2.setCursor(90, 60);
        }
        else if (altePositionSmallRotary == 7)
        {
          u8g2.setCursor(10, 60);
          u8g2.print(F("Accel"));
          u8g2.setCursor(90, 60);
        }
        else u8g2.setCursor(50, 60);
        u8g2.setDrawColor(0);
        if (altePositionSmallRotary == 15)
        {
          analogWrite(MiniLuefterEnable_PIN, MitLuft[AktuellesEtikett] * 25);
          digitalWrite(MiniLuefter_PIN1, HIGH); //Lüfter starten
          if (Was[AktuellesEtikett] < 1)
          {
            u8g2.setCursor(12, 60);
            u8g2.print(F("inaktiv"));
            SetzeSmallRotaryWert(0);
            SetzeBigRotaryWert(0);
            Was[AktuellesEtikett] = 0;
          }
          else
          {
            if (Was[AktuellesEtikett] > 9)
            {
              SetzeSmallRotaryWert(10);
              SetzeBigRotaryWert(0);
              Was[AktuellesEtikett] = 10;
            }
            u8g2.setCursor(48, 60);
            u8g2.print(Was[AktuellesEtikett] * 10);
            u8g2.print("%");
          }
        }
        else u8g2.print(Was[AktuellesEtikett]);
        u8g2.setDrawColor(1);
        u8g2.sendBuffer();
        oldPositionSmallRotary = neuePositionSmallRotary;
        oldPositionBigRotary = PositionBigRotary;
        SetzeSmallRotaryWert(neuePositionSmallRotary);
      }
    }
    EinWertNeu = HIGH;  //EEPROM-Write aktiviert - ein Wert geändert
  } //while Taster nicht gedrückt
  digitalWrite(MiniLuefter_PIN1, LOW); //Lüfter stoppen, falls lief
  SetzeSmallRotaryWert(altePositionSmallRotary); // zurück an die richtige Stelle
  altePositionSmallRotary = 99;
  buzzer(BUZZER_LONG);
  Entprellen();
}






void WertInAktivAendern(bool *Was, char * MenuePunkt) //Für An/Aus-Werte
{
  int oldPositionSmallRotary = 99;
  SetzeSmallRotaryWert(0); //RESET
  while (digitalRead(SmallRotary_PIN_SW))
  {
    neuePositionSmallRotary = LeseSmallRotaryWert();
    if (neuePositionSmallRotary != oldPositionSmallRotary)
    {
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.setCursor(1, 40);
      u8g2.print(MenuePunkt);
      u8g2.setCursor(15, 60);
      u8g2.drawBox(10, 48, 108, 14);
      u8g2.setDrawColor(0);
      if (Was[AktuellesEtikett] == LOW)
      {
        u8g2.print(F("Deaktiviert"));
        Was[AktuellesEtikett] = HIGH;
      }
      else
      {
        u8g2.print(F(" Aktiviert"));
        Was[AktuellesEtikett] = LOW;
      }
      u8g2.setDrawColor(1);
      u8g2.sendBuffer();
      oldPositionSmallRotary = neuePositionSmallRotary;
      SetzeSmallRotaryWert(neuePositionSmallRotary);
      EinWertNeu = HIGH;  //EEPROM-Write aktiviert - ein Wert geändert
    }

  } //while Taster nicht gedrückt
  if (Was[AktuellesEtikett] == LOW) Was[AktuellesEtikett] = HIGH;
  else Was[AktuellesEtikett] = LOW;

  SetzeSmallRotaryWert(altePositionSmallRotary); // zurück an die richtige Stelle
  altePositionSmallRotary = 99;
  buzzer(BUZZER_LONG);
  Entprellen();
}


void PositionAnfahren() {
  int oldPositionSmallRotary = 0;
  Entprellen();
  PositionBigRotary = abs(LeseBigRotaryWert());

  SetzeSmallRotaryWert(0);
  SetzeBigRotaryWert(0);
  int OldBig = 99;
  String SpeedAnzeige = "<<Drehregler>>";
  Serial.println("Start PositionAnfahren"); // Neue Debug-Ausgabe

  while (digitalRead(SmallRotary_PIN_SW)) {
    neuePositionSmallRotary = LeseSmallRotaryWert();
    Serial.print("Neue Position SmallRotary (innerhalb Schleife): ");
    Serial.println(neuePositionSmallRotary); // zusätzliche Debug-Ausgabe
    
    if (neuePositionSmallRotary != oldPositionSmallRotary) {
      Serial.print("Positionsänderung erkannt: ");
      Serial.println(neuePositionSmallRotary);

      u8g2.setDrawColor(0);
      u8g2.drawBox(0, 49, 128, 14); // löschen der Zeile
      u8g2.setDrawColor(1);
      u8g2.setCursor(1, 60);

      if (neuePositionSmallRotary > 0) {
      if (neuePositionSmallRotary > 8)
      {
        SetzeSmallRotaryWert(9);
        neuePositionSmallRotary = 9;
      }
      SpeedAnzeige = String(neuePositionSmallRotary) + " ";
      MotorVor(neuePositionSmallRotary);
      for (int i = 1; i <= neuePositionSmallRotary; i++)
      {
        SpeedAnzeige = SpeedAnzeige + ">";
      }

        
      } else if (neuePositionSmallRotary < 0) {
        if (neuePositionSmallRotary < -8) {
          SetzeSmallRotaryWert(-9);
          neuePositionSmallRotary = -9;
        }
        SpeedAnzeige = String(-neuePositionSmallRotary) + " ";
        Serial.print("MotorRueck wird aufgerufen mit Geschwindigkeit: ");
        Serial.println(neuePositionSmallRotary); // Debug-Ausgabe
        MotorRueck(neuePositionSmallRotary);
        for (int i = -1; i >= neuePositionSmallRotary; i--) {
          SpeedAnzeige = SpeedAnzeige + "<";
        }
      } else {
        SpeedAnzeige = "<<Drehregler>>";
        Serial.println("MotorStop wird aufgerufen"); // Debug-Ausgabe
        MotorStop();
      }

      u8g2.print(SpeedAnzeige);
      u8g2.sendBuffer();
      oldPositionSmallRotary = neuePositionSmallRotary;
      SetzeSmallRotaryWert(neuePositionSmallRotary);
    }
    PositionBigRotary = abs(LeseBigRotaryWert());

    if (PositionBigRotary != OldBig) {
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.setCursor(1, 15);
      u8g2.print(F("STARTPOSITION:"));
      u8g2.setFont(u8g2_font_courB08_tf);
      u8g2.setCursor(1, 30);
      u8g2.print(F("Etikett bis ans Glas"));
      u8g2.setCursor(1, 45);
      u8g2.print(F("ranfahren -->"));
      u8g2.setCursor(93, 45);
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.print(PositionBigRotary);
      u8g2.setCursor(1, 60);
      u8g2.print(SpeedAnzeige);
      u8g2.sendBuffer();
      OldBig = PositionBigRotary;
    }
  
  Serial.println("Ende PositionAnfahren"); // Neue Debug-Ausgabe



  } //while Taster nicht gedrückt

#if myDEBUG
  Serial.println(F("Startpos gef."));
#endif
  Entprellen();
  SetzeSmallRotaryWert(0);
  SetzeBigRotaryWert(0);
  OldBig = 99;
  SpeedAnzeige = "<<Drehregler>>";
  while (digitalRead(SmallRotary_PIN_SW))
  {
    neuePositionSmallRotary = LeseSmallRotaryWert();
    if (neuePositionSmallRotary != oldPositionSmallRotary)
    {
#if myDEBUG
      Serial.print(F("SmallRot:"));
      Serial.println(neuePositionSmallRotary); // ...soll die aktuelle Position im seriellen Monitor ausgegeben werden.
#endif
      u8g2.setDrawColor(0);
      u8g2.drawBox(0, 49, 128, 14); //löschen der Zeile
      u8g2.setDrawColor(1);
      u8g2.setCursor(1, 60);
      if  (neuePositionSmallRotary > 0)
      {

        if (neuePositionSmallRotary > 8)
        {
          SetzeSmallRotaryWert(9);
          neuePositionSmallRotary = 9;
        }
        SpeedAnzeige = String(neuePositionSmallRotary) + " ";
        MotorVor(neuePositionSmallRotary);
        for (int i = 1; i <= neuePositionSmallRotary; i++)
        {
          SpeedAnzeige = SpeedAnzeige + ">";
        }
      }
      else if (neuePositionSmallRotary < 0)
      {

        if (neuePositionSmallRotary < -8)
        {
          SetzeSmallRotaryWert(-9);
          neuePositionSmallRotary = -9;
        }
        SpeedAnzeige = String(-neuePositionSmallRotary) + " ";
        MotorRueck(-neuePositionSmallRotary);
        for (int i = -1; i >= neuePositionSmallRotary; i--)
        {
          SpeedAnzeige = SpeedAnzeige + "<";
        }
      }
      else
      {
        SpeedAnzeige = "<<Drehregler>>";
        MotorStop();
      }
      u8g2.print(SpeedAnzeige);
      u8g2.sendBuffer();
      oldPositionSmallRotary = neuePositionSmallRotary;
      SetzeSmallRotaryWert(neuePositionSmallRotary);
    }
    PositionBigRotary = abs(LeseBigRotaryWert());

    if (PositionBigRotary != OldBig)
    {
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.setCursor(1, 15);
      if (altePositionSmallRotary == 2)
      {
        u8g2.print(F("END-POSITION:"));
        u8g2.setFont(u8g2_font_courB08_tf);
        u8g2.setCursor(1, 30);
        u8g2.print(F("Etikett ans nächste"));
        u8g2.setCursor(1, 45);
        u8g2.print(F("Glas fahren ->"));
      }
      else
      {
        u8g2.print(F("DRUCK-POSITION:"));
        u8g2.setFont(u8g2_font_courB08_tf);
        u8g2.setCursor(1, 30);
        u8g2.print(F("Etikett an die Druck-"));
        u8g2.setCursor(1, 45);
        u8g2.print(F("Position fahren"));
      }
      u8g2.setCursor(93, 45);
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.print(PositionBigRotary);
      u8g2.setCursor(1, 60);
      u8g2.print(SpeedAnzeige);
      u8g2.sendBuffer();
      OldBig = PositionBigRotary;
    }

  } //while Taster nicht gedrückt

  if (altePositionSmallRotary == 2)
  {
    Etikettenlaenge[AktuellesEtikett] = abs(LeseBigRotaryWert());
#if myDEBUG
    Serial.print(F("Endpos gef."));
    Serial.println(Etikettenlaenge[AktuellesEtikett]);
#endif
  }
  else
  {
    ZeitBisDatumDruck[AktuellesEtikett] = abs(LeseBigRotaryWert());
#if myDEBUG
    Serial.print(F("Druckpos.gef."));
    Serial.println(ZeitBisDatumDruck[AktuellesEtikett]);
    Serial.print(F("alte rotPOs:"));
    Serial.println(altePositionSmallRotary);
#endif
  }
  SetzeSmallRotaryWert(altePositionSmallRotary - 1); // zurück an die richtige Stelle
  altePositionSmallRotary = 99;
  buzzer(BUZZER_LONG);
  EinWertNeu = HIGH;  //EEPROM-Write aktiviert - ein Wert geändert
  Entprellen();
}


void buzzer(byte type)
{

  pinMode(Buzzer_PIN, OUTPUT);
  delay(100);
  switch (type)
  {
    case BUZZER_SHORT: //short
      if (MitBuzzer[AktuellesEtikett])
      {
        digitalWrite(Buzzer_PIN, HIGH);
        delay(100);
        digitalWrite(Buzzer_PIN, LOW);
      }
      else
      {
        delay(100);
      }
      break;

    case BUZZER_LONG: //long
      if (MitBuzzer[AktuellesEtikett])
      {
        digitalWrite(Buzzer_PIN, HIGH);
        delay(500);
        digitalWrite(Buzzer_PIN, LOW);
      }
      else delay(500);
      break;

    case BUZZER_SUCCESS: //success
      if (MitBuzzer[AktuellesEtikett])
      {
        digitalWrite(Buzzer_PIN, HIGH);
        delay(100);
        digitalWrite(Buzzer_PIN, LOW);
        delay(100);
        digitalWrite(Buzzer_PIN, HIGH);
        delay(100);
        digitalWrite(Buzzer_PIN, LOW);
        delay(100);
        digitalWrite(Buzzer_PIN, HIGH);
        delay(100);
        digitalWrite(Buzzer_PIN, LOW);
      }
      else delay(500);
      break;

    case BUZZER_ERROR: //error
      if (MitBuzzer[AktuellesEtikett])
      {
        digitalWrite(Buzzer_PIN, HIGH);
        delay(1500);
        digitalWrite(Buzzer_PIN, LOW);
      }
      else delay(1500);
      break;
  }
}

bool Ultraschallsensor(float Schwelle) {
  bool glasda = LOW;

  float Abstand = 0; //KUD Abstand initialisieren
  for (int i = 1; i <= n_pings; i++) {
    Abstand = Abstand + get_distance(); //KUD Ultraschallsensor auslesen
  }

  Abstand = Abstand / n_pings; //KUD Mittelwertbildung

  if (Abstand <= Schwelle) {
    glasda = HIGH;
  }

  return (glasda);

}

float get_distance() { //KUD Abstand Glas von Ultraschallsensor
  float duration = 0;
  float distance = 0;

  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  noInterrupts();
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  duration = pulseIn(NaeherungsSensor_PIN, HIGH); // Erfassung - Dauer in Mikrosekunden
  interrupts();

  distance = (duration / 2) / 29.1; // Distanz in CM
  return (distance);
}

//------------------------------------------
// StartLOGO
//------------------------------------------
void print_logo() {
  u8g2.clearBuffer();          // clear the internal memory
  u8g2.setFont(u8g2_font_courB10_tf);
  u8g2.setCursor(1, 10);    u8g2.print(F("Achtung:"));
  u8g2.setCursor(1, 25);    u8g2.print(F("Debug"));
  u8g2.setCursor(1, 40);    u8g2.print(F("an!!!"));


  u8g2.setFont(u8g2_font_courB14_tf);
#if mySYSTEM
  u8g2.setCursor(85, 20);    u8g2.print(F("Et"));
  u8g2.setCursor(80, 40);    u8g2.print(F("Vom"));
  u8g2.setCursor(52, 60);    u8g2.print(F("Schleck"));
#else
  u8g2.setCursor(85, 27);    u8g2.print("Etti");
  u8g2.setCursor(73, 43);    u8g2.print("MANDL");
  u8g2.setCursor(85, 54);
#endif
  u8g2.setFont(u8g2_font_courB10_tf);
  u8g2.setCursor(0, 62); u8g2.print(Version);
  u8g2.sendBuffer();
  delay(2000);
  DisplayNeutral();
}



//----------------------------------------------------------------
// Schreibe in Memory
//----------------------------------------------------------------
void WriteMem() {

#if mySYSTEM
  byte low, high, set;
  byte  AnzahlWerte = 23;

  set = 99;
  EEPROM.write(0, set); // Zeichen, dass bereits aktiv beschrieben wurde

  for (int w = 0; w < 3; w++) //Position 1-69
  {
    low = Etikettenlaenge[w] & 0xFF;
    high = (Etikettenlaenge[w] >> 8) & 0xFF;
    EEPROM.write(1 + (w * AnzahlWerte), low);
    EEPROM.write(2 + (w * AnzahlWerte), high);

    EEPROM.write(3 + (w * AnzahlWerte), MitBuzzer[w]);

    low = Counter[w] & 0xFF;
    high = (Counter[w] >> 8) & 0xFF;
    EEPROM.write(4 + (w * AnzahlWerte), low);
    EEPROM.write(5 + (w * AnzahlWerte), high);

    low = MaxSpeed[w] & 0xFF;
    high = (MaxSpeed[w] >> 8) & 0xFF;
    EEPROM.write(6 + (w * AnzahlWerte), low);
    EEPROM.write(7 + (w * AnzahlWerte), high);

    low = Acceleration[w] & 0xFF;
    high = (Acceleration[w] >> 8) & 0xFF;
    EEPROM.write(8 + (w * AnzahlWerte), low);
    EEPROM.write(9 + (w * AnzahlWerte), high);

    EEPROM.write(10 + (w * AnzahlWerte), MitFuss[w]);

    EEPROM.write(11 + (w * AnzahlWerte), MitDruck[w]);

    low = ZeitBisDatumDruck[w] & 0xFF;
    high = (ZeitBisDatumDruck[w] >> 8) & 0xFF;
    EEPROM.write(12 + (w * AnzahlWerte), low);
    EEPROM.write(13 + (w * AnzahlWerte), high);


    low = MitLuft[w] & 0xFF;
    high = (MitLuft[w] >> 8) & 0xFF;
    EEPROM.write(20 + (w * AnzahlWerte), low);
    EEPROM.write(21 + (w * AnzahlWerte), high);

    low = DruckTrockenZeit[w] & 0xFF;
    high = (DruckTrockenZeit[w] >> 8) & 0xFF;
    EEPROM.write(22 + (w * AnzahlWerte), low);
    EEPROM.write(23 + (w * AnzahlWerte), high);
  }

  EEPROM.write(70, AktuellesEtikett);
#else
  preferences.begin("EEPROM", false);
  preferences.putUInt("AktEtikett", AktuellesEtikett);
  preferences.putUInt("EtiLaenge0", Etikettenlaenge[0]);
  preferences.putUInt("EtiLaenge1", Etikettenlaenge[1]);
  preferences.putUInt("EtiLaenge2", Etikettenlaenge[2]);
  preferences.putBool("MitBuzzer0", MitBuzzer[0]);
  preferences.putBool("MitBuzzer1", MitBuzzer[1]);
  preferences.putBool("MitBuzzer2", MitBuzzer[2]);
  preferences.putUInt("Counter0", Counter[0]);
  preferences.putUInt("Counter1", Counter[1]);
  preferences.putUInt("Counter2", Counter[2]);
  preferences.putUInt("MaxSpeed0", MaxSpeed[0]);
  preferences.putUInt("MaxSpeed1", MaxSpeed[1]);
  preferences.putUInt("MaxSpeed2", MaxSpeed[2]);
  preferences.putUInt("Acceleration0", Acceleration[0]);
  preferences.putUInt("Acceleration1", Acceleration[1]);
  preferences.putUInt("Acceleration2", Acceleration[2]);
  preferences.putBool("MitFuss0", MitFuss[0]);
  preferences.putBool("MitFuss1", MitFuss[1]);
  preferences.putBool("MitFuss2", MitFuss[2]);
  preferences.putBool("MitDruck0", MitDruck[0]);
  preferences.putBool("MitDruck1", MitDruck[1]);
  preferences.putBool("MitDruck2", MitDruck[2]);
  preferences.putUInt("ZeitBisDruck0", ZeitBisDatumDruck[0]);
  preferences.putUInt("ZeitBisDruck1", ZeitBisDatumDruck[1]);
  preferences.putUInt("ZeitBisDruck2", ZeitBisDatumDruck[2]);
  preferences.putUInt("MitLuft0", MitLuft[0]);
  preferences.putUInt("MitLuft1", MitLuft[1]);
  preferences.putUInt("MitLuft2", MitLuft[2]);
  preferences.putUInt("TrockenZeit0", DruckTrockenZeit[0]);
  preferences.putUInt("TrockenZeit1", DruckTrockenZeit[1]);
  preferences.putUInt("TrockenZeit2", DruckTrockenZeit[2]);
  preferences.end();

#endif

/*
#if myDEBUG
  Serial.println(F("EE_Writing"));
  Serial.print( F("Aktuelles Etikett: ") );
  Serial.println(AktuellesEtikett + 1);

  for (int d = 0; d < 3; d++)
  {
    Serial.print( F("Etikettenlaenge") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(Etikettenlaenge[d]);

    Serial.print( F("ZeitBisDatumDruck") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(ZeitBisDatumDruck[d]);

    Serial.print( F("Buzzer") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(MitBuzzer[d]);

    Serial.print( F("Counter") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(Counter[d]);

    Serial.print( F("DruckOption") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(MitDruck[d]);

    Serial.print( F("DruckTrockenZeit") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(DruckTrockenZeit[d]);

    Serial.print( F("Lüfter") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(MitLuft[d]);

    Serial.println();
  }

#endif
*/
}
//----------------------------------------------------------------


//----------------------------------------------------------------
// Lese aus Memory
//----------------------------------------------------------------
void ReadMem() {

#if mySYSTEM //Arduino NANO
  byte low, high, set;
  byte  AnzahlWerte = 23;
  set = EEPROM.read(0);

  if (set == 99) //Gibt es bereits Daten im EEPROM?
  {
    for (int r = 0; r < 3; r++) //Position 1-69
    {
      low = EEPROM.read(1 + (r * AnzahlWerte));
      high = EEPROM.read(2 + (r * AnzahlWerte));
      Etikettenlaenge[r]  = low + ((high << 8) & 0xFF00);

      MitBuzzer[r] = EEPROM.read(3 + (r * AnzahlWerte));

      low = EEPROM.read(4 + (r * AnzahlWerte));
      high = EEPROM.read(5 + (r * AnzahlWerte));
      Counter[r]  = low + ((high << 8) & 0xFF00);

      low = EEPROM.read(6 + (r * AnzahlWerte));
      high = EEPROM.read(7 + (r * AnzahlWerte));
      MaxSpeed[r]  = low + ((high << 8) & 0xFF00);

      low = EEPROM.read(8 + (r * AnzahlWerte));
      high = EEPROM.read(9 + (r * AnzahlWerte));
      Acceleration[r]  = low + ((high << 8) & 0xFF00);

      MitFuss[r] = EEPROM.read(10 + (r * AnzahlWerte));

      MitDruck[r] = EEPROM.read(11 + (r * AnzahlWerte));

      low = EEPROM.read(12 + (r * AnzahlWerte));
      high = EEPROM.read(13 + (r * AnzahlWerte));
      ZeitBisDatumDruck[r]  = low + ((high << 8) & 0xFF00);


      low = EEPROM.read(20 + (r * AnzahlWerte));
      high = EEPROM.read(21 + (r * AnzahlWerte));
      MitLuft[r]  = low + ((high << 8) & 0xFF00);

      low = EEPROM.read(22 + (r * AnzahlWerte));
      high = EEPROM.read(23 + (r * AnzahlWerte));
      DruckTrockenZeit[r]  = low + ((high << 8) & 0xFF00);
    }
    AktuellesEtikett = EEPROM.read(70);
  }

#else //ESP32


  preferences.begin("EEPROM", false);

  AktuellesEtikett = preferences.getUInt("AktEtikett", 0);

  Etikettenlaenge[0] = preferences.getUInt("EtiLaenge0", 500);
  Etikettenlaenge[1] = preferences.getUInt("EtiLaenge1", 1000);
  Etikettenlaenge[2] = preferences.getUInt("EtiLaenge2", 2000);

  ZeitBisDatumDruck[0] = preferences.getUInt("ZeitBisDruck0", 250);
  ZeitBisDatumDruck[1] = preferences.getUInt("ZeitBisDruck1", 500);
  ZeitBisDatumDruck[2] = preferences.getUInt("ZeitBisDruck2", 1000);

  MitBuzzer[0] = preferences.getBool("MitBuzzer0", 1);
  MitBuzzer[1] = preferences.getBool("MitBuzzer1", 0);
  MitBuzzer[2] = preferences.getBool("MitBuzzer2", 0);

  Counter[0] = preferences.getUInt("Counter0", 0);
  Counter[1] = preferences.getUInt("Counter1", 0);
  Counter[2] = preferences.getUInt("Counter2", 0);

  MaxSpeed[0] = preferences.getUInt("MaxSpeed0", 1000);
  MaxSpeed[1] = preferences.getUInt("MaxSpeed1", 1000);
  MaxSpeed[2] = preferences.getUInt("MaxSpeed", 1000);

  Acceleration[0] = preferences.getUInt("Acceleration0", 0);
  Acceleration[1] = preferences.getUInt("Acceleration1", 0);
  Acceleration[2] = preferences.getUInt("Acceleration2", 0);

  MitFuss[0] = preferences.getBool("MitFuss0", 0);
  MitFuss[1] = preferences.getBool("MitFuss1", 0);
  MitFuss[2] = preferences.getBool("MitFuss2", 0);

  MitDruck[0] = preferences.getBool("MitDruck0", 0);
  MitDruck[1] = preferences.getBool("MitDruck1", 0);
  MitDruck[2] = preferences.getBool("MitDruck2", 0);



  MitLuft[0] = preferences.getUInt("MitLuft0", 0);
  MitLuft[1] = preferences.getUInt("MitLuft1", 0);
  MitLuft[2] = preferences.getUInt("MitLuft2", 0);

  DruckTrockenZeit[0] = preferences.getUInt("TrockenZeit0", 0);
  DruckTrockenZeit[1] = preferences.getUInt("TrockenZeit1", 0);
  DruckTrockenZeit[2] = preferences.getUInt("TrockenZeit2", 0);
  // preferences.clear();  Falls mal mal das EE-Prom leeren will
  preferences.end();

#endif

/*
#if myDEBUG
  Serial.println(F("EE_Reading"));
  Serial.print( F("Aktuelles Etikett: ") );
  Serial.println(AktuellesEtikett + 1);

  for (int d = 0; d < 3; d++)
  {
    Serial.print( F("Etikettenlaenge") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(Etikettenlaenge[d]);
    Serial.print( F("ZeitBisDatumDruck") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(ZeitBisDatumDruck[d]);

    Serial.print(d + 1);
    Serial.print( F(": ") );



    Serial.print( F("MitDruck") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(MitDruck[d]);

    Serial.print( F("MitLuft") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    if (MitLuft[d] > 10) MitLuft[d] = 10;
    Serial.println(MitLuft[d]);

    Serial.print( F("DruckTrockenZeit") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.print(DruckTrockenZeit[d]);
    Serial.print( F(" / ") );
    if (DruckTrockenZeit[d] > 60) DruckTrockenZeit[d] = 60;
    Serial.println(DruckTrockenZeit[d]);

    Serial.print( F("Buzzer") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(MitBuzzer[d]);
    Serial.println();
  }


#endif
*/
}

Im folgenden Abschnitt kann ich den Motor durch drehen des Small Rotary vor und zurück bewegen

//----------------------------------------------------------------
// DIREKTE MOTORANSTEUERUNG: VORWÄRTS UND RÜCKWÄRTS ZUM JUSTIEREN
//----------------------------------------------------------------
void Handsteuerung()
{
  String SpeedAnzeige;
  neuePositionSmallRotary = LeseSmallRotaryWert();
  if (neuePositionSmallRotary != altePositionSmallRotary)
  {
    Serial.print("Neue Position SmallRotary: "); 
    Serial.println(neuePositionSmallRotary);
    
    u8g2.setDrawColor(0);
    u8g2.drawBox(0, 37, 128, 16); //löschen der Zeile
    u8g2.setDrawColor(1);
    u8g2.setCursor(1, 50);
    if  (neuePositionSmallRotary > 0)
    {

      if (neuePositionSmallRotary > 8)
      {
        SetzeSmallRotaryWert(9);
        neuePositionSmallRotary = 9;
      }
      SpeedAnzeige = String(neuePositionSmallRotary) + " ";
      MotorVor(neuePositionSmallRotary);
      for (int i = 1; i <= neuePositionSmallRotary; i++)
      {
        SpeedAnzeige = SpeedAnzeige + ">";
      }
    }
    else if (neuePositionSmallRotary < 0)
    {

      if (neuePositionSmallRotary < -8)
      {
        SetzeSmallRotaryWert(-9);
        neuePositionSmallRotary = -9;
      }
      SpeedAnzeige = String(-neuePositionSmallRotary) + " ";
      MotorRueck(-neuePositionSmallRotary);
      for (int i = -1; i >= neuePositionSmallRotary; i--)
      {
        SpeedAnzeige = SpeedAnzeige + "<";
      }
    }
    else
    {
      if (MitFuss[AktuellesEtikett]) SpeedAnzeige = "<FussT>";
      else SpeedAnzeige = "GlasDrauf";
      MotorStop();
    }



    u8g2.print(SpeedAnzeige);
    u8g2.sendBuffer();
    altePositionSmallRotary = neuePositionSmallRotary;
    PositionSmallRotary = neuePositionSmallRotary;
  }
#if !myDRIVE
  if (PositionSmallRotary != 0)
  {
    stepper.setEnablePin(MotorEnable_PIN);
    int SpeedOutput;
    if (PositionSmallRotary > 0) SpeedOutput = MaxSpeed[AktuellesEtikett] * 100 * PositionSmallRotary / 9;
    else SpeedOutput = -(MaxSpeed[AktuellesEtikett] * 100 * abs(PositionSmallRotary) / 9);
    stepper.setSpeed(SpeedOutput);
    stepper.runSpeed();
  }
  else stepper.disableOutputs();
#endif

}

Im Seriellen Monitor sehe ich folgendes

Neue Position SmallRotary: 1
MotorVor - Speed: 1
SpeedOutput: 95
Motor vorwärts - mit 0%
Neue Position SmallRotary: 2
MotorVor - Speed: 2
SpeedOutput: 115
Motor vorwärts - mit 0%
Neue Position SmallRotary: 1
MotorVor - Speed: 1
SpeedOutput: 95
Motor vorwärts - mit 0%
Neue Position SmallRotary: 2
MotorVor - Speed: 2
SpeedOutput: 115
Motor vorwärts - mit 0%

Der Abschnitt im Quellcode wo ich den Rotary drehe und der Motor sich nicht bewegt ist

void PositionAnfahren() {
  int oldPositionSmallRotary = 0;
  Entprellen();
  PositionBigRotary = abs(LeseBigRotaryWert());

  SetzeSmallRotaryWert(0);
  SetzeBigRotaryWert(0);
  int OldBig = 99;
  String SpeedAnzeige = "<<Drehregler>>";
  Serial.println("Start PositionAnfahren"); // Neue Debug-Ausgabe

  while (digitalRead(SmallRotary_PIN_SW)) {
    neuePositionSmallRotary = LeseSmallRotaryWert();
    Serial.print("Neue Position SmallRotary (innerhalb Schleife): ");
    Serial.println(neuePositionSmallRotary); // zusätzliche Debug-Ausgabe
    
    if (neuePositionSmallRotary != oldPositionSmallRotary) {
      Serial.print("Positionsänderung erkannt: ");
      Serial.println(neuePositionSmallRotary);

      u8g2.setDrawColor(0);
      u8g2.drawBox(0, 49, 128, 14); // löschen der Zeile
      u8g2.setDrawColor(1);
      u8g2.setCursor(1, 60);

      if (neuePositionSmallRotary > 0) {
      if (neuePositionSmallRotary > 8)
      {
        SetzeSmallRotaryWert(9);
        neuePositionSmallRotary = 9;
      }
      SpeedAnzeige = String(neuePositionSmallRotary) + " ";
      MotorVor(neuePositionSmallRotary);
      for (int i = 1; i <= neuePositionSmallRotary; i++)
      {
        SpeedAnzeige = SpeedAnzeige + ">";
      }

        
      } else if (neuePositionSmallRotary < 0) {
        if (neuePositionSmallRotary < -8) {
          SetzeSmallRotaryWert(-9);
          neuePositionSmallRotary = -9;
        }
        SpeedAnzeige = String(-neuePositionSmallRotary) + " ";
        Serial.print("MotorRueck wird aufgerufen mit Geschwindigkeit: ");
        Serial.println(neuePositionSmallRotary); // Debug-Ausgabe
        MotorRueck(neuePositionSmallRotary);
        for (int i = -1; i >= neuePositionSmallRotary; i--) {
          SpeedAnzeige = SpeedAnzeige + "<";
        }
      } else {
        SpeedAnzeige = "<<Drehregler>>";
        Serial.println("MotorStop wird aufgerufen"); // Debug-Ausgabe
        MotorStop();
      }

      u8g2.print(SpeedAnzeige);
      u8g2.sendBuffer();
      oldPositionSmallRotary = neuePositionSmallRotary;
      SetzeSmallRotaryWert(neuePositionSmallRotary);
    }
    PositionBigRotary = abs(LeseBigRotaryWert());

    if (PositionBigRotary != OldBig) {
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.setCursor(1, 15);
      u8g2.print(F("STARTPOSITION:"));
      u8g2.setFont(u8g2_font_courB08_tf);
      u8g2.setCursor(1, 30);
      u8g2.print(F("Etikett bis ans Glas"));
      u8g2.setCursor(1, 45);
      u8g2.print(F("ranfahren -->"));
      u8g2.setCursor(93, 45);
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.print(PositionBigRotary);
      u8g2.setCursor(1, 60);
      u8g2.print(SpeedAnzeige);
      u8g2.sendBuffer();
      OldBig = PositionBigRotary;
    }
  
  Serial.println("Ende PositionAnfahren"); // Neue Debug-Ausgabe



  } //while Taster nicht gedrückt

#if myDEBUG
  Serial.println(F("Startpos gef."));
#endif
  Entprellen();
  SetzeSmallRotaryWert(0);
  SetzeBigRotaryWert(0);
  OldBig = 99;
  SpeedAnzeige = "<<Drehregler>>";
  while (digitalRead(SmallRotary_PIN_SW))
  {
    neuePositionSmallRotary = LeseSmallRotaryWert();
    if (neuePositionSmallRotary != oldPositionSmallRotary)
    {
#if myDEBUG
      Serial.print(F("SmallRot:"));
      Serial.println(neuePositionSmallRotary); // ...soll die aktuelle Position im seriellen Monitor ausgegeben werden.
#endif
      u8g2.setDrawColor(0);
      u8g2.drawBox(0, 49, 128, 14); //löschen der Zeile
      u8g2.setDrawColor(1);
      u8g2.setCursor(1, 60);
      if  (neuePositionSmallRotary > 0)
      {

        if (neuePositionSmallRotary > 8)
        {
          SetzeSmallRotaryWert(9);
          neuePositionSmallRotary = 9;
        }
        SpeedAnzeige = String(neuePositionSmallRotary) + " ";
        MotorVor(neuePositionSmallRotary);
        for (int i = 1; i <= neuePositionSmallRotary; i++)
        {
          SpeedAnzeige = SpeedAnzeige + ">";
        }
      }
      else if (neuePositionSmallRotary < 0)
      {

        if (neuePositionSmallRotary < -8)
        {
          SetzeSmallRotaryWert(-9);
          neuePositionSmallRotary = -9;
        }
        SpeedAnzeige = String(-neuePositionSmallRotary) + " ";
        MotorRueck(-neuePositionSmallRotary);
        for (int i = -1; i >= neuePositionSmallRotary; i--)
        {
          SpeedAnzeige = SpeedAnzeige + "<";
        }
      }
      else
      {
        SpeedAnzeige = "<<Drehregler>>";
        MotorStop();
      }
      u8g2.print(SpeedAnzeige);
      u8g2.sendBuffer();
      oldPositionSmallRotary = neuePositionSmallRotary;
      SetzeSmallRotaryWert(neuePositionSmallRotary);
    }
    PositionBigRotary = abs(LeseBigRotaryWert());

    if (PositionBigRotary != OldBig)
    {
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.setCursor(1, 15);
      if (altePositionSmallRotary == 2)
      {
        u8g2.print(F("END-POSITION:"));
        u8g2.setFont(u8g2_font_courB08_tf);
        u8g2.setCursor(1, 30);
        u8g2.print(F("Etikett ans nächste"));
        u8g2.setCursor(1, 45);
        u8g2.print(F("Glas fahren ->"));
      }
      else
      {
        u8g2.print(F("DRUCK-POSITION:"));
        u8g2.setFont(u8g2_font_courB08_tf);
        u8g2.setCursor(1, 30);
        u8g2.print(F("Etikett an die Druck-"));
        u8g2.setCursor(1, 45);
        u8g2.print(F("Position fahren"));
      }
      u8g2.setCursor(93, 45);
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.print(PositionBigRotary);
      u8g2.setCursor(1, 60);
      u8g2.print(SpeedAnzeige);
      u8g2.sendBuffer();
      OldBig = PositionBigRotary;
    }

  } //while Taster nicht gedrückt

  if (altePositionSmallRotary == 2)
  {
    Etikettenlaenge[AktuellesEtikett] = abs(LeseBigRotaryWert());
#if myDEBUG
    Serial.print(F("Endpos gef."));
    Serial.println(Etikettenlaenge[AktuellesEtikett]);
#endif
  }
  else
  {
    ZeitBisDatumDruck[AktuellesEtikett] = abs(LeseBigRotaryWert());
#if myDEBUG
    Serial.print(F("Druckpos.gef."));
    Serial.println(ZeitBisDatumDruck[AktuellesEtikett]);
    Serial.print(F("alte rotPOs:"));
    Serial.println(altePositionSmallRotary);
#endif
  }
  SetzeSmallRotaryWert(altePositionSmallRotary - 1); // zurück an die richtige Stelle
  altePositionSmallRotary = 99;
  buzzer(BUZZER_LONG);
  EinWertNeu = HIGH;  //EEPROM-Write aktiviert - ein Wert geändert
  Entprellen();
}

Der Motor bewegt sich nicht und im Seriellen Monitor sehe ich

14:51:44.132 -> Ende PositionAnfahren
14:51:44.132 -> Neue Position SmallRotary (innerhalb Schleife): 1
14:51:44.132 -> Ende PositionAnfahren
14:51:44.132 -> Neue Position SmallRotary (innerhalb Schleife): 1
14:51:44.132 -> Ende PositionAnfahren
14:51:44.132 -> Neue Position SmallRotary (innerhalb Schleife): 2
14:51:44.132 -> Positionsänderung erkannt: 2
14:51:44.132 -> MotorVor - Speed: 2
14:51:44.132 -> SpeedOutput: 115
14:51:44.132 -> Motor vorwärts - mit 0%
14:51:44.179 -> Ende PositionAnfahren
14:51:44.179 -> Neue Position SmallRotary (innerhalb Schleife): 2
14:51:44.179 -> Ende PositionAnfahren
14:51:44.179 -> Neue Position SmallRotary (innerhalb Schleife): 2
14:51:44.179 -> Ende PositionAnfahren
14:51:44.179 -> Neue Position SmallRotary (innerhalb Schleife): 2
14:51:44.226 -> Ende PositionAnfahren
14:51:44.226 -> Neue Position SmallRotary (innerhalb Schleife): 2
14:51:44.226 -> Ende PositionAnfahren
14:51:44.226 -> Neue Position SmallRotary (innerhalb Schleife): 2
14:51:44.226 -> Ende PositionAnfahren
14:51:44.226 -> Neue Position SmallRotary (innerhalb Schleife): 2
14:51:44.226 -> Ende PositionAnfahren
14:51:44.226 -> Neue Position SmallRotary (innerhalb Schleife): 2
14:51:44.226 -> Ende PositionAnfahren
14:51:44.226 -> Neue Position SmallRotary (innerhalb Schleife): 2
14:51:44.226 -> Ende PositionAnfahren
14:51:44.226 -> Neue Position SmallRotary (innerhalb Schleife): 2
14:51:44.226 -> Ende PositionAnfahren
14:51:44.226 -> Neue Position SmallRotary (innerhalb Schleife): 2
14:51:44.273 -> Ende PositionAnfahren
14:51:44.273 -> Neue Position SmallRotary (innerhalb Schleife): 2
14:51:44.273 -> Ende PositionAnfahren
14:51:44.273 -> Neue Position SmallRotary (innerhalb Schleife): 2
14:51:44.273 -> Ende PositionAnfahren
14:51:44.273 -> Neue Position SmallRotary (innerhalb Schleife): 2
14:51:44.273 -> Ende PositionAnfahren

Ich hab die verschiedenen Abschnitt wo sich der Motor Vor bzw. Rückwärts bewegen sollte verglichen, hab aber keine Fehler festgestellt. Kann es sein das der Motor deswegen nicht bewegt wird, weil die Abfrage des Rotary zu schnell durchgeführt wird und nicht nur bei Änderung?

Ich finde es ja interessant, wie konsequent mein Hinweis (#21) ignoriert wird, dass eine Menge Speicher vom Controller durch den Frame Buffer der u8g2 Library verbraucht wird.

Das kann durch die Verwendung eines anderen Konstruktors und der Umstellung der Display-Ausgabe geändert werden.

The full buffer F option can be used only, if there is sufficient RAM available in the microcontroller. Use option 1 or 2 on a microcontroller with a small amount of RAM. The u8x8 API can be used if there is not even RAM for one page.

Sorry, das mit der Umstellung auf eine andere Display-Ausgabe war mir zu hoch. Für die Fehlersuche brauch ich die Servo Funktion nicht. Wenn ich den Fehler jemals finde, kann ich die Servo Komponenten wieder einbauen.

Also ich würde als nächstes serial.print() IN die function MotorVor() einbauen.

Lieber @michaelapp

wenn dir die User hier helfen sollen dann solltest du

ausnahmslos IMMER

den kompletten Sketch posten. Auch dann wenn du nur eine einzige Zeile geändert hast.

Es gibt einen html-Befehl mit dem man Text einklappbar / aussklappbar machen kann.
Damit bleibt das Posting schön kurz und trotzdem sind alle aktuellen Infos da.

[details=Titel des Abschnitts]
[/details] 


[details=hier der komplette sketch]
[/details] 
hier der komplette sketch für nano-every
// MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START *
// a detailed explanation how these macros work is given in this tutorial
// https://forum.arduino.cc/t/comfortable-serial-debug-output-short-to-write-fixed-text-name-and-content-of-any-variable-code-example/888298

#define dbg(myFixedText, variableName) \
  Serial.print( #myFixedText " "  #variableName"="); \
  Serial.println(variableName);

#define dbgi(myFixedText, variableName,timeInterval) \
  { \
    static unsigned long intervalStartTime; \
    if ( millis() - intervalStartTime >= timeInterval ){ \
      intervalStartTime = millis(); \
      Serial.print( #myFixedText " "  #variableName"="); \
      Serial.println(variableName); \
    } \
  }

#define dbgc(myFixedText, variableName) \
  { \
    static long lastState; \
    if ( lastState != variableName ){ \
      Serial.print( #myFixedText " "  #variableName" changed from "); \
      Serial.print(lastState); \
      Serial.print( F(" to ") ); \
      Serial.println(variableName); \
      lastState = variableName; \
    } \
  }

#define dbgcf(myFixedText, variableName) \
  { \
    static float lastState; \
    if ( lastState != variableName ){ \
      Serial.print( #myFixedText " "  #variableName" changed from "); \
      Serial.print(lastState); \
      Serial.print( " to "); \
      Serial.println(variableName); \
      lastState = variableName; \
    } \
  }
// MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END *

unsigned long MyTestTimer = 0;                   // Timer-variables MUST be of type unsigned long

// Version compiler-Schalter eingestellt für ESP32
/* Universalcode für den Ettimandl (ESP32)  und den EtVonSchleck (Arduino Nano)

  Copyright (C) 2021 Jeremias Bruker
  2021-01-03 Jeremias Bruker| Den Code kann jeder frei verwenden, ändern und hochladen wo er will,
                              solange er nicht seinen eigenen Namen drüber setzt, oder diesen kommerziell verwertet, beispielsweise
                              indem Etikettiermaschinen mit diesem Code versehen und verkauft werden.

  2021-01-03 Jeremias Bruker | initial version,
  2021-01-09 Martin Zahn     | Unterstützung ESP32+Schrittmotor hinzugefügt
  2021-01-16 Jeremias Bruker | Wahl zwischen Schrittmotor und Gleichstrommotor per myDRIVE
  2021-01-21 Johannes Kuder  | Ultraschallsensor anstatt Näherungssensor per mySensor
  2021-01-28 Jeremias Bruker | Etikettenlänge kann während des Labelvorgangs mit dem SmallRotary geändert werden - wird mit E+ oder E- angezeigt
                             | Stepperlaufrichtung kann per define angepasst werden
  2021-01-29 Johannes Kuder  | OTA-Funktionalität für ESP32
  2021-01-29 Jeremias Bruker | Grafik auf U8g2 umgestellt
  2021-02-03 Jeremias Bruker | Fußschalter implementiert
  2021-02-20 Jeremias Bruker | Große Werte können im Menü parallel mit Small und BigRotary verändert werden werden
  2021-02-23 Jeremias Bruker | Die Spannung bzw. Drehzahl des Lüfters kann nun per Software eingestellt werden
  2021-02-25 Jeremias Bruker | Gemeinsame EncoderLib (für Every und ESP32) & Abbruch über Rotary-Button während der Trockenzeit*/

//----------------------------------------------------------------
// Allgemeine Konfiguration DEBUG/GRAFIK/System Information
//----------------------------------------------------------------
#define mySYSTEM            1 //< 0= ESP32           // 1= Arduino Every / 0 = ESP32
#define myDEBUG             1            // 0 = Debug via Serial Monitor
#define myDRIVE             0            // 1 = Gleichstrommotor mit H-Brücke 0 = Schrittmotor
#define mySENSOR            0            // 1 = Ultraschallsensor 0 = kap. Näherungssensor
//---------------------------
#define useOTA              0            // 1 = OTA Funktionalität nutzen
#if useOTA
const char* ssid = "";
const char* password = "";
#endif
//---------------------------
#define StepperLaufrichtung 0           // 0 für senkrechten Aufbau 1 für waagerechten Aufbau
//----------------------------------------------------------------

const char Version[] = "2.6"; //02.03.2021

#if mySYSTEM
//----------------------------------------------------------------
// Pinbelegung Arduino Nano
//----------------------------------------------------------------
// Rotary Encoder klein für Menü-Steuerung
#define SmallRotary_PIN_SW               A0

#define TRIG_PIN                         A1    // falls Ultraschallsensor im Einsatz

#define Buzzer_PIN                       A2
// I2C-Display                           A4   // SDA
// I2C-Display                           A5   // SCL
#define FussSchalter                     A6
#define NaeherungsSensor_PIN             A7    // Ausgang Näherungsschalter oder Ausgang Ultraschallsensor
// Serial                                 0
// Serial                                 1
#define RotaryBig_PIN_A                   2
#define RotaryBig_PIN_B                   3

#define SmallRotary_PIN_A                 4
#define SmallRotary_PIN_B                 5

#define MiniLuefterEnable_PIN             6 //Speed PWM für Lüfter am Gleichstrommotorausgang B
#define MiniLuefter_PIN1                  7 //PinA Motorsteuerung für Lüfter 

#define Motorsteuerung_PIN1               8    // Schrittmotor-->  Motorsteuerung_PIN1 = Step   oder Gleichstrommotor--> Pin A
#define Motorsteuerung_PIN2               9    // Schrittmotor-->  Motorsteuerung_PIN2 = Dir    oder Gleichstrommotor--> Pin B
#define MotorEnable_PIN                   10    // Schrittmotor-->  Enable-Pin                    oder Gleichstrommotor--> Speed PWM MotorA

#define SERVO1_PIN                        12 //Stempel-Servo
#define SERVO2_PIN                        13 //Stempel-Position
//----------------------------------------------------------------
#else
//----------------------------------------------------------------
// Pinbelegung ESP32
//----------------------------------------------------------------
#define MotorEnable_PIN                  14    // Schrittmotor-->  Enable-Pin    oder Gleichstrommotor--> Speed PWM
#define Motorsteuerung_PIN1              33    // Schrittmotor-->  Step          oder Gleichstrommotor--> Pin A
#define Motorsteuerung_PIN2              32    // Schrittmotor-->  Dir           oder Gleichstrommotor--> Pin B

// Rotary Encoder (Inkrementaler Drehgeber für Etikettenposition)
// Grün = A-Phase, Weiß = B-Phase, Rot = Vcc-Leistung +, Schwarz = V0
#define RotaryBig_PIN_A                  16      // A-Phase
#define RotaryBig_PIN_B                  17      // B-Phase


// Rotary Encoder klein für Menü-Steuerung
#define SmallRotary_PIN_SW               13
#define SmallRotary_PIN_A                35 // DT
#define SmallRotary_PIN_B                34 // CLK


// Servo
#define SERVO1_PIN                       19     // Servo für Stempel
#define SERVO2_PIN                       26     // Stempelposition 

// I2C-Display                           21: SDA
// I2C-Display                           22: SCL

// SPI-Display                           18: CLK
// SPI-Display                           19: MISO
// SPI-Display                           23: MOSI
// SPI-Display                            5: CS

#define Buzzer_PIN                       25
#define MiniLuefter_PIN1                  2
#define MiniLuefterEnable_PIN             18 //Speed PWM für Lüfter am Gleichstrommotorausgang B

// Start-Sensor
#define NaeherungsSensor_PIN             23  // Im Fall Ultraschallsensor: ECHO Pin

#define TRIG_PIN                          4  // falls Ultraschallsensor im Einsatz

#define FussSchalter                      5



// OTA
#if useOTA
#include <WiFi.h>
#endif
#if useOTA
#include <ESPmDNS.h>
#endif
#if useOTA
#include <WiFiUdp.h>
#endif
#if useOTA
#include <ArduinoOTA.h>
#endif
#endif
//----------------------------------------------------------------

//----------------------------------------------------------------
// gemeinsame Libs (Nano und ESP)
//----------------------------------------------------------------
#include <Arduino.h>
#include <Encoder.h>          // https://github.com/PaulStoffregen/Encoder
#if !myDRIVE
#include <AccelStepper.h> // für Schrittmotor. https://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html
#endif
//----------------------------------------------------------------


//----------------------------------------------------------------
// diverse ARduino Libs
//----------------------------------------------------------------
#if mySYSTEM
#include <EEPROM.h>           // aus dem Bibliotheksverwalter
#endif

#if mySYSTEM
#include <Servo.h>         // aus dem Bibliotheksverwalter
#endif
//----------------------------------------------------------------


//----------------------------------------------------------------
// diverse ESP32 Libs
//----------------------------------------------------------------
#if !mySYSTEM
#include <Preferences.h>  // für EEPROM
#endif

#if !mySYSTEM
#include <ESP32Servo.h>
#endif
//----------------------------------------------------------------

//----------------------------------------------------------------
// DISPLAY
//----------------------------------------------------------------
#include <Wire.h>             // aus dem Bibliotheksverwalter 
#include <U8g2lib.h>      // aus dem Arduino-Bibliotheksverwalter
#if mySYSTEM
//OLED 1.3 128*64 Breite Version -------------------------------------------------------------------
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); //128*64 BreiteVersion
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
#else
//2.42 Oled 128*64 Große Version -------------------------------------------------------------------
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
#endif

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
//----------------------------------------------------------------



//----------------------------------------------------------------
// Konfiguration SmallRotary
//----------------------------------------------------------------
Encoder SmallRotary(SmallRotary_PIN_A, SmallRotary_PIN_B);

int LeseSmallRotaryWert()
{
  int Wert;
  Wert = SmallRotary.read() / 4;
  return Wert;
}

void SetzeSmallRotaryWert(int Wert)
{
  SmallRotary.write(Wert * 4);
}

//----------------------------------------------------------------


//----------------------------------------------------------------
// Konfiguration Bigrotary
//----------------------------------------------------------------
Encoder BigRotary(RotaryBig_PIN_A, RotaryBig_PIN_B);

int LeseBigRotaryWert()
{
  int Wert;
  Wert = BigRotary.read();
  return Wert;
}

void SetzeBigRotaryWert(int Wert)
{
  BigRotary.write(Wert);
}
//----------------------------------------------------------------


//----------------------------------------------------------------
// Konfiguration Schrittmotor
//----------------------------------------------------------------
#if !myDRIVE
AccelStepper stepper(1, Motorsteuerung_PIN1, Motorsteuerung_PIN2); // Motortyp, Motorsteuerung_PIN1, Motorsteuerung_PIN2
#endif


//----------------------------------------------------------------
// Konfiguration EEPROM ESP32
//----------------------------------------------------------------
#if !mySYSTEM
Preferences preferences;
#endif

//----------------------------------------------------------------
// Konfiguration Servo
//----------------------------------------------------------------
Servo Servo1;
Servo Servo2;
//----------------------------------------------------------------

//----------------------------------------------------------------
// Konfiguration Datentransfer via Serial / FTDI / USB
//----------------------------------------------------------------
#define Serial_Baudrate 115200
//----------------------------------------------------------------

//----------------------------------------------------------------
// Konfiguration Buzzer
//----------------------------------------------------------------
#define BUZZER_SHORT   1
#define BUZZER_LONG    2
#define BUZZER_SUCCESS 3
#define BUZZER_ERROR   4
//----------------------------------------------------------------

//----------------------------------------------------------------
// Variablen
//----------------------------------------------------------------

int hand_steps = 400; // variable Schrittweite, original 40
unsigned int n_pings = 10; // Anzahl Einzelmessungen Ultraschallsensor zur Mittelwertbildung
float Schwelle = 2;    // Grenzabstand in cm an dem Glas erkannt wird


volatile int PositionBigRotary;
int altePositionBigRotary   = 0;    // Def der "alten" RotaryPosition
volatile int PositionSmallRotary;
int altePositionSmallRotary = 0;  // Def der "alten" RotaryPosition
int neuePositionSmallRotary = 0;  // Def der "alten" RotaryPosition
bool altePositionNaeherung = HIGH;//kein Glas aufgelegt
long Fortschritt;
long AlterFortschritt = 0;
bool EinWertNeu = LOW; //Anzeiger, ob EEPROM beschrieben werden soll
bool HandModus = LOW;
char  Ausgabe[30];

//Menüwerte
unsigned int AktuellesEtikett = 0;
unsigned int Etikettenlaenge[] = {500 , 1000 , 2000 };
unsigned int ZeitBisDatumDruck[] = {250 , 500 , 1000 };
unsigned int Counter[] = {0 , 0 , 0}; // Anzahl der
bool MitBuzzer[] = {LOW, LOW, LOW}; //Soll der Buzzer aktiv sein
bool MitFuss[] = {LOW, LOW, LOW}; //Soll der Fußschalter aktiv sein
bool MitDruck[] = {LOW, LOW, LOW}; //Soll überhaupt auf das Etikett gedruckt werden?
unsigned int Servo1PositionOben[]  = {90, 90, 90};
unsigned int Servo1PositionUnten[] = {90, 90, 90};
unsigned int Servo2Position[]      = {90, 90, 90};
unsigned int DruckTrockenZeit[]    = {1, 1, 1}; //Sekunden nach dem Druck warten, damit die Tinte trocknen kann
unsigned int MitLuft[]  = {0, 0, 0}; // Spannung des Lüfters in %(Versorgungsspannung Motor) 0 = inaktiv 10 = 100 %


// Schrittmotoreinstellungen
unsigned int MaxSpeed[] = {10, 10, 10};                   // Schrittmotor Maximalgeschwindigkeit, wird im Code mit 100 multipliziert
unsigned int Acceleration[] = {5, 5, 5};                  // Schrittmotor Beschleunigung (höher = schneller)  wird im Code mit 100 multipliziert
//int Speed = 1000;                                         // Schrittmotor Geschwindigkeit für Handbetrieb
int LastSteps = 20000;                      // Gefahrene Schritte des Schrittmotors beim letzten Etikettiervorgang
int LastStepsPrint = 18000;                 // Gefahrene Schritte des Schrittmotors beim letzten Etikettiervorgang
#if myDRIVE
int DriveJump = 2; //Menüpunkte vom Schrittmotor ausblenden
#else
int DriveJump = 0;
#endif

//################################################# SETUP #############################################

void setup() {
#if myDEBUG
  Serial.begin(Serial_Baudrate);
  Serial.print("Starte Setup -");
  Serial.println(Version);
#endif
  delay(100);

  ReadMem(); //Werte aus EE_Prom einlesen

  Wire.begin();
  //Wire.setClock(400000L);

  u8g2.begin();
  u8g2.enableUTF8Print();

  //print_logo();


#if !mySYSTEM
  // OTA -------------------------------------------------
#if useOTA
#if myDEBUG
  Serial.println("Starte OTA");
#endif
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println( "Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
  }

  WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE); // required to set hostname properly
#if mySYSTEM
  WiFi.setHostname("EtVomSchleck");
#else
  WiFi.setHostname("EttiMandl");
#endif

  ArduinoOTA
  .onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH)
      type = "sketch";
    else // U_SPIFFS
      type = "filesystem";

#if myDEBUG
    Serial.println( "Start updating " + type);
#endif

    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_courB12_tf);
    u8g2.setCursor(1, 15);
    u8g2.print("Receiving");
    u8g2.setCursor(1, 35);
    u8g2.print("OTA Update");
    u8g2.sendBuffer();
  })
  .onEnd([]() {
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_courB12_tf);
    u8g2.setCursor(1, 15);
    u8g2.print("Receiving");
    u8g2.setCursor(1, 35);
    u8g2.print("OTA Update");
    u8g2.setCursor(1, 55);
    u8g2.print("Done !");
    u8g2.sendBuffer();
  })
  .onProgress([](unsigned int progress, unsigned int total) {
#if myDEBUG
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
#endif
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_courB12_tf);
    u8g2.setCursor(1, 15);
    u8g2.print("Receiving");
    u8g2.setCursor(1, 35);
    u8g2.print("OTA Update");
    u8g2.setCursor(1, 55);
    u8g2.printf("Progress: %u%%\r", (progress / (total / 100)));
    u8g2.sendBuffer();
  })
  .onError([](ota_error_t error) {
#if myDEBUG
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR)
      Serial.println( "Auth Failed");
    else if (error == OTA_BEGIN_ERROR)
      Serial.println( "Begin Failed");
    else if (error == OTA_CONNECT_ERROR)
      Serial.println( "Connect Failed");
    else if (error == OTA_RECEIVE_ERROR)
      Serial.println( "Receive Failed");
    else if (error == OTA_END_ERROR)
      Serial.println( "End Failed");
#endif
  });

  ArduinoOTA.begin();

#if myDEBUG
  Serial.println( "Ready") ;
  Serial.print( "IP") ;
  Serial.println(WiFi.localIP());
#endif
#endif

  // Ende OTA
#endif

  //----------------------------------------------------------------
  //Setup Fußschalter
  //----------------------------------------------------------------
  pinMode(FussSchalter, INPUT_PULLUP);
  //----------------------------------------------------------------



#if myDRIVE
  //----------------------------------------------------------------
  //Setup Motorsteuerung
  //----------------------------------------------------------------

  digitalWrite(Motorsteuerung_PIN1, LOW);
  digitalWrite(Motorsteuerung_PIN2, LOW);
  pinMode(Motorsteuerung_PIN1, OUTPUT);
  pinMode(Motorsteuerung_PIN2, OUTPUT);
  pinMode(MotorEnable_PIN, OUTPUT);
  digitalWrite(MotorEnable_PIN, HIGH); // Kann erstmal aktiv sein
  //----------------------------------------------------------------
#else
  //----------------------------------------------------------------
  //Setup Schrittmotorsteuerung
  //----------------------------------------------------------------
  stepper.setEnablePin(MotorEnable_PIN);
  stepper.setPinsInverted(StepperLaufrichtung, false, true); // directioninvert, stepinvert, enableinvert
  stepper.setMaxSpeed(MaxSpeed[AktuellesEtikett] * 100); // Maximale Geschwindigkeit
  //stepper.setAcceleration(Acceleration[AktuellesEtikett]*100); // Beschleunigung
  //stepper.setCurrentPosition(0);
#endif
  //----------------------------------------------------------------


  //----------------------------------------------------------------
  // Setup MiniLuefter
  //----------------------------------------------------------------
  pinMode(MiniLuefter_PIN1, OUTPUT);
  pinMode(MiniLuefterEnable_PIN, OUTPUT);
  digitalWrite(MiniLuefter_PIN1, LOW);
#if mySYSTEM
  analogWrite(MiniLuefterEnable_PIN, MitLuft[AktuellesEtikett] * 25);
#else
  ledcSetup(0, 5000, 8);
  ledcAttachPin(MiniLuefterEnable_PIN, 0);
  ledcWrite(0, 125);
#endif

  //----------------------------------------------------------------


  //----------------------------------------------------------------
  //Setup MiniRotarySwitch
  //----------------------------------------------------------------
  pinMode(SmallRotary_PIN_SW, INPUT);
  //----------------------------------------------------------------


  //----------------------------------------------------------------
  // Konfiguration Servo
  //----------------------------------------------------------------
  Servo1.attach(SERVO1_PIN);
  Servo2.attach(SERVO2_PIN);
  Servo1.write(Servo1PositionOben[AktuellesEtikett]);
  Servo2.write(Servo2Position[AktuellesEtikett]);
  //----------------------------------------------------------------

  //----------------------------------------------------------------
  // Konfiguration Buzzer
  //----------------------------------------------------------------
  pinMode(Buzzer_PIN, OUTPUT);
  if (MitBuzzer[0] || MitBuzzer[1] || MitBuzzer[2])
  {
    buzzer(BUZZER_LONG);
  }
  //----------------------------------------------------------------


  //----------------------------------------------------------------
  // Konfiguration Ultraschallsensor
  //----------------------------------------------------------------
  pinMode(TRIG_PIN, OUTPUT);

}   //-----------SETUP ENDE----------------------------------------------------------------



void loop()
{
#if !mySYSTEM
#if useOTA
  ArduinoOTA.handle();
#endif
#endif

  Einstellungsmenue(); //Mit RotarySwitch ins Menü rein
  Handsteuerung(); // Mit RotaryDrehen ---> Motor Vor und Motor zurück

  //------------------------------------------------------------
  // BEREIT-MODUS  Abfrage Näherungsschalter und eventuell Etikettieren!
  //------------------------------------------------------------

#if mySENSOR // Ultraschallsensor
  bool neuePositionNaeherung = !Ultraschallsensor(Schwelle);

#else // Abstandssensor
  bool neuePositionNaeherung = digitalRead(NaeherungsSensor_PIN);
#endif

  if (MitFuss[AktuellesEtikett])
  {
    if (!digitalRead(FussSchalter))  // Fußschalter wurde eventuell gedrückt
    {
      buzzer(BUZZER_LONG);
      if (!digitalRead(FussSchalter))  // Fußschalter wurde gedrückt !
      {
#if myDEBUG
        Serial.println("FußSchalter");
#endif
        Etikettieren();
        for (int i = 0; i <= 3; i++)
        {
          buzzer(BUZZER_LONG);
          delay(200);
        }
      }
    }
  }
  else if (neuePositionNaeherung != altePositionNaeherung)  // Sollte die neue Position ungleich der alten sein...
  {
    altePositionNaeherung = neuePositionNaeherung;
    if (neuePositionNaeherung == LOW)
    {
      buzzer(BUZZER_LONG);
#if myDEBUG
      Serial.println( "Glas erkannt!");
#endif
      if (neuePositionNaeherung == LOW) Etikettieren(); // Falls Glas immer noch liegt
      for (int i = 0; i <= 2; i++)
      {
        buzzer(BUZZER_SHORT);
        delay(200);
      }

    }
  }

}//ENDE LOOP-------------------------------------------------------



//----------------------------------------------------------------
// Etikettiervorgang
//----------------------------------------------------------------
void Etikettieren()
{
  SetzeBigRotaryWert(0); //RESET
  PositionBigRotary = 0;
  bool Gedruckt = LOW;
  int LiveLaengenWert = 0;

  DisplayEtikettieren(0); //Start mit 0 Prozent

#if !myDRIVE // Für Schrittmotor

  stepper.enableOutputs();
  stepper.setCurrentPosition(0);
  stepper.setAcceleration(Acceleration[AktuellesEtikett] * 100); // ggf brauch man das hier nicht nochmal.
  stepper.setMaxSpeed(MaxSpeed[AktuellesEtikett] * 100); // Maximale Geschwindigkeit
  stepper.moveTo(LastSteps * 1.02); //

  if (MitDruck[AktuellesEtikett]) stepper.moveTo(LastStepsPrint * 1.02);

#if myDEBUG
  Serial.println( "Vorber.") ;
  Serial.print( "Acc");
  Serial.println(Acceleration[AktuellesEtikett]);
  Serial.print( "Speed");
  Serial.println(MaxSpeed[AktuellesEtikett] * 100
                );
  Serial.print( "LastStepsPrint");
  Serial.println(LastStepsPrint);
  Serial.print( "LastSteps: ");
  Serial.println(LastSteps);
#endif
#endif


  bool Notstop = LOW;
  MotorVor(11); //Starten

  altePositionSmallRotary = 0;
  SetzeSmallRotaryWert(0);

  bool LiveRotAenderung = false;
  bool RotAenderung = false;
  while (abs(PositionBigRotary) <= Etikettenlaenge[AktuellesEtikett]) //Etikettierung starten
  {

    bool FortschrittAenderung = false;
#if !myDRIVE
    stepper.run();
    if (stepper.speed() <= (MaxSpeed[AktuellesEtikett] * 100) / 4 && stepper.distanceToGo() < 20)
      stepper.setSpeed(MaxSpeed[AktuellesEtikett] * 100 / 4);
    stepper.runSpeed();
#endif

    neuePositionSmallRotary = LeseSmallRotaryWert();

    if (neuePositionSmallRotary != altePositionSmallRotary)
    {
      Etikettenlaenge[AktuellesEtikett] +=  neuePositionSmallRotary;
      LiveLaengenWert +=  neuePositionSmallRotary;
      SetzeSmallRotaryWert(0);
      LiveRotAenderung = true;
      RotAenderung = true;
    }


    Fortschritt = abs((((long)(PositionBigRotary) * 100) / (long)(Etikettenlaenge[AktuellesEtikett])));

#if mySYSTEM
    if (Fortschritt != AlterFortschritt || LiveRotAenderung == true) //Zeigt jeden Prozentfortschritt an
#else  //Der Schrittmotor wird gestört bei Grafikausgabe
    if (abs(Fortschritt - AlterFortschritt) >= 10 || LiveRotAenderung == true)  //Zeigt nur jeden zehnten Prozentfortschritt an
#endif
    {
      u8g2.setDrawColor(0);       //Zum Löschen der alten Zeichen
      u8g2.drawBox(0, 35, 128, 15); //Zum Löschen der alten Zeichen
      u8g2.setDrawColor(1);      //Zum Löschen der alten Zeichen

      if (RotAenderung)
      {
        u8g2.setCursor(1, 50);
        sprintf(Ausgabe, "E%d", LiveLaengenWert);
        u8g2.print(Ausgabe);
      }
      u8g2.setCursor(43, 50);
      sprintf(Ausgabe, "-->%3d\n%%", Fortschritt);
      u8g2.print(Ausgabe);
      u8g2.sendBuffer();
      LiveRotAenderung = false;
      AlterFortschritt = Fortschritt;
    }


    if ((digitalRead(SmallRotary_PIN_SW) == LOW)) //RotarySwitch während Etikettiervorgang als NOTSTOP
    {
      MotorStop();
#if myDEBUG
      Serial.println("Notstop");
#endif
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_courB14_tf);
      u8g2.setCursor(10, 20);
      u8g2.print("ROTA-STOP");
      u8g2.setCursor(0, 50);
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.print("Glas raus");
      u8g2.sendBuffer();
      Notstop = HIGH;
      buzzer(BUZZER_ERROR);
      Entprellen();
      delay(1000);
      break;
    }  //NOTFALL AUS

    // eventuell Datum Drucken?
    if (MitDruck[AktuellesEtikett])
    {
      if (abs(PositionBigRotary) > ZeitBisDatumDruck[AktuellesEtikett] && Gedruckt == LOW)
      {
        if (MitLuft[AktuellesEtikett] > 0)
        {
#if !mySYSTEM
          ledcWrite(0, MitLuft[AktuellesEtikett] * 25);
#endif

#if mySYSTEM
          analogWrite(MiniLuefterEnable_PIN, MitLuft[AktuellesEtikett] * 25);
#endif
          digitalWrite(MiniLuefter_PIN1, HIGH); //Lüfter starten
        }
#if myDEBUG
        Serial.print("LüfterAn");
#endif
#if !myDRIVE
        LastStepsPrint = stepper.currentPosition();
#endif

        MotorStop(); //warten bis gedruckt
        Drucken();
        Gedruckt = HIGH;
#if !myDRIVE
        stepper.moveTo((LastSteps) * 1.02);
#if myDEBUG
        Serial.println( "Vorber,") ;
        Serial.print( "Acc");
        Serial.println(Acceleration[AktuellesEtikett]);
        Serial.print( "Speed");
        Serial.println(MaxSpeed[AktuellesEtikett] * 100);
        Serial.print( "LastStepsPrint");
        Serial.println(LastStepsPrint);
        Serial.print( "LastSteps");
        Serial.println(LastSteps);
#endif
#endif

        DisplayEtikettieren(Fortschritt);
        MotorVor(11);
      }
    } // mit Druck ende

    altePositionBigRotary = PositionBigRotary;
    PositionBigRotary = LeseBigRotaryWert();
  } // while ende

#if !myDRIVE
  LastSteps = stepper.currentPosition();

#if myDEBUG
  Serial.print("Stepper gefahrener Schritte:");
  Serial.println(LastSteps);
#endif
#endif

  MotorStop(); //Etikettierung beendet


#if !myDRIVE
  stepper.disableOutputs();
#endif


  //Falls Lüfter lief ---> abschalten
  digitalWrite(MiniLuefter_PIN1, LOW);
#if myDEBUG
  Serial.print("LüfterAUS");
#endif
  if (HandModus == LOW)  //Im Handbetrieb diesen Punkt überspringen
  {
    if (Notstop == LOW) //Der Vorgagng lief sauber durch
    {
      u8g2.setCursor(43, 50);
      sprintf(Ausgabe, "-->%3d\n%%", 100);
      u8g2.print(Ausgabe);
      u8g2.sendBuffer();
      delay (1000);
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_courB14_tf);
      u8g2.setCursor(25, 20);
      u8g2.print("FERTIG");
      u8g2.setCursor(0, 50);
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.print("Glas raus");
      u8g2.sendBuffer();
      buzzer(BUZZER_SUCCESS);
      Counter[AktuellesEtikett]++;
    }

#if mySENSOR // Ultraschallsensor
    while (Ultraschallsensor(Schwelle) == HIGH); //GLAS liegt noch drauf
#else
    while (digitalRead(NaeherungsSensor_PIN) == LOW) //GLAS liegt noch drauf
#endif
    {
      delay (100);
    }
    delay (1000);
    if (LiveLaengenWert != 0) WriteMem(); //Etikettenlänge wurde live angepasst
    DisplayNeutral();
  }
}
//ENDE ETIKETTIERVORGANG------------------------------------------

void DisplayEtikettieren(int Fortschrittswert)
{
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_courB10_tf);
  u8g2.setCursor(0, 20);
#if mySYSTEM
  u8g2.print("EtVomSchleckn");
#else
  u8g2.print("EttiMandln");
#endif
  u8g2.setCursor(43, 50);
  if (Fortschrittswert > 100) sprintf(Ausgabe, "-->%3d\n%%", "");
  else sprintf(Ausgabe, "-->%3d\n%%", Fortschrittswert);
  u8g2.print(Ausgabe);
  u8g2.sendBuffer();
}

//----------------------------------------------------------------
// DIREKTE MOTORANSTEUERUNG: VORWÄRTS UND RÜCKWÄRTS ZUM JUSTIEREN
//----------------------------------------------------------------
void Handsteuerung()
{
  String SpeedAnzeige;
  neuePositionSmallRotary = LeseSmallRotaryWert();
  if (neuePositionSmallRotary != altePositionSmallRotary)
  {
    u8g2.setDrawColor(0);
    u8g2.drawBox(0, 37, 128, 16); //löschen der Zeile
    u8g2.setDrawColor(1);
    u8g2.setCursor(1, 50);
    if  (neuePositionSmallRotary > 0)
    {

      if (neuePositionSmallRotary > 8)
      {
        SetzeSmallRotaryWert(9);
        neuePositionSmallRotary = 9;
      }
      SpeedAnzeige = String(neuePositionSmallRotary) + " ";
      MotorVor(neuePositionSmallRotary);
      for (int i = 1; i <= neuePositionSmallRotary; i++)
      {
        SpeedAnzeige = SpeedAnzeige + ">";
      }
    }
    else if (neuePositionSmallRotary < 0)
    {

      if (neuePositionSmallRotary < -8)
      {
        SetzeSmallRotaryWert(-9);
        neuePositionSmallRotary = -9;
      }
      SpeedAnzeige = String(-neuePositionSmallRotary) + " ";
      MotorRueck(-neuePositionSmallRotary);
      for (int i = -1; i >= neuePositionSmallRotary; i--)
      {
        SpeedAnzeige = SpeedAnzeige + "<";
      }
    }
    else
    {
      if (MitFuss[AktuellesEtikett]) SpeedAnzeige = "< FussTaster >";
      else SpeedAnzeige = "Glas auflegen";
      MotorStop();
    }



    u8g2.print(SpeedAnzeige);
    u8g2.sendBuffer();
    altePositionSmallRotary = neuePositionSmallRotary;
    PositionSmallRotary = neuePositionSmallRotary;
  }
#if !myDRIVE
  if (PositionSmallRotary != 0)
  {
    stepper.setEnablePin(MotorEnable_PIN);
    int SpeedOutput;
    if (PositionSmallRotary > 0) SpeedOutput = MaxSpeed[AktuellesEtikett] * 100 * PositionSmallRotary / 9;
    else SpeedOutput = -(MaxSpeed[AktuellesEtikett] * 100 * abs(PositionSmallRotary) / 9);
    stepper.setSpeed(SpeedOutput);
    stepper.runSpeed();
  }
  else stepper.disableOutputs();
#endif

}

//------------------------------------------
// Haltbarkeitsdatum Drucken
//------------------------------------------
void Drucken()
{
#if myDEBUG
  Serial.println("Stempeln");
#endif

  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_courB12_tf);
  u8g2.setCursor(20, 20);
  u8g2.print("Stempeln");
  u8g2.setCursor(0, 50);
  u8g2.print("Warte...");
  u8g2.sendBuffer();

  Servo1.write(Servo1PositionUnten[AktuellesEtikett]);
  delay(500);
  Servo1.write(Servo1PositionOben[AktuellesEtikett]);
  // Warten zum Trocknen
  if (DruckTrockenZeit > 0)
  {
    unsigned long AktuelleZeit = millis();
    unsigned int  LetzteAnzeige;

    while (millis() - AktuelleZeit < (DruckTrockenZeit[AktuellesEtikett] * 1000))
    {
      unsigned int LaufZeit =  DruckTrockenZeit[AktuellesEtikett] - int((millis() - AktuelleZeit) / 1000);
      if (LaufZeit != LetzteAnzeige)
      {
        u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_courB12_tf);
        u8g2.setCursor(20, 20);
        u8g2.print("Stempeln");
        u8g2.setCursor(0, 50);
        u8g2.print("Warte...");
        u8g2.print(LaufZeit);
        u8g2.print("sec");
        u8g2.sendBuffer();
        LetzteAnzeige = LaufZeit;
      }
      if ((digitalRead(SmallRotary_PIN_SW) == LOW)) break; //Mit Rotary-Knopfdruck raus aus der Wartezeit
    }
    Entprellen();
  }
}
//----------------------------------------------------------------


//------------------------------------------
// Motor Stop
//------------------------------------------
void MotorStop()
{
#if myDRIVE
  digitalWrite(Motorsteuerung_PIN1, LOW);
  digitalWrite(Motorsteuerung_PIN2, LOW);
#endif

#if myDEBUG
  Serial.print("Motor Stop");
#endif
}

//------------------------------------------
// Motor vorwärts
//------------------------------------------
void MotorVor(int Speed) {
  Serial.print("enter MotorVor speed");
  Serial.println(Speed);
#if myDRIVE
  int SpeedOutput;
  SpeedOutput = 75 + Speed * 20; //erst ab ca 100 dreht der 12V Gleichstrommmotor
  analogWrite(MotorEnable_PIN, SpeedOutput);
  digitalWrite(Motorsteuerung_PIN1, HIGH); //Motor läuft vorwärts
  digitalWrite(Motorsteuerung_PIN2, LOW);
#if myDEBUG
  Serial.print("Motor vorwärts- mit ");
  Serial.print((SpeedOutput * 100) / 255);
  Serial.println("%");
#endif
#endif
  Serial.println("exit MotorVor");

}

//------------------------------------------
// Motor rückwärts
//------------------------------------------
void MotorRueck(int Speed) {
  Serial.print("enter MotorRueck speed");
  Serial.println(Speed);


#if myDRIVE
  int SpeedOutput;
  SpeedOutput = 75 + Speed * 20; //erst ab ca. 100 dreht der 12V Gleichstrommmotor
  analogWrite(MotorEnable_PIN, SpeedOutput);
  digitalWrite(Motorsteuerung_PIN1, LOW);
  digitalWrite(Motorsteuerung_PIN2, HIGH);
#if myDEBUG
  Serial.print("Motor rückwärts: ");
  Serial.println(SpeedOutput);
#endif
#endif
  Serial.println("exit MotorVor");

}

void DisplayNeutral() {
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_courB14_tf);
  u8g2.setCursor(0, 20);
  u8g2.print("Etiketten");
  u8g2.setFont(u8g2_font_courB08_tf);
  u8g2.print(" (");
  u8g2.print(AktuellesEtikett + 1);
  u8g2.print(")");
  u8g2.setCursor(0, 50);
  u8g2.setFont(u8g2_font_courB12_tf);
  if (MitFuss[AktuellesEtikett]) u8g2.print("<FussTaster>");
  else u8g2.print("Glas auflegen");
  u8g2.sendBuffer();
}


//-----------------------------------------------------------------------------------------
//  // Menü Einstellungen
//-----------------------------------------------------------------------------------------
void Einstellungsmenue()
{
  if (digitalRead(SmallRotary_PIN_SW) == LOW)  //Rein ins Menü durch Tastendruck
  {
    //Hauptmenü
    int SpeicherAktuellesEtikett = AktuellesEtikett;
    Entprellen();

    altePositionSmallRotary = 99;
    SetzeSmallRotaryWert(AktuellesEtikett); //RESET
    while (digitalRead(SmallRotary_PIN_SW))
    {
      neuePositionSmallRotary = LeseSmallRotaryWert();
      if (neuePositionSmallRotary != altePositionSmallRotary)
      {
        if (neuePositionSmallRotary > 2)
        {
          neuePositionSmallRotary = 2;
          SetzeSmallRotaryWert(2);
        }
        if (neuePositionSmallRotary < 0)
        {
          neuePositionSmallRotary = 0;
          SetzeSmallRotaryWert(0);
        }
        altePositionSmallRotary = neuePositionSmallRotary;
        AktuellesEtikett = neuePositionSmallRotary;
        u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_courB08_tf);
        u8g2.setCursor(0, 10);
        u8g2.print("Einstellungen für");
        u8g2.drawLine(0, 16, 128, 16); //horiz. Linie
        u8g2.setFontMode(0);

        for (int d = 1; d < 4; d++)
        {
          u8g2.setFont(u8g2_font_courB08_tf);
          sprintf(Ausgabe, "%d)", d);
          u8g2.setCursor(0, d * 15 + 15);
          if (d == AktuellesEtikett + 1)
          {
            u8g2.drawBox(0, d * 15 + 6, 10, 11);
            u8g2.setDrawColor(0);
          }
          u8g2.print(Ausgabe);
          u8g2.setDrawColor(1);
          u8g2.setFont(u8g2_font_courB10_tf);
          u8g2.setCursor(12, d * 15 + 15);
          u8g2.print("Etiketten");
          u8g2.setFont(u8g2_font_courB08_tf);
          u8g2.setCursor(98, d * 15 + 15);
          sprintf(Ausgabe, "c:%d", Counter[d - 1]);
          u8g2.print(Ausgabe);
        }
        u8g2.sendBuffer();
        SetzeSmallRotaryWert(AktuellesEtikett); //RESET
      }
    } //while Taster nicht gedrückt
    //AktuellesEtikett = altePositionSmallRotary;
    // Ende Hauptmenü
    buzzer(BUZZER_SHORT);
    if (MitDruck[AktuellesEtikett]) //Servos einstellen für ausgewähltes Etikett
    {
      Servo1.write(Servo1PositionOben[AktuellesEtikett]);
      Servo2.write(Servo2Position[AktuellesEtikett]);
    }
    Entprellen();

    // Untermenü
    char* MenuePunkte[17] = { "Menü verlassen",     // 0
                              "Etikettenlänge",   // 1 + Wert
                              "Etikettenlänge", // 2 Untermenü
                              " Handbetrieb",       // 3 HANDMODUS falls der Näherungssensor nicht funktioniert
                              "    Buzzer",             // 4 Sound aktiv oder inaktiv
                              " Counterwert",       // 5
                              " Schrittmotor",   // 6 Speed
                              " Schrittmotor",   // 7 Acceleration
                              " Fußschalter",     //8 Aktiv Inaktiv
                              "   Drucken",           // 9 + Aktiv oder Inaktiv
                              "Druck-Position",     // 10 +Wert
                              "Druck-Position",// 11 Untermenü
                              " Servo1 Oben",        // 12 +Wert
                              " Servo1 Unten",       // 13 +Wert
                              "Servo2Position",     // 14 +Wert
                              "    Lüfter",           // 15 Inaktiv oder Spannung
                              " Trockenzeit"        // 16 WarteZeit nach Druck in Zehntelsekunden
                            };

    byte AktuellerMenuePunkt = 99;

    altePositionSmallRotary = 99;
    SetzeSmallRotaryWert(0); //RESET

    while (altePositionSmallRotary != 0) //bis Menü verlassen wird
    {

      while (digitalRead(SmallRotary_PIN_SW))
      {
        neuePositionSmallRotary = LeseSmallRotaryWert();
        if (neuePositionSmallRotary < 0)
        {
          neuePositionSmallRotary = 0;
          SetzeSmallRotaryWert(neuePositionSmallRotary);
        }
        if (neuePositionSmallRotary > 16)
        {
          neuePositionSmallRotary = 16;
          SetzeSmallRotaryWert(neuePositionSmallRotary);
        }

        if (MitDruck[AktuellesEtikett] == LOW) neuePositionSmallRotary = neuePositionSmallRotary % 10; //Drucken nicht aktiviert
        else neuePositionSmallRotary = neuePositionSmallRotary % 17;

        if (neuePositionSmallRotary == 6 && altePositionSmallRotary == 5) neuePositionSmallRotary += DriveJump;
        if (neuePositionSmallRotary == 7) neuePositionSmallRotary -=  DriveJump;

        if (neuePositionSmallRotary != altePositionSmallRotary)
        {
#if myDEBUG
          Serial.print("1.UM_neuePositionSmallRotary:");
          Serial.println(neuePositionSmallRotary);
#endif
          u8g2.clearBuffer();
          u8g2.setFont(u8g2_font_courB10_tf);
          u8g2.setCursor(5, 15);
          sprintf(Ausgabe, "Datensatz (%d)", (AktuellesEtikett + 1));
          u8g2.print(Ausgabe);
          u8g2.drawLine(0, 20, 164, 20); //horiz. Linie
          u8g2.setCursor(1, 40);
          u8g2.print(MenuePunkte[neuePositionSmallRotary]);
          u8g2.setCursor(52, 60);

          if (neuePositionSmallRotary == 1) //Etikettenlänge
          {
            u8g2.print(Etikettenlaenge[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 2 || neuePositionSmallRotary == 11) //M)Etikettenlänge
          {
            u8g2.setCursor(1, 60);
            u8g2.print(" man. anfahren");
          }
          if (neuePositionSmallRotary == 3) //Handbetrieb
          {
            u8g2.setCursor(30, 60);
            u8g2.print("Inaktiv");
          }
          if (neuePositionSmallRotary == 4) //Buzzer
          {
            u8g2.setCursor(12, 60);
            if (MitBuzzer[AktuellesEtikett] == LOW) u8g2.print("inaktiv");
            else u8g2.print(" Aktiv");
          }
          if (neuePositionSmallRotary == 5) //Counter
          {
            u8g2.print(Counter[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 6) //SchrittMotor Speed
          {
            u8g2.setCursor(10, 60);
            u8g2.print("Speed");
            u8g2.setCursor(90, 60);
            u8g2.print(MaxSpeed[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 7) //SchrittMotor Acceleration
          {
            u8g2.setCursor(10, 60);
            u8g2.print("Accel.");
            u8g2.setCursor(90, 60);
            u8g2.print(Acceleration[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 8) //Fußschalter
          {
            u8g2.setCursor(12, 60);
            if (MitFuss[AktuellesEtikett] == LOW) u8g2.print("inaktiv");
            else u8g2.print(" Aktiv");
          }
          if (neuePositionSmallRotary == 9) //Drucken
          {
            u8g2.setCursor(12, 60);
            if (MitDruck[AktuellesEtikett] == LOW) u8g2.print("inaktive");
            else u8g2.print(" Aktiv");
          }
          if (neuePositionSmallRotary == 10) //Druckposition
          {
            u8g2.print(ZeitBisDatumDruck[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 12) //Servo1Oben
          {
            u8g2.print(Servo1PositionOben[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 13) //Servo1Unten
          {
            u8g2.print(Servo1PositionUnten[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 14) ////Servo2Pos
          {
            u8g2.print(Servo2Position[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 15) //Lüfter
          {
            u8g2.setCursor(12, 60);
            if (MitLuft[AktuellesEtikett] == 0) u8g2.print("inaktive");
            else
            {
              u8g2.setCursor(48, 60);
              u8g2.print(MitLuft[AktuellesEtikett] * 10);
              u8g2.print("%");
            }
          }
          if (neuePositionSmallRotary == 16)
          {
            u8g2.print(DruckTrockenZeit[AktuellesEtikett]);
            u8g2.print(" sec");
          }
          u8g2.sendBuffer();
          altePositionSmallRotary = neuePositionSmallRotary;
          SetzeSmallRotaryWert(neuePositionSmallRotary);
        }
      } //while Taster nicht gedrückt
      buzzer(BUZZER_SHORT);
      Entprellen();

      // Ende Untermenü


      // Position 1 Etikettenlänge per Wert einstellen
      if  (altePositionSmallRotary == 1) WertAendern(Etikettenlaenge, MenuePunkte[neuePositionSmallRotary]);

      // Position 2 Etikettenlänge (durch Wert Position anfahren) einstellen
      if (altePositionSmallRotary == 2) PositionAnfahren();

      // Position 3 Handbetrieb
      if  (altePositionSmallRotary == 3) Handbetrieb();

      // Position 4 Buzzer generell de-/aktivieren
      if  (altePositionSmallRotary == 4) WertInAktivAendern(MitBuzzer, MenuePunkte[neuePositionSmallRotary]);

      // Position 5 Counter Reset
      if  (altePositionSmallRotary == 5)
      {
        int oldPositionSmallRotary = 99;
        bool ResetCounter = HIGH;
        SetzeSmallRotaryWert(0); //RESET

        while (digitalRead(SmallRotary_PIN_SW))
        {

          neuePositionSmallRotary = LeseSmallRotaryWert();
          if (neuePositionSmallRotary != oldPositionSmallRotary)
          {
            u8g2.drawBox(15, 48, 103, 14);
            u8g2.setDrawColor(0);
            if (!ResetCounter)
            {
              u8g2.setCursor(42, 60);
              u8g2.setDrawColor(0);
              u8g2.print("Reset");
              ResetCounter = HIGH;
            }
            else
            {
              u8g2.setCursor(52, 60);
              u8g2.print(Counter[AktuellesEtikett]);
              ResetCounter = LOW;
            }
            u8g2.setDrawColor(1);
            u8g2.sendBuffer();

            oldPositionSmallRotary = neuePositionSmallRotary;
          }
        } //while Taster nicht gedrückt
        if (ResetCounter)
        {
          Counter[AktuellesEtikett] = 0;
          EinWertNeu = HIGH;  //EEPROM-Write aktiviert - ein Wert geändert
        }
        SetzeSmallRotaryWert(altePositionSmallRotary); // zurück an die richtige Stelle
        altePositionSmallRotary = 99;
        buzzer(BUZZER_LONG);
        Entprellen();
      }

      // Position 6 MaxSpeed
      if  (altePositionSmallRotary == 6) WertAendern(MaxSpeed, MenuePunkte[neuePositionSmallRotary]);

      // Position 7 Acceleration
      if  (altePositionSmallRotary == 7) WertAendern(Acceleration, MenuePunkte[neuePositionSmallRotary]);

      // Position 8 Fußschalter generell de-/aktivieren
      if  (altePositionSmallRotary == 8) WertInAktivAendern(MitFuss, MenuePunkte[neuePositionSmallRotary]);

      // Position 9 Druck de-/aktivieren
      if  (altePositionSmallRotary == 9) WertInAktivAendern(MitDruck, MenuePunkte[neuePositionSmallRotary]);

      // Position 10 ZeitBisDruck per Wert einstellen
      if  (altePositionSmallRotary == 10) WertAendern(ZeitBisDatumDruck, MenuePunkte[neuePositionSmallRotary]);

      // Position 11  ZeitBisDruck per Anfahren einstellen
      if  (altePositionSmallRotary == 11) PositionAnfahren();

      // Position 12 Servo1Oben per Wert einstellen
      if  (altePositionSmallRotary == 12) WertServoAendern(Servo1PositionOben, MenuePunkte[neuePositionSmallRotary]);

      // Position 13 Servo1Oben per Wert einstellen
      if  (altePositionSmallRotary == 13) WertServoAendern(Servo1PositionUnten, MenuePunkte[neuePositionSmallRotary]);

      // Position 14 Servo1Oben per Wert einstellen
      if  (altePositionSmallRotary == 14) WertServoAendern(Servo2Position, MenuePunkte[neuePositionSmallRotary]);

      // Position 15 Lüfter de-/aktivieren bzw Spannung einstellen
      if  (altePositionSmallRotary == 15) WertAendern(MitLuft, MenuePunkte[neuePositionSmallRotary]);

      // Position 16 Druckwartezeit einstellen
      if  (altePositionSmallRotary == 16) WertServoAendern(DruckTrockenZeit, MenuePunkte[neuePositionSmallRotary]);
    }

    //Menü verlassen
    if (SpeicherAktuellesEtikett != AktuellesEtikett) EinWertNeu = HIGH; //Falls nur Etikett geändert auch abspeichern

    if (EinWertNeu)
    {
      WriteMem(); //Daten nur sichern, falls es eine Änderung gab
      //MenueHeader();
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.setCursor(0, 60);
      u8g2.setFont(u8g2_font_courB08_tf);
      u8g2.print("Daten abspeichern...");
      u8g2.sendBuffer();
      for (int p = 0; p < 3; p++)
      {
        buzzer(BUZZER_SHORT);
      }
      EinWertNeu = LOW; //Reset
    }

    Entprellen();
    DisplayNeutral();

    //Es geht in den BEREITmodus zurück
    altePositionSmallRotary = 0; //RESET
    SetzeSmallRotaryWert(0); //RESET
  }
}


void Entprellen()
{
  while (digitalRead(SmallRotary_PIN_SW) == LOW) //ENTPRELLEN
  {
    delay (100);
  }
}

void Handbetrieb()
{
  int oldPositionSmallRotary = 0;
  SetzeSmallRotaryWert(100); //RESET

  Entprellen();
  HandModus = HIGH;
  while (digitalRead(SmallRotary_PIN_SW) && HandModus) //Warte bis RotarySwitch gedrückt und Modus inaktiv
  {
    while (digitalRead(SmallRotary_PIN_SW)) //Warte bis RotarySwitch gedrückt und Modus aktiv
    {
      neuePositionSmallRotary = LeseSmallRotaryWert();
      if (neuePositionSmallRotary != oldPositionSmallRotary)
      {
        u8g2.drawBox(1, 48, 128, 14);
        u8g2.setDrawColor(0);
        if (HandModus)
        {
          HandModus = LOW;
          u8g2.setCursor(30, 60);
          u8g2.print("Inaktiv");
        }
        else
        {
          HandModus = HIGH;
          u8g2.setCursor(1, 60);
          u8g2.print("Press to Start");
        }
        u8g2.setDrawColor(1);
        u8g2.sendBuffer();
        oldPositionSmallRotary = neuePositionSmallRotary;
      }
    } //while Taster nicht gedrückt - innere While-Schleife
    //Tastendruck Auswerten
    Entprellen();
    if (HandModus)
    {
      Etikettieren(); //Vorgang von Hand gestartet
      Entprellen(); // falls Abbruch im Etikettiervorgang
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.setCursor(5, 15);
      sprintf(Ausgabe, "Datensatz (%d)", (AktuellesEtikett + 1));
      u8g2.print(Ausgabe);
      u8g2.drawLine(0, 20, 164, 20); //horiz. Linie
      u8g2.setCursor(1, 40);
      u8g2.print(" Handbetrieb");
      u8g2.setCursor(1, 60);
      u8g2.drawBox(1, 48, 128, 14);
      u8g2.setDrawColor(0);
      u8g2.print("Press to Start");
      u8g2.setDrawColor(1);
      u8g2.sendBuffer();
      oldPositionSmallRotary = neuePositionSmallRotary;
    }
  } //äussere Whileschleife
  SetzeSmallRotaryWert(altePositionSmallRotary); // zurück an die richtige Stelle
  altePositionSmallRotary = 99;
  buzzer(BUZZER_LONG);
}



void WertAendern(unsigned int *Was, char * MenuePunkt)
{
  int AlterWasWert = Was[AktuellesEtikett];
  int oldPositionSmallRotary = 0;
  int oldPositionBigRotary = 0;

  SetzeSmallRotaryWert(Was[AktuellesEtikett]); //RESET
  SetzeBigRotaryWert(0);

  while (digitalRead(SmallRotary_PIN_SW))
  {
    neuePositionSmallRotary = LeseSmallRotaryWert();
    PositionBigRotary = LeseBigRotaryWert();
    if ((neuePositionSmallRotary >= 0) && (neuePositionSmallRotary <= 10000))
    {
      if (neuePositionSmallRotary != oldPositionSmallRotary || PositionBigRotary != oldPositionBigRotary)
      {
        Was[AktuellesEtikett] = neuePositionSmallRotary + PositionBigRotary;
#if myDEBUG
        Serial.print(" neu:");
        Serial.println(Was[AktuellesEtikett]);
#endif
        u8g2.setFont(u8g2_font_courB10_tf);
        u8g2.setCursor(1, 40);
        u8g2.print(MenuePunkt);
        if (altePositionSmallRotary == 6 || altePositionSmallRotary == 7) u8g2.drawBox(80, 48, 108, 14);
        else u8g2.drawBox(10, 48, 108, 14);
        if (altePositionSmallRotary == 6)
        {
          u8g2.setCursor(10, 60);
          u8g2.print("Speed:");
          u8g2.setCursor(90, 60);
        }
        else if (altePositionSmallRotary == 7)
        {
          u8g2.setCursor(10, 60);
          u8g2.print("Accel.");
          u8g2.setCursor(90, 60);
        }
        else u8g2.setCursor(50, 60);
        u8g2.setDrawColor(0);
        if (altePositionSmallRotary == 15)
        {
#if !mySYSTEM
          ledcWrite(0, MitLuft[AktuellesEtikett] * 25);
#endif

#if mySYSTEM
          analogWrite(MiniLuefterEnable_PIN, MitLuft[AktuellesEtikett] * 25);
#endif
          digitalWrite(MiniLuefter_PIN1, HIGH); //Lüfter starten
          if (Was[AktuellesEtikett] < 1)
          {
            u8g2.setCursor(12, 60);
            u8g2.print("inaktiv");
            SetzeSmallRotaryWert(0);
            SetzeBigRotaryWert(0);
            Was[AktuellesEtikett] = 0;
          }
          else
          {
            if (Was[AktuellesEtikett] > 9)
            {
              SetzeSmallRotaryWert(10);
              SetzeBigRotaryWert(0);
              Was[AktuellesEtikett] = 10;
            }
            u8g2.setCursor(48, 60);
            u8g2.print(Was[AktuellesEtikett] * 10);
            u8g2.print("%");
          }
        }
        else u8g2.print(Was[AktuellesEtikett]);
        u8g2.setDrawColor(1);
        u8g2.sendBuffer();
        oldPositionSmallRotary = neuePositionSmallRotary;
        oldPositionBigRotary = PositionBigRotary;
        SetzeSmallRotaryWert(neuePositionSmallRotary);
      }
    }
    EinWertNeu = HIGH;  //EEPROM-Write aktiviert - ein Wert geändert
  } //while Taster nicht gedrückt
  digitalWrite(MiniLuefter_PIN1, LOW); //Lüfter stoppen, falls lief
  SetzeSmallRotaryWert(altePositionSmallRotary); // zurück an die richtige Stelle
  altePositionSmallRotary = 99;
  buzzer(BUZZER_LONG);
  Entprellen();
}


void WertServoAendern(unsigned int *Was, char * MenuePunkt) //Für Servowerte und Drucktrockenzeit
{
  int oldPositionSmallRotary = 0;
  SetzeSmallRotaryWert(Was[AktuellesEtikett]); //RESET

  while (digitalRead(SmallRotary_PIN_SW))
  {
    neuePositionSmallRotary = LeseSmallRotaryWert();
    if ((neuePositionSmallRotary >= 0) && (neuePositionSmallRotary <= 180))
    {
      if (neuePositionSmallRotary != oldPositionSmallRotary)
      {
        Was[AktuellesEtikett] = neuePositionSmallRotary;

#if myDEBUG
        Serial.print("SmRot");
        Serial.println(Was[AktuellesEtikett]);
#endif
        u8g2.setFont(u8g2_font_courB10_tf);
        u8g2.setCursor(1, 40);
        u8g2.print(MenuePunkt);
        u8g2.drawBox(15, 48, 103, 14);
        u8g2.setCursor(52, 60);
        u8g2.setDrawColor(0);
        u8g2.print(Was[AktuellesEtikett]);
        if (altePositionSmallRotary == 16) u8g2.print(" sec"); //WarteZeit nach Druck
        u8g2.setDrawColor(1);
        u8g2.sendBuffer();
        if (altePositionSmallRotary == 12 || altePositionSmallRotary == 13) Servo1.write(Was[AktuellesEtikett]);
        if (altePositionSmallRotary == 14) Servo2.write(Was[AktuellesEtikett]);
        oldPositionSmallRotary = neuePositionSmallRotary;
        SetzeSmallRotaryWert(Was[AktuellesEtikett]);
      }
    }
    EinWertNeu = HIGH;  //EEPROM-Write aktiviert - ein Wert geändert
  } //while Taster nicht gedrückt

  //Falls unterer Servo1Wert eingestellt wurde - Servo automatisch wieder hochfahren
  if (altePositionSmallRotary == 13) Servo1.write(Servo1PositionOben[AktuellesEtikett]);

  SetzeSmallRotaryWert(altePositionSmallRotary); // zurück an die richtige Stelle
  altePositionSmallRotary = 99;
  buzzer(BUZZER_LONG);
  Entprellen();
}



void WertInAktivAendern(bool *Was, char * MenuePunkt) //Für An/Aus-Werte
{
  int oldPositionSmallRotary = 99;
  SetzeSmallRotaryWert(0); //RESET
  while (digitalRead(SmallRotary_PIN_SW))
  {
    neuePositionSmallRotary = LeseSmallRotaryWert();
    if (neuePositionSmallRotary != oldPositionSmallRotary)
    {
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.setCursor(1, 40);
      u8g2.print(MenuePunkt);
      u8g2.setCursor(15, 60);
      u8g2.drawBox(10, 48, 108, 14);
      u8g2.setDrawColor(0);
      if (Was[AktuellesEtikett] == LOW)
      {
        u8g2.print("inaktiv");
        Was[AktuellesEtikett] = HIGH;
      }
      else
      {
        u8g2.print(" Aktiv");
        Was[AktuellesEtikett] = LOW;
      }
      u8g2.setDrawColor(1);
      u8g2.sendBuffer();
      oldPositionSmallRotary = neuePositionSmallRotary;
      SetzeSmallRotaryWert(neuePositionSmallRotary);
      EinWertNeu = HIGH;  //EEPROM-Write aktiviert - ein Wert geändert
    }

  } //while Taster nicht gedrückt
  if (Was[AktuellesEtikett] == LOW) Was[AktuellesEtikett] = HIGH;
  else Was[AktuellesEtikett] = LOW;

  SetzeSmallRotaryWert(altePositionSmallRotary); // zurück an die richtige Stelle
  altePositionSmallRotary = 99;
  buzzer(BUZZER_LONG);
  Entprellen();
}


void PositionAnfahren()
{
  int oldPositionSmallRotary = 0;
  Entprellen();
  PositionBigRotary = abs(LeseBigRotaryWert());

  SetzeSmallRotaryWert(0);
  SetzeBigRotaryWert(0);
  int OldBig = 99;
  String SpeedAnzeige = "<<Drehregler>>";
  while (digitalRead(SmallRotary_PIN_SW))
  {
    neuePositionSmallRotary = LeseSmallRotaryWert();
    if (neuePositionSmallRotary != oldPositionSmallRotary)
    {
      u8g2.setDrawColor(0);
      u8g2.drawBox(0, 49, 128, 14); //löschen der Zeile
      u8g2.setDrawColor(1);
      u8g2.setCursor(1, 60);
      if  (neuePositionSmallRotary > 0)
      {

        if (neuePositionSmallRotary > 8)
        {
          SetzeSmallRotaryWert(9);
          neuePositionSmallRotary = 9;
        }
        SpeedAnzeige = String(neuePositionSmallRotary) + " ";
        MotorVor(neuePositionSmallRotary);
        for (int i = 1; i <= neuePositionSmallRotary; i++)
        {
          SpeedAnzeige = SpeedAnzeige + ">";
        }
      }
      else if (neuePositionSmallRotary < 0)
      {

        if (neuePositionSmallRotary < -8)
        {
          SetzeSmallRotaryWert(-9);
          neuePositionSmallRotary = -9;
        }
        SpeedAnzeige = String(-neuePositionSmallRotary) + " ";
        MotorRueck(-neuePositionSmallRotary);
        for (int i = -1; i >= neuePositionSmallRotary; i--)
        {
          SpeedAnzeige = SpeedAnzeige + "<";
        }
      }
      else
      {
        SpeedAnzeige = "<<Drehregler>>";
        MotorStop();
      }
      u8g2.print(SpeedAnzeige);
      u8g2.sendBuffer();
      oldPositionSmallRotary = neuePositionSmallRotary;
      SetzeSmallRotaryWert(neuePositionSmallRotary);
    }
    PositionBigRotary = abs(LeseBigRotaryWert());

    if (PositionBigRotary != OldBig)
    {
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.setCursor(1, 15);
      u8g2.print("STARTPOS:");
      u8g2.setFont(u8g2_font_courB08_tf);
      u8g2.setCursor(1, 30);
      u8g2.print("Etikett bis Glas");
      u8g2.setCursor(1, 45);
      u8g2.print("ranfahren->");
      u8g2.setCursor(93, 45);
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.print(PositionBigRotary);
      u8g2.setCursor(1, 60);
      u8g2.print(SpeedAnzeige);
      u8g2.sendBuffer();
      OldBig = PositionBigRotary;
    }

  } //while Taster nicht gedrückt

#if myDEBUG
  Serial.println("Startpos. gefunden");
#endif
  Entprellen();
  SetzeSmallRotaryWert(0);
  SetzeBigRotaryWert(0);
  OldBig = 99;
  SpeedAnzeige = "<<Drehregler>>";
  while (digitalRead(SmallRotary_PIN_SW))
  {
    neuePositionSmallRotary = LeseSmallRotaryWert();
    if (neuePositionSmallRotary != oldPositionSmallRotary)
    {
#if myDEBUG
      Serial.print("SmallRotarywert");
      Serial.println(neuePositionSmallRotary); // ...soll die aktuelle Position im seriellen Monitor ausgegeben werden.
#endif
      u8g2.setDrawColor(0);
      u8g2.drawBox(0, 49, 128, 14); //löschen der Zeile
      u8g2.setDrawColor(1);
      u8g2.setCursor(1, 60);
      if  (neuePositionSmallRotary > 0)
      {

        if (neuePositionSmallRotary > 8)
        {
          SetzeSmallRotaryWert(9);
          neuePositionSmallRotary = 9;
        }
        SpeedAnzeige = String(neuePositionSmallRotary) + " ";
        MotorVor(neuePositionSmallRotary);
        for (int i = 1; i <= neuePositionSmallRotary; i++)
        {
          SpeedAnzeige = SpeedAnzeige + ">";
        }
      }
      else if (neuePositionSmallRotary < 0)
      {

        if (neuePositionSmallRotary < -8)
        {
          SetzeSmallRotaryWert(-9);
          neuePositionSmallRotary = -9;
        }
        SpeedAnzeige = String(-neuePositionSmallRotary) + " ";
        MotorRueck(-neuePositionSmallRotary);
        for (int i = -1; i >= neuePositionSmallRotary; i--)
        {
          SpeedAnzeige = SpeedAnzeige + "<";
        }
      }
      else
      {
        SpeedAnzeige = "<<Drehregler>>";
        MotorStop();
      }
      u8g2.print(SpeedAnzeige);
      u8g2.sendBuffer();
      oldPositionSmallRotary = neuePositionSmallRotary;
      SetzeSmallRotaryWert(neuePositionSmallRotary);
    }
    PositionBigRotary = abs(LeseBigRotaryWert());

    if (PositionBigRotary != OldBig)
    {
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.setCursor(1, 15);
      if (altePositionSmallRotary == 2)
      {
        u8g2.print("END-POS");
        u8g2.setFont(u8g2_font_courB08_tf);
        u8g2.setCursor(1, 30);
        u8g2.print("Etikett ans nächste");
        u8g2.setCursor(1, 45);
        u8g2.print("Glas fahren->");
      }
      else
      {
        u8g2.print("DRUCK-POS");
        u8g2.setFont(u8g2_font_courB08_tf);
        u8g2.setCursor(1, 30);
        u8g2.print("Etikett an die Druck-");
        u8g2.setCursor(1, 45);
        u8g2.print("Pos. fahren");
      }
      u8g2.setCursor(93, 45);
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.print(PositionBigRotary);
      u8g2.setCursor(1, 60);
      u8g2.print(SpeedAnzeige);
      u8g2.sendBuffer();
      OldBig = PositionBigRotary;
    }

  } //while Taster nicht gedrückt

  if (altePositionSmallRotary == 2)
  {
    Etikettenlaenge[AktuellesEtikett] = abs(LeseBigRotaryWert());
#if myDEBUG
    Serial.print("Endpos. gefunden");
    Serial.println(Etikettenlaenge[AktuellesEtikett]);
#endif
  }
  else
  {
    ZeitBisDatumDruck[AktuellesEtikett] = abs(LeseBigRotaryWert());
#if myDEBUG
    Serial.print("Druckpos. gefunden:");
    Serial.println(ZeitBisDatumDruck[AktuellesEtikett]);
    Serial.print("alte rotPOs");
    Serial.println(altePositionSmallRotary);
#endif
  }
  SetzeSmallRotaryWert(altePositionSmallRotary - 1); // zurück an die richtige Stelle
  altePositionSmallRotary = 99;
  buzzer(BUZZER_LONG);
  EinWertNeu = HIGH;  //EEPROM-Write aktiviert - ein Wert geändert
  Entprellen();
}


void buzzer(byte type)
{

  pinMode(Buzzer_PIN, OUTPUT);
  delay(100);
  switch (type)
  {
    case BUZZER_SHORT: //short
      if (MitBuzzer[AktuellesEtikett])
      {
        digitalWrite(Buzzer_PIN, HIGH);
        delay(100);
        digitalWrite(Buzzer_PIN, LOW);
      }
      else
      {
        delay(100);
      }
      break;

    case BUZZER_LONG: //long
      if (MitBuzzer[AktuellesEtikett])
      {
        digitalWrite(Buzzer_PIN, HIGH);
        delay(500);
        digitalWrite(Buzzer_PIN, LOW);
      }
      else delay(500);
      break;

    case BUZZER_SUCCESS: //success
      if (MitBuzzer[AktuellesEtikett])
      {
        digitalWrite(Buzzer_PIN, HIGH);
        delay(100);
        digitalWrite(Buzzer_PIN, LOW);
        delay(100);
        digitalWrite(Buzzer_PIN, HIGH);
        delay(100);
        digitalWrite(Buzzer_PIN, LOW);
        delay(100);
        digitalWrite(Buzzer_PIN, HIGH);
        delay(100);
        digitalWrite(Buzzer_PIN, LOW);
      }
      else delay(500);
      break;

    case BUZZER_ERROR: //error
      if (MitBuzzer[AktuellesEtikett])
      {
        digitalWrite(Buzzer_PIN, HIGH);
        delay(1500);
        digitalWrite(Buzzer_PIN, LOW);
      }
      else delay(1500);
      break;
  }
}

bool Ultraschallsensor(float Schwelle) {
  bool glasda = LOW;

  float Abstand = 0; //KUD Abstand initialisieren
  for (int i = 1; i <= n_pings; i++) {
    Abstand = Abstand + get_distance(); //KUD Ultraschallsensor auslesen
  }

  Abstand = Abstand / n_pings; //KUD Mittelwertbildung

  if (Abstand <= Schwelle) {
    glasda = HIGH;
  }

  return (glasda);

}

float get_distance() { //KUD Abstand Glas von Ultraschallsensor
  float duration = 0;
  float distance = 0;

  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  noInterrupts();
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  duration = pulseIn(NaeherungsSensor_PIN, HIGH); // Erfassung - Dauer in Mikrosekunden
  interrupts();

  distance = (duration / 2) / 29.1; // Distanz in CM
  return (distance);
}

//------------------------------------------
// StartLOGO
//------------------------------------------
void print_logo()
{

#if !myDEBUG
  const unsigned char logo_biene1[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0,
    0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x60, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC1, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x70, 0x00, 0xF0, 0xFF, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0x80, 0xF1, 0x47, 0xF0, 0x07, 0x00, 0x3E, 0xE0, 0xFF, 0xFF, 0x07,
    0xF9, 0x07, 0x7E, 0x00, 0x00, 0x78, 0xF0, 0x03, 0xE0, 0x1F, 0xF8, 0x07, 0x1F, 0x00, 0x00, 0x70, 0x3C, 0x00, 0x00, 0xFE, 0x38, 0xC0, 0x03, 0x00,
    0x00, 0xF0, 0x0E, 0x00, 0x00, 0xF8, 0x03, 0xF8, 0x00, 0x00, 0x00, 0xE0, 0x06, 0x00, 0x00, 0xC0, 0x0F, 0x7C, 0x00, 0x00, 0x00, 0xE0, 0x06, 0x00,
    0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x70, 0x03, 0x00, 0x00, 0x00, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x70, 0x03, 0x00, 0x00, 0x00, 0xF0, 0x03,
    0x00, 0x00, 0x00, 0x38, 0x03, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x07, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x07, 0x00, 0x00, 0x0F,
    0x0F, 0x00, 0x00, 0x78, 0x78, 0xE0, 0x3F, 0x00, 0xC0, 0x07, 0x3E, 0x00, 0x80, 0xFF, 0x3C, 0xC0, 0x7F, 0x00, 0xF0, 0x01, 0xFC, 0x00, 0xE0, 0xFF,
    0x1C, 0x80, 0xFF, 0x01, 0x7E, 0x00, 0xF0, 0xFF, 0xFF, 0x3F, 0x0E, 0x00, 0xFE, 0xFF, 0x0F, 0x00, 0xC0, 0xFF, 0xFF, 0x07, 0x0F, 0x00, 0xC0, 0x1F,
    0x00, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x07, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x80, 0x03, 0x80, 0x03, 0xE0, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0,
    0x01, 0xC0, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0xE0, 0x81, 0xC3, 0x01, 0xC0, 0x01, 0x00, 0x00, 0x70, 0x00, 0xE0, 0xF1, 0x8F,
    0x03, 0x80, 0x03, 0x00, 0x00, 0x38, 0x00, 0xF0, 0xFC, 0x9F, 0x07, 0x00, 0x07, 0x00, 0x00, 0x1C, 0x00, 0xF8, 0x1C, 0x1C, 0x0F, 0x00, 0x06, 0x00,
    0x00, 0x1C, 0x00, 0xFE, 0x00, 0x00, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x0E, 0x00, 0xF7, 0x00, 0x00, 0x7F, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x80, 0x73,
    0x00, 0x00, 0xE6, 0x00, 0x0C, 0x00, 0x00, 0x07, 0xE0, 0x71, 0x00, 0x00, 0xC6, 0x03, 0x0C, 0x00, 0x00, 0x07, 0x70, 0x70, 0xF0, 0x0F, 0x86, 0x07,
    0x0C, 0x00, 0x00, 0x03, 0x3C, 0x70, 0xFC, 0x3F, 0x06, 0x1F, 0x0E, 0x00, 0x00, 0x03, 0x1E, 0x70, 0xFE, 0x3F, 0x06, 0xFC, 0x07, 0x00, 0x00, 0x87,
    0x0F, 0x70, 0x1E, 0x38, 0x06, 0xF0, 0x03, 0x00, 0x00, 0xFE, 0x03, 0xF0, 0x00, 0x00, 0x06, 0xC0, 0x00, 0x00, 0x00, 0xFC, 0x00, 0xF0, 0x00, 0x00,
    0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x80, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0x0F, 0x07, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0xE0, 0xF1, 0x9F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x3B, 0x9C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,
    0x07, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x7C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0D,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  };
  u8g2.clearBuffer();          // clear the internal memory
  u8g2.drawXBM(0, 0, 80, 64, logo_biene1);
#else
  u8g2.clearBuffer();          // clear the internal memory
  u8g2.setFont(u8g2_font_courB10_tf);
  u8g2.setCursor(1, 10);    u8g2.print("Achtung:");
  u8g2.setCursor(1, 25);    u8g2.print("Debug");
  u8g2.setCursor(1, 40);    u8g2.print("an!!!");
#endif

  u8g2.setFont(u8g2_font_courB14_tf);
#if mySYSTEM
  u8g2.setCursor(85, 20);    u8g2.print("Et");
  u8g2.setCursor(80, 40);    u8g2.print("Vom");
  u8g2.setCursor(52, 60);    u8g2.print("Schleck");
#else
  u8g2.setCursor(85, 27);    u8g2.print("Etti");
  u8g2.setCursor(73, 43);    u8g2.print("MANDL");
  u8g2.setCursor(85, 54);
#endif
  u8g2.setFont(u8g2_font_courB10_tf);
  u8g2.setCursor(0, 62); u8g2.print(Version);
  u8g2.sendBuffer();
  delay(2000);
  DisplayNeutral();
}



//----------------------------------------------------------------
// Schreibe in Memory
//----------------------------------------------------------------
void WriteMem() {

#if mySYSTEM
  byte low, high, set;
  byte  AnzahlWerte = 23;

  set = 99;
  EEPROM.write(0, set); // Zeichen, dass bereits aktiv beschrieben wurde

  for (int w = 0; w < 3; w++) //Position 1-69
  {
    low = Etikettenlaenge[w] & 0xFF;
    high = (Etikettenlaenge[w] >> 8) & 0xFF;
    EEPROM.write(1 + (w * AnzahlWerte), low);
    EEPROM.write(2 + (w * AnzahlWerte), high);

    EEPROM.write(3 + (w * AnzahlWerte), MitBuzzer[w]);

    low = Counter[w] & 0xFF;
    high = (Counter[w] >> 8) & 0xFF;
    EEPROM.write(4 + (w * AnzahlWerte), low);
    EEPROM.write(5 + (w * AnzahlWerte), high);

    low = MaxSpeed[w] & 0xFF;
    high = (MaxSpeed[w] >> 8) & 0xFF;
    EEPROM.write(6 + (w * AnzahlWerte), low);
    EEPROM.write(7 + (w * AnzahlWerte), high);

    low = Acceleration[w] & 0xFF;
    high = (Acceleration[w] >> 8) & 0xFF;
    EEPROM.write(8 + (w * AnzahlWerte), low);
    EEPROM.write(9 + (w * AnzahlWerte), high);

    EEPROM.write(10 + (w * AnzahlWerte), MitFuss[w]);

    EEPROM.write(11 + (w * AnzahlWerte), MitDruck[w]);

    low = ZeitBisDatumDruck[w] & 0xFF;
    high = (ZeitBisDatumDruck[w] >> 8) & 0xFF;
    EEPROM.write(12 + (w * AnzahlWerte), low);
    EEPROM.write(13 + (w * AnzahlWerte), high);

    low = Servo1PositionOben[w] & 0xFF;
    high = (Servo1PositionOben[w] >> 8) & 0xFF;
    EEPROM.write(14 + (w * AnzahlWerte), low);
    EEPROM.write(15 + (w * AnzahlWerte), high);

    low = Servo1PositionUnten[w] & 0xFF;
    high = (Servo1PositionUnten[w] >> 8) & 0xFF;
    EEPROM.write(16 + (w * AnzahlWerte), low);
    EEPROM.write(17 + (w * AnzahlWerte), high);

    low = Servo2Position[w] & 0xFF;
    high = (Servo2Position[w] >> 8) & 0xFF;
    EEPROM.write(18 + (w * AnzahlWerte), low);
    EEPROM.write(19 + (w * AnzahlWerte), high);

    low = MitLuft[w] & 0xFF;
    high = (MitLuft[w] >> 8) & 0xFF;
    EEPROM.write(20 + (w * AnzahlWerte), low);
    EEPROM.write(21 + (w * AnzahlWerte), high);

    low = DruckTrockenZeit[w] & 0xFF;
    high = (DruckTrockenZeit[w] >> 8) & 0xFF;
    EEPROM.write(22 + (w * AnzahlWerte), low);
    EEPROM.write(23 + (w * AnzahlWerte), high);
  }

  EEPROM.write(70, AktuellesEtikett);
#else
  preferences.begin("EEPROM", false);
  preferences.putUInt("AktEtikett", AktuellesEtikett);
  preferences.putUInt("EtiLaenge0", Etikettenlaenge[0]);
  preferences.putUInt("EtiLaenge1", Etikettenlaenge[1]);
  preferences.putUInt("EtiLaenge2", Etikettenlaenge[2]);
  preferences.putBool("MitBuzzer0", MitBuzzer[0]);
  preferences.putBool("MitBuzzer1", MitBuzzer[1]);
  preferences.putBool("MitBuzzer2", MitBuzzer[2]);
  preferences.putUInt("Counter0", Counter[0]);
  preferences.putUInt("Counter1", Counter[1]);
  preferences.putUInt("Counter2", Counter[2]);
  preferences.putUInt("MaxSpeed0", MaxSpeed[0]);
  preferences.putUInt("MaxSpeed1", MaxSpeed[1]);
  preferences.putUInt("MaxSpeed2", MaxSpeed[2]);
  preferences.putUInt("Acceleration0", Acceleration[0]);
  preferences.putUInt("Acceleration1", Acceleration[1]);
  preferences.putUInt("Acceleration2", Acceleration[2]);
  preferences.putBool("MitFuss0", MitFuss[0]);
  preferences.putBool("MitFuss1", MitFuss[1]);
  preferences.putBool("MitFuss2", MitFuss[2]);
  preferences.putBool("MitDruck0", MitDruck[0]);
  preferences.putBool("MitDruck1", MitDruck[1]);
  preferences.putBool("MitDruck2", MitDruck[2]);
  preferences.putUInt("ZeitBisDruck0", ZeitBisDatumDruck[0]);
  preferences.putUInt("ZeitBisDruck1", ZeitBisDatumDruck[1]);
  preferences.putUInt("ZeitBisDruck2", ZeitBisDatumDruck[2]);
  preferences.putUInt("Servo1PosOben0", Servo1PositionOben[0]);
  preferences.putUInt("Servo1PosOben1", Servo1PositionOben[1]);
  preferences.putUInt("Servo1PosOben2", Servo1PositionOben[2]);
  preferences.putUInt("Servo1PosUnten0", Servo1PositionUnten[0]);
  preferences.putUInt("Servo1PosUnten1", Servo1PositionUnten[1]);
  preferences.putUInt("Servo1PosUnten2", Servo1PositionUnten[2]);
  preferences.putUInt("Servo2Pos0", Servo2Position[0]);
  preferences.putUInt("Servo2Pos1", Servo2Position[1]);
  preferences.putUInt("Servo2Pos2", Servo2Position[2]);
  preferences.putUInt("MitLuft0", MitLuft[0]);
  preferences.putUInt("MitLuft1", MitLuft[1]);
  preferences.putUInt("MitLuft2", MitLuft[2]);
  preferences.putUInt("TrockenZeit0", DruckTrockenZeit[0]);
  preferences.putUInt("TrockenZeit1", DruckTrockenZeit[1]);
  preferences.putUInt("TrockenZeit2", DruckTrockenZeit[2]);
  preferences.end();

#endif
  /*
    #if myDEBUG
    Serial.println(F("EE_Writing"));
    Serial.print( F("Aktuelles Etikett: ") );
    Serial.println(AktuellesEtikett + 1);

    for (int d = 0; d < 3; d++)
    {
      Serial.print( F("Etikettenlaenge") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      Serial.println(Etikettenlaenge[d]);

      Serial.print( F("ZeitBisDatumDruck") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      Serial.println(ZeitBisDatumDruck[d]);

      Serial.print( F("Buzzer") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      Serial.println(MitBuzzer[d]);

      Serial.print( F("Counter") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      Serial.println(Counter[d]);

      Serial.print( F("DruckOption") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      Serial.println(MitDruck[d]);

      Serial.print( F("Servo1PositionOben") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      Serial.println(Servo1PositionOben[d]);

      Serial.print( F("Servo1PositionUnten") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      Serial.println(Servo1PositionUnten[d]);

      Serial.print( F("Servo2Position") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      Serial.println(Servo2Position[d]);

      Serial.print( F("DruckTrockenZeit") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      Serial.println(DruckTrockenZeit[d]);

      Serial.print( F("Lüfter") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      Serial.println(MitLuft[d]);

      Serial.println();
    }

    #endif
  */
}
//----------------------------------------------------------------


//----------------------------------------------------------------
// Lese aus Memory
//----------------------------------------------------------------
void ReadMem() {

#if mySYSTEM //Arduino NANO
  byte low, high, set;
  byte  AnzahlWerte = 23;
  set = EEPROM.read(0);

  if (set == 99) //Gibt es bereits Daten im EEPROM?
  {
    for (int r = 0; r < 3; r++) //Position 1-69
    {
      low = EEPROM.read(1 + (r * AnzahlWerte));
      high = EEPROM.read(2 + (r * AnzahlWerte));
      Etikettenlaenge[r]  = low + ((high << 8) & 0xFF00);

      MitBuzzer[r] = EEPROM.read(3 + (r * AnzahlWerte));

      low = EEPROM.read(4 + (r * AnzahlWerte));
      high = EEPROM.read(5 + (r * AnzahlWerte));
      Counter[r]  = low + ((high << 8) & 0xFF00);

      low = EEPROM.read(6 + (r * AnzahlWerte));
      high = EEPROM.read(7 + (r * AnzahlWerte));
      MaxSpeed[r]  = low + ((high << 8) & 0xFF00);

      low = EEPROM.read(8 + (r * AnzahlWerte));
      high = EEPROM.read(9 + (r * AnzahlWerte));
      Acceleration[r]  = low + ((high << 8) & 0xFF00);

      MitFuss[r] = EEPROM.read(10 + (r * AnzahlWerte));

      MitDruck[r] = EEPROM.read(11 + (r * AnzahlWerte));

      low = EEPROM.read(12 + (r * AnzahlWerte));
      high = EEPROM.read(13 + (r * AnzahlWerte));
      ZeitBisDatumDruck[r]  = low + ((high << 8) & 0xFF00);

      low = EEPROM.read(14 + (r * AnzahlWerte));
      high = EEPROM.read(15 + (r * AnzahlWerte));
      Servo1PositionOben[r]  = low + ((high << 8) & 0xFF00);

      low = EEPROM.read(16 + (r * AnzahlWerte));
      high = EEPROM.read(17 + (r * AnzahlWerte));
      Servo1PositionUnten[r]  = low + ((high << 8) & 0xFF00);

      low = EEPROM.read(18 + (r * AnzahlWerte));
      high = EEPROM.read(19 + (r * AnzahlWerte));
      Servo2Position[r]  = low + ((high << 8) & 0xFF00);

      low = EEPROM.read(20 + (r * AnzahlWerte));
      high = EEPROM.read(21 + (r * AnzahlWerte));
      MitLuft[r]  = low + ((high << 8) & 0xFF00);

      low = EEPROM.read(22 + (r * AnzahlWerte));
      high = EEPROM.read(23 + (r * AnzahlWerte));
      DruckTrockenZeit[r]  = low + ((high << 8) & 0xFF00);
    }
    AktuellesEtikett = EEPROM.read(70);
  }

#else //ESP32


  preferences.begin("EEPROM", false);

  AktuellesEtikett = preferences.getUInt("AktEtikett", 0);

  Etikettenlaenge[0] = preferences.getUInt("EtiLaenge0", 500);
  Etikettenlaenge[1] = preferences.getUInt("EtiLaenge1", 1000);
  Etikettenlaenge[2] = preferences.getUInt("EtiLaenge2", 2000);

  ZeitBisDatumDruck[0] = preferences.getUInt("ZeitBisDruck0", 250);
  ZeitBisDatumDruck[1] = preferences.getUInt("ZeitBisDruck1", 500);
  ZeitBisDatumDruck[2] = preferences.getUInt("ZeitBisDruck2", 1000);

  MitBuzzer[0] = preferences.getBool("MitBuzzer0", 1);
  MitBuzzer[1] = preferences.getBool("MitBuzzer1", 0);
  MitBuzzer[2] = preferences.getBool("MitBuzzer2", 0);

  Counter[0] = preferences.getUInt("Counter0", 0);
  Counter[1] = preferences.getUInt("Counter1", 0);
  Counter[2] = preferences.getUInt("Counter2", 0);

  MaxSpeed[0] = preferences.getUInt("MaxSpeed0", 1000);
  MaxSpeed[1] = preferences.getUInt("MaxSpeed1", 1000);
  MaxSpeed[2] = preferences.getUInt("MaxSpeed", 1000);

  Acceleration[0] = preferences.getUInt("Acceleration0", 0);
  Acceleration[1] = preferences.getUInt("Acceleration1", 0);
  Acceleration[2] = preferences.getUInt("Acceleration2", 0);

  MitFuss[0] = preferences.getBool("MitFuss0", 0);
  MitFuss[1] = preferences.getBool("MitFuss1", 0);
  MitFuss[2] = preferences.getBool("MitFuss2", 0);

  MitDruck[0] = preferences.getBool("MitDruck0", 0);
  MitDruck[1] = preferences.getBool("MitDruck1", 0);
  MitDruck[2] = preferences.getBool("MitDruck2", 0);

  Servo1PositionOben[0] = preferences.getUInt("Servo1PosOben0", 125);
  Servo1PositionOben[1] = preferences.getUInt("Servo1PosOben1", 125);
  Servo1PositionOben[2] = preferences.getUInt("Servo1PosOben2", 125);

  Servo1PositionUnten[0] = preferences.getUInt("Servo1PosUnten0", 125);
  Servo1PositionUnten[1] = preferences.getUInt("Servo1PosUnten1", 125);
  Servo1PositionUnten[2] = preferences.getUInt("Servo1PosUnten2", 125);

  Servo2Position[0] = preferences.getUInt("Servo2Pos0", 125);
  Servo2Position[1] = preferences.getUInt("Servo2Po1", 125);
  Servo2Position[2] = preferences.getUInt("Servo2Pos2", 125);

  MitLuft[0] = preferences.getUInt("MitLuft0", 0);
  MitLuft[1] = preferences.getUInt("MitLuft1", 0);
  MitLuft[2] = preferences.getUInt("MitLuft2", 0);

  DruckTrockenZeit[0] = preferences.getUInt("TrockenZeit0", 0);
  DruckTrockenZeit[1] = preferences.getUInt("TrockenZeit1", 0);
  DruckTrockenZeit[2] = preferences.getUInt("TrockenZeit2", 0);
  // preferences.clear();  Falls mal mal das EE-Prom leeren will
  preferences.end();

#endif

  /*
    #if myDEBUG
    Serial.println(F("EE_Reading"));
    Serial.print( F("Aktuelles Etikett: ") );
    Serial.println(AktuellesEtikett + 1);

    for (int d = 0; d < 3; d++)
    {
      Serial.print( F("Etikettenlaenge") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      Serial.println(Etikettenlaenge[d]);
      Serial.print( F("ZeitBisDatumDruck") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      Serial.println(ZeitBisDatumDruck[d]);
      Serial.print( F("Servo1PositionOben") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      Serial.println(Servo1PositionOben[d]);
      if (Servo1PositionOben[d] > 180) Servo1PositionOben[d] = 180;
      Serial.print( F("Servo1PositionUnten") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      if (Servo1PositionUnten[d] > 180) Servo1PositionUnten[d] = 180;
      Serial.println(Servo1PositionUnten[d]);

      Serial.print( F("Servo2Position") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      if (Servo2Position[d] > 180) Servo2Position[d] = 180;
      Serial.println(Servo2Position[d]);

      Serial.print( F("MitDruck") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      Serial.println(MitDruck[d]);

      Serial.print( F("MitLuft") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      if (MitLuft[d] > 10) MitLuft[d] = 10;
      Serial.println(MitLuft[d]);

      Serial.print( F("DruckTrockenZeit") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      Serial.print(DruckTrockenZeit[d]);
      Serial.print( F(" / ") );
      if (DruckTrockenZeit[d] > 60) DruckTrockenZeit[d] = 60;
      Serial.println(DruckTrockenZeit[d]);

      Serial.print( F("Buzzer") );
      Serial.print(d + 1);
      Serial.print( F(": ") );
      Serial.println(MitBuzzer[d]);
      Serial.println();
    }

    #endif
  */
}

Lieber @ StefanL38,

sorry für die falsche Formatierung, ich gelobe Besserung.

Die serial.print() habe ich bereits in MotorVor() eingebaut

MotorVor serial.print()
void MotorVor(int Speed) {
  #if myDRIVE
    int SpeedOutput = min(255, 75 + Speed * 20); // erst ab ca 100 dreht der 12V Gleichstrommotor
    Serial.print("MotorVor - Speed: ");
    Serial.println(Speed);
    Serial.print("SpeedOutput: ");
    Serial.println(SpeedOutput);
    analogWrite(MotorEnable_PIN, 255);
    digitalWrite(Motorsteuerung_PIN1, HIGH); // Motor läuft vorwärts
    digitalWrite(Motorsteuerung_PIN2, LOW);

    #if myDEBUG
      Serial.print(F("Motor vorwärts - mit "));
      Serial.print(SpeedOutput / 255 * 100);
      Serial.println(F("%"));
    #endif
  #endif
}```

In dem Hauptmenü wo sich der Motor vor und zurück dreht sehe ich das im Seriellen Monitor

Serieller Monitor wo sich der Motor dreht
Neue Position SmallRotary: 1
MotorVor - Speed: 1
SpeedOutput: 95
Motor vorwärts - mit 0%

In den beiden Untermenüs "Etikettenlänge und END-POSITION" dreht sich der Motor nicht:

Menüpunkt "Etikettenlänge..." Die Ausgabe erfolgt so lange bis ich den Switch am Rotary drücke, dann geht es zum nächsten
21:06:20.290 -> Ende PositionAnfahren
21:06:20.290 -> MotorVor - Speed: 1
21:06:20.290 -> SpeedOutput: 95
21:06:20.290 -> Motor vorwärts - mit 0%
21:06:20.290 -> Ende PositionAnfahren
21:06:20.290 -> MotorVor - Speed: 1
21:06:20.290 -> SpeedOutput: 95
21:06:20.290 -> Motor vorwärts - mit 0%
21:06:20.290 -> Ende PositionAnfahren
21:06:20.290 -> MotorVor - Speed: 1
21:06:20.290 -> SpeedOutput: 95
21:06:20.290 -> Motor vorwärts - mit 0%
21:06:20.290 -> Ende PositionAnfahren
21:06:20.290 -> MotorVor - Speed: 1
21:06:20.290 -> SpeedOutput: 95
21:06:20.290 -> Motor vorwärts - mit 0%
21:06:20.290 -> Ende PositionAnfahren
21:06:20.290 -> MotorVor - Speed: 1
21:06:20.290 -> SpeedOutput: 95
21:06:20.290 -> Motor vorwärts - mit 0%
21:06:20.290 -> Ende PositionAnfahren
21:06:20.290 -> MotorVor - Speed: 1
21:06:20.290 -> SpeedOutput: 95
21:06:20.290 -> Motor vorwärts - mit 0%
21:06:20.339 -> Ende PositionAnfahren
21:06:20.339 -> MotorVor - Speed: 1
21:06:20.339 -> SpeedOutput: 95
21:06:20.339 -> Motor vorwärts - mit 0%
21:06:20.339 -> Ende PositionAnfahren
21:06:20.339 -> MotorVor - Speed: 1
21:06:20.339 -> SpeedOutput: 95
21:06:20.339 -> Motor vorwärts - mit 0%
21:06:20.339 -> Ende PositionAnfahren
21:06:20.339 -> MotorVor - Speed: 1
21:06:20.339 -> SpeedOutput: 95
21:06:20.339 -> Motor vorwärts - mit 0%
Menüpunkt "END-POSITION..." hier dreht sich der Motor auch nicht

1:15:40.846 -> SmallRot:5
21:15:40.846 -> MotorVor - Speed: 5
21:15:40.846 -> SpeedOutput: 175
21:15:40.846 -> Motor vorwärts - mit 0%
21:19:49.605 -> SmallRot:6
21:19:49.605 -> MotorVor - Speed: 6
21:19:49.605 -> SpeedOutput: 195
21:19:49.605 -> Motor vorwärts - mit 0%

Der komplette Quellcode inkl. der serial.print() und die Makro Erweiterung von Dir
// MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START *
// a detailed explanation how these macros work is given in this tutorial
// https://forum.arduino.cc/t/comfortable-serial-debug-output-short-to-write-fixed-text-name-and-content-of-any-variable-code-example/888298

#define dbg(myFixedText, variableName) \
  Serial.print( #myFixedText " "  #variableName"="); \
  Serial.println(variableName);

#define dbgi(myFixedText, variableName,timeInterval) \
  { \
    static unsigned long intervalStartTime; \
    if ( millis() - intervalStartTime >= timeInterval ){ \
      intervalStartTime = millis(); \
      Serial.print( #myFixedText " "  #variableName"="); \
      Serial.println(variableName); \
    } \
  }

#define dbgc(myFixedText, variableName) \
  { \
    static long lastState; \
    if ( lastState != variableName ){ \
      Serial.print( #myFixedText " "  #variableName" changed from "); \
      Serial.print(lastState); \
      Serial.print( F(" to ") ); \
      Serial.println(variableName); \
      lastState = variableName; \
    } \
  }

#define dbgcf(myFixedText, variableName) \
  { \
    static float lastState; \
    if ( lastState != variableName ){ \
      Serial.print( #myFixedText " "  #variableName" changed from "); \
      Serial.print(lastState); \
      Serial.print( " to "); \
      Serial.println(variableName); \
      lastState = variableName; \
    } \
  }
// MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END *

unsigned long MyTestTimer = 0;                   // Timer-variables MUST be of type unsigned long

/* Universalcode für den Ettimandl (ESP32)  und den EtVonSchleck (Arduino Nano)

  Copyright (C) 2021 Jeremias Bruker
  2021-01-03 Jeremias Bruker| Den Code kann jeder frei verwenden, ändern und hochladen wo er will,
                              solange er nicht seinen eigenen Namen drüber setzt, oder diesen kommerziell verwertet, beispielsweise
                              indem Etikettiermaschinen mit diesem Code versehen und verkauft werden.

  2021-01-03 Jeremias Bruker | initial version,
  2021-01-09 Martin Zahn     | Unterstützung ESP32+Schrittmotor hinzugefügt
  2021-01-16 Jeremias Bruker | Wahl zwischen Schrittmotor und Gleichstrommotor per myDRIVE
  2021-01-21 Johannes Kuder  | Ultraschallsensor anstatt Näherungssensor per mySensor
  2021-01-28 Jeremias Bruker | Etikettenlänge kann während des Labelvorgangs mit dem SmallRotary geändert werden - wird mit E+ oder E- angezeigt
                             | Stepperlaufrichtung kann per define angepasst werden
  2021-01-29 Johannes Kuder  | OTA-Funktionalität für ESP32
  2021-01-29 Jeremias Bruker | Grafik auf U8g2 umgestellt
  2021-02-03 Jeremias Bruker | Fußschalter implementiert
  2021-02-20 Jeremias Bruker | Große Werte können im Menü parallel mit Small und BigRotary verändert werden werden
  2021-02-23 Jeremias Bruker | Die Spannung bzw. Drehzahl des Lüfters kann nun per Software eingestellt werden
  2021-02-25 Jeremias Bruker | Gemeinsame EncoderLib (für Every und ESP32) & Abbruch über Rotary-Button während der Trockenzeit*/


//----------------------------------------------------------------
// Allgemeine Konfiguration DEBUG/GRAFIK/System Information
//----------------------------------------------------------------
#define mySYSTEM            1            // 1= Arduino Every / 0 = ESP32
#define myDEBUG             1            // 0 = Debug via Serial Monitor
#define myDRIVE             0            // 1 = Gleichstrommotor mit H-Brücke 0 = Schrittmotor
#define mySENSOR            0            // 1 = Ultraschallsensor 0 = kap. Näherungssensor
//---------------------------
#define useOTA              0            // 1 = OTA Funktionalität nutzen
#if useOTA
const char* ssid = "";
const char* password = "";
#endif
//---------------------------
#define StepperLaufrichtung 0           // 0 für senkrechten Aufbau 1 für waagerechten Aufbau
//----------------------------------------------------------------

const char Version[] = "2.6"; //02.03.2021

#if mySYSTEM
//----------------------------------------------------------------
// Pinbelegung Arduino Nano
//----------------------------------------------------------------
// Rotary Encoder klein für Menü-Steuerung
#define SmallRotary_PIN_SW               A0

#define TRIG_PIN                         A1    // falls Ultraschallsensor im Einsatz

#define Buzzer_PIN                       A2
// I2C-Display                           A4   // SDA
// I2C-Display                           A5   // SCL
#define FussSchalter                     A6
#define NaeherungsSensor_PIN             A7    // Ausgang Näherungsschalter oder Ausgang Ultraschallsensor
// Serial                                 0
// Serial                                 1
#define RotaryBig_PIN_A                   2
#define RotaryBig_PIN_B                   3

#define SmallRotary_PIN_A                 4
#define SmallRotary_PIN_B                 5

#define MiniLuefterEnable_PIN             6 //Speed PWM für Lüfter am Gleichstrommotorausgang B
#define MiniLuefter_PIN1                  7 //PinA Motorsteuerung für Lüfter 

#define Motorsteuerung_PIN1               8    // Schrittmotor-->  Motorsteuerung_PIN1 = Step   oder Gleichstrommotor--> Pin A
#define Motorsteuerung_PIN2               9    // Schrittmotor-->  Motorsteuerung_PIN2 = Dir    oder Gleichstrommotor--> Pin B
#define MotorEnable_PIN                   10    // Schrittmotor-->  Enable-Pin                    oder Gleichstrommotor--> Speed PWM MotorA

//----------------------------------------------------------------
#else
//----------------------------------------------------------------
// Pinbelegung ESP32
//----------------------------------------------------------------
#define MotorEnable_PIN                  14    // Schrittmotor-->  Enable-Pin    oder Gleichstrommotor--> Speed PWM
#define Motorsteuerung_PIN1              33    // Schrittmotor-->  Step          oder Gleichstrommotor--> Pin A
#define Motorsteuerung_PIN2              32    // Schrittmotor-->  Dir           oder Gleichstrommotor--> Pin B

// Rotary Encoder (Inkrementaler Drehgeber für Etikettenposition)
// Grün = A-Phase, Weiß = B-Phase, Rot = Vcc-Leistung +, Schwarz = V0
#define RotaryBig_PIN_A                  16      // A-Phase
#define RotaryBig_PIN_B                  17      // B-Phase


// Rotary Encoder klein für Menü-Steuerung
#define SmallRotary_PIN_SW               13
#define SmallRotary_PIN_A                35 // DT
#define SmallRotary_PIN_B                34 // CLK


// Servo
#define SERVO1_PIN                       19     // Servo für Stempel
#define SERVO2_PIN                       26     // Stempelposition 

// I2C-Display                           21: SDA
// I2C-Display                           22: SCL

// SPI-Display                           18: CLK
// SPI-Display                           19: MISO
// SPI-Display                           23: MOSI
// SPI-Display                            5: CS

#define Buzzer_PIN                       25
#define MiniLuefter_PIN1                  2
#define MiniLuefterEnable_PIN             18 //Speed PWM für Lüfter am Gleichstrommotorausgang B

// Start-Sensor
#define NaeherungsSensor_PIN             23  // Im Fall Ultraschallsensor: ECHO Pin

#define TRIG_PIN                          4  // falls Ultraschallsensor im Einsatz

#define FussSchalter                      5



// OTA
#if useOTA
#include <WiFi.h>
#endif
#if useOTA
#include <ESPmDNS.h>
#endif
#if useOTA
#include <WiFiUdp.h>
#endif
#if useOTA
#include <ArduinoOTA.h>
#endif
#endif
//----------------------------------------------------------------

//----------------------------------------------------------------
// gemeinsame Libs (Nano und ESP)
//----------------------------------------------------------------
#include <Arduino.h>
#include <Encoder.h>          // https://github.com/PaulStoffregen/Encoder
#if !myDRIVE
#include <AccelStepper.h> // für Schrittmotor. https://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html
#endif
//----------------------------------------------------------------


//----------------------------------------------------------------
// diverse ARduino Libs
//----------------------------------------------------------------
#if mySYSTEM
#include <EEPROM.h>           // aus dem Bibliotheksverwalter
#endif


//----------------------------------------------------------------


//----------------------------------------------------------------
// diverse ESP32 Libs
//----------------------------------------------------------------
#if !mySYSTEM
#include <Preferences.h>  // für EEPROM
#endif

#if !mySYSTEM
#include <ESP32Servo.h>
#endif
//----------------------------------------------------------------

//----------------------------------------------------------------
// DISPLAY
//----------------------------------------------------------------
#include <Wire.h>             // aus dem Bibliotheksverwalter 
#include <U8g2lib.h>      // aus dem Arduino-Bibliotheksverwalter
#if mySYSTEM
//OLED 1.3 128*64 Breite Version -------------------------------------------------------------------
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); //128*64 BreiteVersion
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
#else
//2.42 Oled 128*64 Große Version -------------------------------------------------------------------
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
#endif

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
//----------------------------------------------------------------



//----------------------------------------------------------------
// Konfiguration SmallRotary
//----------------------------------------------------------------
Encoder SmallRotary(SmallRotary_PIN_A, SmallRotary_PIN_B);

int LeseSmallRotaryWert()
{
  int Wert;
  Wert = SmallRotary.read() / 4;
  return Wert;
}

void SetzeSmallRotaryWert(int Wert)
{
  SmallRotary.write(Wert * 4);
}

//----------------------------------------------------------------


//----------------------------------------------------------------
// Konfiguration Bigrotary
//----------------------------------------------------------------
Encoder BigRotary(RotaryBig_PIN_A, RotaryBig_PIN_B);

int LeseBigRotaryWert()
{
  int Wert;
  Wert = BigRotary.read();
  return Wert;
}

void SetzeBigRotaryWert(int Wert)
{
  BigRotary.write(Wert);
}
//----------------------------------------------------------------


//----------------------------------------------------------------
// Konfiguration Schrittmotor
//----------------------------------------------------------------
#if !myDRIVE
AccelStepper stepper(1, Motorsteuerung_PIN1, Motorsteuerung_PIN2); // Motortyp, Motorsteuerung_PIN1, Motorsteuerung_PIN2
#endif


//----------------------------------------------------------------
// Konfiguration EEPROM ESP32
//----------------------------------------------------------------
#if !mySYSTEM
Preferences preferences;
#endif



//----------------------------------------------------------------
// Konfiguration Datentransfer via Serial / FTDI / USB
//----------------------------------------------------------------
#define Serial_Baudrate 115200
//----------------------------------------------------------------

//----------------------------------------------------------------
// Konfiguration Buzzer
//----------------------------------------------------------------
#define BUZZER_SHORT   1
#define BUZZER_LONG    2
#define BUZZER_SUCCESS 3
#define BUZZER_ERROR   4
//----------------------------------------------------------------

//----------------------------------------------------------------
// Variablen
//----------------------------------------------------------------

int hand_steps = 400; // variable Schrittweite, original 40
unsigned int n_pings = 10; // Anzahl Einzelmessungen Ultraschallsensor zur Mittelwertbildung
float Schwelle = 2;    // Grenzabstand in cm an dem Glas erkannt wird


volatile int PositionBigRotary;
int altePositionBigRotary   = 0;    // Def der "alten" RotaryPosition
volatile int PositionSmallRotary;
int altePositionSmallRotary = 0;  // Def der "alten" RotaryPosition
int neuePositionSmallRotary = 0;  // Def der "alten" RotaryPosition
bool altePositionNaeherung = HIGH;//kein Glas aufgelegt
long Fortschritt;
long AlterFortschritt = 0;
bool EinWertNeu = LOW; //Anzeiger, ob EEPROM beschrieben werden soll
bool HandModus = LOW;
char  Ausgabe[30];

//Menüwerte
unsigned int AktuellesEtikett = 0;
unsigned int Etikettenlaenge[] = {500 , 1000 , 2000 };
unsigned int ZeitBisDatumDruck[] = {250 , 500 , 1000 };
unsigned int Counter[] = {0 , 0 , 0}; // Anzahl der
bool MitBuzzer[] = {LOW, LOW, LOW}; //Soll der Buzzer aktiv sein
bool MitFuss[] = {LOW, LOW, LOW}; //Soll der Fußschalter aktiv sein
bool MitDruck[] = {LOW, LOW, LOW}; //Soll überhaupt auf das Etikett gedruckt werden?
unsigned int DruckTrockenZeit[]    = {1, 1, 1}; //Sekunden nach dem Druck warten, damit die Tinte trocknen kann
unsigned int MitLuft[]  = {0, 0, 0}; // Spannung des Lüfters in %(Versorgungsspannung Motor) 0 = inaktiv 10 = 100 %


// Schrittmotoreinstellungen
unsigned int MaxSpeed[] = {10, 10, 10};                   // Schrittmotor Maximalgeschwindigkeit, wird im Code mit 100 multipliziert
unsigned int Acceleration[] = {5, 5, 5};                  // Schrittmotor Beschleunigung (höher = schneller)  wird im Code mit 100 multipliziert
//int Speed = 1000;                                         // Schrittmotor Geschwindigkeit für Handbetrieb
int LastSteps = 20000;                      // Gefahrene Schritte des Schrittmotors beim letzten Etikettiervorgang
int LastStepsPrint = 18000;                 // Gefahrene Schritte des Schrittmotors beim letzten Etikettiervorgang
#if myDRIVE
int DriveJump = 2; //Menüpunkte vom Schrittmotor ausblenden
#else
int DriveJump = 0;
#endif

//################################################# SETUP #############################################

void setup() {
#if myDEBUG
  Serial.begin(Serial_Baudrate);
  Serial.println(Version);
#endif
  delay(100);
  
  ReadMem(); //Werte aus EE_Prom einlesen


  Wire.begin();
  //Wire.setClock(400000L);

  u8g2.begin();
  u8g2.enableUTF8Print();

  print_logo();


#if !mySYSTEM
  // OTA -------------------------------------------------
#if useOTA
#if myDEBUG
  Serial.println(F("OTA") );
#endif
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println( F("Reboot") );
    delay(5000);
    ESP.restart();
  }

  WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE); // required to set hostname properly
#if mySYSTEM
  WiFi.setHostname("EtVomSchleck");
#else
  WiFi.setHostname("EttiMandl");
#endif

  ArduinoOTA
  .onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH)
      type = "sketch";
    else // U_SPIFFS
      type = "filesystem";

#if myDEBUG
    Serial.println( F("update" + type) );
#endif

    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_courB12_tf);
    u8g2.setCursor(1, 15);
    u8g2.print("Receiving");
    u8g2.setCursor(1, 35);
    u8g2.print("OTA Update");
    u8g2.sendBuffer();
  })
  .onEnd([]() {
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_courB12_tf);
    u8g2.setCursor(1, 15);
    u8g2.print("Receiving");
    u8g2.setCursor(1, 35);
    u8g2.print("OTA Update");
    u8g2.setCursor(1, 55);
    u8g2.print("Done !");
    u8g2.sendBuffer();
  })
  .onProgress([](unsigned int progress, unsigned int total) {
#if myDEBUG
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
#endif
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_courB12_tf);
    u8g2.setCursor(1, 15);
    u8g2.print("Receiving");
    u8g2.setCursor(1, 35);
    u8g2.print("OTA Update");
    u8g2.setCursor(1, 55);
    u8g2.printf("Progress: %u%%\r", (progress / (total / 100)));
    u8g2.sendBuffer();
  })
  .onError([](ota_error_t error) {
#if myDEBUG
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR)
      Serial.println( F("NoAuth") );
    else if (error == OTA_BEGIN_ERROR)
      Serial.println( F("BeginFail"));
    else if (error == OTA_CONNECT_ERROR)
      Serial.println( F("Con.Fail") );
    else if (error == OTA_RECEIVE_ERROR)
      Serial.println( F("RcvFail") );
    else if (error == OTA_END_ERROR)
      Serial.println( F("EndFail") );
#endif
  });

  ArduinoOTA.begin();

#if myDEBUG
  Serial.println( F("OK") );
  Serial.print( F("IP") );
  Serial.println(WiFi.localIP());
#endif
#endif

  // Ende OTA
#endif

  //----------------------------------------------------------------
  //Setup Fußschalter
  //----------------------------------------------------------------
  pinMode(FussSchalter, INPUT_PULLUP);
  //----------------------------------------------------------------



#if myDRIVE
  //----------------------------------------------------------------
  //Setup Motorsteuerung
  //----------------------------------------------------------------

  digitalWrite(Motorsteuerung_PIN1, LOW);
  digitalWrite(Motorsteuerung_PIN2, LOW);
  pinMode(Motorsteuerung_PIN1, OUTPUT);
  pinMode(Motorsteuerung_PIN2, OUTPUT);
  pinMode(MotorEnable_PIN, OUTPUT);
  digitalWrite(MotorEnable_PIN, HIGH); // Kann erstmal aktiv sein
  //----------------------------------------------------------------
#else
  //----------------------------------------------------------------
  //Setup Schrittmotorsteuerung
  //----------------------------------------------------------------
  stepper.setEnablePin(MotorEnable_PIN);
  stepper.setPinsInverted(StepperLaufrichtung, false, true); // directioninvert, stepinvert, enableinvert
  stepper.setMaxSpeed(MaxSpeed[AktuellesEtikett] * 100); // Maximale Geschwindigkeit
  //stepper.setAcceleration(Acceleration[AktuellesEtikett]*100); // Beschleunigung
  //stepper.setCurrentPosition(0);
#endif
  //----------------------------------------------------------------


  //----------------------------------------------------------------
  // Setup MiniLuefter
  //----------------------------------------------------------------
  pinMode(MiniLuefter_PIN1, OUTPUT);
  pinMode(MiniLuefterEnable_PIN, OUTPUT);
  digitalWrite(MiniLuefter_PIN1, LOW);
#if mySYSTEM
  analogWrite(MiniLuefterEnable_PIN, MitLuft[AktuellesEtikett] * 25);
#else
  ledcSetup(0, 5000, 8);
  ledcAttachPin(MiniLuefterEnable_PIN, 0);
  ledcWrite(0, 125);
#endif

  //----------------------------------------------------------------


  //----------------------------------------------------------------
  //Setup MiniRotarySwitch
  //----------------------------------------------------------------
  pinMode(SmallRotary_PIN_SW, INPUT);
  //----------------------------------------------------------------



  //----------------------------------------------------------------
  // Konfiguration Buzzer
  //----------------------------------------------------------------
  pinMode(Buzzer_PIN, OUTPUT);
  if (MitBuzzer[0] || MitBuzzer[1] || MitBuzzer[2])
  {
    buzzer(BUZZER_LONG);
  }
  //----------------------------------------------------------------


  //----------------------------------------------------------------
  // Konfiguration Ultraschallsensor
  //----------------------------------------------------------------
  pinMode(TRIG_PIN, OUTPUT);

}   //-----------SETUP ENDE----------------------------------------------------------------



void loop()
{
#if !mySYSTEM
#if useOTA
  ArduinoOTA.handle();
#endif
#endif

  Einstellungsmenue(); //Mit RotarySwitch ins Menü rein
  Handsteuerung(); // Mit RotaryDrehen ---> Motor Vor und Motor zurück

  //------------------------------------------------------------
  // BEREIT-MODUS  Abfrage Näherungsschalter und eventuell Etikettieren!
  //------------------------------------------------------------

#if mySENSOR // Ultraschallsensor
  bool neuePositionNaeherung = !Ultraschallsensor(Schwelle);

#else // Abstandssensor
  bool neuePositionNaeherung = digitalRead(NaeherungsSensor_PIN);
#endif

  if (MitFuss[AktuellesEtikett])
  {
    if (!digitalRead(FussSchalter))  // Fußschalter wurde eventuell gedrückt
    {
      buzzer(BUZZER_LONG);
      if (!digitalRead(FussSchalter))  // Fußschalter wurde gedrückt !
      {
#if myDEBUG
        Serial.println(F("FußSPress"));
#endif
        Etikettieren();
        for (int i = 0; i <= 3; i++)
        {
          buzzer(BUZZER_LONG);
          delay(200);
        }
      }
    }
  }
  else if (neuePositionNaeherung != altePositionNaeherung)  // Sollte die neue Position ungleich der alten sein...
  {
    altePositionNaeherung = neuePositionNaeherung;
    if (neuePositionNaeherung == LOW)
    {
      buzzer(BUZZER_LONG);
#if myDEBUG
      Serial.println( F("GlasDetect") );
#endif
      if (neuePositionNaeherung == LOW) Etikettieren(); // Falls Glas immer noch liegt
      for (int i = 0; i <= 2; i++)
      {
        buzzer(BUZZER_SHORT);
        delay(200);
      }

    }
  }

}//ENDE LOOP-------------------------------------------------------



//----------------------------------------------------------------
// Etikettiervorgang
//----------------------------------------------------------------
void Etikettieren()
{
  SetzeBigRotaryWert(0); //RESET
  PositionBigRotary = 0;
  bool Gedruckt = LOW;
  int LiveLaengenWert = 0;

  DisplayEtikettieren(0); //Start mit 0 Prozent

#if !myDRIVE // Für Schrittmotor

  stepper.enableOutputs();
  stepper.setCurrentPosition(0);
  stepper.setAcceleration(Acceleration[AktuellesEtikett] * 100); // ggf brauch man das hier nicht nochmal.
  stepper.setMaxSpeed(MaxSpeed[AktuellesEtikett] * 100); // Maximale Geschwindigkeit
  stepper.moveTo(LastSteps * 1.02); //

  if (MitDruck[AktuellesEtikett]) stepper.moveTo(LastStepsPrint * 1.02);

#if myDEBUG
  Serial.println( F("Vorb.") );
  Serial.print( F("Acc") );
  Serial.println(Acceleration[AktuellesEtikett]);
  Serial.print( F("Speed") );
  Serial.println(MaxSpeed[AktuellesEtikett] * 100
                );
  Serial.print( F("LastStepsP:") );
  Serial.println(LastStepsPrint);
  Serial.print( F("LastSteps") );
  Serial.println(LastSteps);
#endif
#endif


  bool Notstop = LOW;
  MotorVor(11); //Starten

  altePositionSmallRotary = 0;
  SetzeSmallRotaryWert(0);

  bool LiveRotAenderung = false;
  bool RotAenderung = false;
  while (abs(PositionBigRotary) <= Etikettenlaenge[AktuellesEtikett]) //Etikettierung starten
  {

    bool FortschrittAenderung = false;
#if !myDRIVE
    stepper.run();
    if (stepper.speed() <= (MaxSpeed[AktuellesEtikett] * 100) / 4 && stepper.distanceToGo() < 20)
      stepper.setSpeed(MaxSpeed[AktuellesEtikett] * 100 / 4);
    stepper.runSpeed();
#endif

    neuePositionSmallRotary = LeseSmallRotaryWert();

    if (neuePositionSmallRotary != altePositionSmallRotary)
    {
      Etikettenlaenge[AktuellesEtikett] +=  neuePositionSmallRotary;
      LiveLaengenWert +=  neuePositionSmallRotary;
      SetzeSmallRotaryWert(0);
      LiveRotAenderung = true;
      RotAenderung = true;
    }


    Fortschritt = abs((((long)(PositionBigRotary) * 100) / (long)(Etikettenlaenge[AktuellesEtikett])));

#if mySYSTEM
    if (Fortschritt != AlterFortschritt || LiveRotAenderung == true) //Zeigt jeden Prozentfortschritt an
#else  //Der Schrittmotor wird gestört bei Grafikausgabe
    if (abs(Fortschritt - AlterFortschritt) >= 10 || LiveRotAenderung == true)  //Zeigt nur jeden zehnten Prozentfortschritt an
#endif
    {
      u8g2.setDrawColor(0);       //Zum Löschen der alten Zeichen
      u8g2.drawBox(0, 35, 128, 15); //Zum Löschen der alten Zeichen
      u8g2.setDrawColor(1);      //Zum Löschen der alten Zeichen

      if (RotAenderung)
      {
        u8g2.setCursor(1, 50);
        sprintf(Ausgabe, "E%d", LiveLaengenWert);
        u8g2.print(Ausgabe);
      }
      u8g2.setCursor(43, 50);
      sprintf(Ausgabe, "-->%3d\n%%", Fortschritt);
      u8g2.print(Ausgabe);
      u8g2.sendBuffer();
      LiveRotAenderung = false;
      AlterFortschritt = Fortschritt;
    }


    if ((digitalRead(SmallRotary_PIN_SW) == LOW)) //RotarySwitch während Etikettiervorgang als NOTSTOP
    {
      MotorStop();
#if myDEBUG
      Serial.println(F("Notstop"));
#endif
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_courB14_tf);
      u8g2.setCursor(10, 20);
      u8g2.print(F("ROTASTOP"));
      u8g2.setCursor(0, 50);
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.print(F("GlasRaus"));
      u8g2.sendBuffer();
      Notstop = HIGH;
      buzzer(BUZZER_ERROR);
      Entprellen();
      delay(1000);
      break;
    }  //NOTFALL AUS

    // eventuell Datum Drucken?
    if (MitDruck[AktuellesEtikett])
    {
      if (abs(PositionBigRotary) > ZeitBisDatumDruck[AktuellesEtikett] && Gedruckt == LOW)
      {
        if (MitLuft[AktuellesEtikett] > 0)
        {
#if !mySYSTEM
          ledcWrite(0, 125);
#endif
          analogWrite(MiniLuefterEnable_PIN, MitLuft[AktuellesEtikett] * 25);
          digitalWrite(MiniLuefter_PIN1, HIGH); //Lüfter starten
        }
#if myDEBUG
        Serial.print(F("Lüfter"));
#endif
#if !myDRIVE
        LastStepsPrint = stepper.currentPosition();
#endif

        MotorStop(); //warten bis gedruckt
        Drucken();
        Gedruckt = HIGH;
#if !myDRIVE
        stepper.moveTo((LastSteps) * 1.02);
#if myDEBUG
        Serial.println( F("Vorb.") );
        Serial.print( F("Acc") );
        Serial.println(Acceleration[AktuellesEtikett]);
        Serial.print( F("Speed") );
        Serial.println(MaxSpeed[AktuellesEtikett] * 100);
        Serial.print( F("LastStepsP") );
        Serial.println(LastStepsPrint);
        Serial.print( F("LastSteps") );
        Serial.println(LastSteps);
#endif
#endif

        DisplayEtikettieren(Fortschritt);
        MotorVor(11);
      }
    } // mit Druck ende

    altePositionBigRotary = PositionBigRotary;
    PositionBigRotary = LeseBigRotaryWert();
  } // while ende

#if !myDRIVE
  LastSteps = stepper.currentPosition();

#if myDEBUG
  Serial.print(F("Stepper steps"));
  Serial.println(LastSteps);
#endif
#endif

  MotorStop(); //Etikettierung beendet


#if !myDRIVE
  stepper.disableOutputs();
#endif


  //Falls Lüfter lief ---> abschalten
  digitalWrite(MiniLuefter_PIN1, LOW);
#if myDEBUG
  Serial.print(F("Lüfter0"));
#endif
  if (HandModus == LOW)  //Im Handbetrieb diesen Punkt überspringen
  {
    if (Notstop == LOW) //Der Vorgagng lief sauber durch
    {
      u8g2.setCursor(43, 50);
      sprintf(Ausgabe, "-->%3d\n%%", 100);
      u8g2.print(Ausgabe);
      u8g2.sendBuffer();
      delay (1000);
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_courB14_tf);
      u8g2.setCursor(25, 20);
      u8g2.print(F("FERTIG"));
      u8g2.setCursor(0, 50);
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.print(F("GlasRaus"));
      u8g2.sendBuffer();
      buzzer(BUZZER_SUCCESS);
      Counter[AktuellesEtikett]++;
    }

#if mySENSOR // Ultraschallsensor
    while (Ultraschallsensor(Schwelle) == HIGH); //GLAS liegt noch drauf
#else
    while (digitalRead(NaeherungsSensor_PIN) == LOW) //GLAS liegt noch drauf
#endif
    {
      delay (100);
    }
    delay (1000);
    if (LiveLaengenWert != 0) WriteMem(); //Etikettenlänge wurde live angepasst
    DisplayNeutral();
  }
}
//ENDE ETIKETTIERVORGANG------------------------------------------

void DisplayEtikettieren(int Fortschrittswert)
{
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_courB10_tf);
  u8g2.setCursor(0, 20);
#if mySYSTEM
  u8g2.print(F("EtVomSchleckn"));
#else
  u8g2.print(F("EttiMandln"));
#endif
  u8g2.setCursor(43, 50);
  if (Fortschrittswert > 100) sprintf(Ausgabe, "-->%3d\n%%", "");
  else sprintf(Ausgabe, "-->%3d\n%%", Fortschrittswert);
  u8g2.print(Ausgabe);
  u8g2.sendBuffer();
}

//----------------------------------------------------------------
// DIREKTE MOTORANSTEUERUNG: VORWÄRTS UND RÜCKWÄRTS ZUM JUSTIEREN
//----------------------------------------------------------------
void Handsteuerung()
{
  String SpeedAnzeige;
  neuePositionSmallRotary = LeseSmallRotaryWert();
  if (neuePositionSmallRotary != altePositionSmallRotary)
  {
    Serial.print("Neue Position SmallRotary: "); 
    Serial.println(neuePositionSmallRotary);
    
    u8g2.setDrawColor(0);
    u8g2.drawBox(0, 37, 128, 16); //löschen der Zeile
    u8g2.setDrawColor(1);
    u8g2.setCursor(1, 50);
    if  (neuePositionSmallRotary > 0)
    {

      if (neuePositionSmallRotary > 8)
      {
        SetzeSmallRotaryWert(9);
        neuePositionSmallRotary = 9;
      }
      SpeedAnzeige = String(neuePositionSmallRotary) + " ";
      MotorVor(neuePositionSmallRotary);
      for (int i = 1; i <= neuePositionSmallRotary; i++)
      {
        SpeedAnzeige = SpeedAnzeige + ">";
      }
    }
    else if (neuePositionSmallRotary < 0)
    {

      if (neuePositionSmallRotary < -8)
      {
        SetzeSmallRotaryWert(-9);
        neuePositionSmallRotary = -9;
      }
      SpeedAnzeige = String(-neuePositionSmallRotary) + " ";
      MotorRueck(-neuePositionSmallRotary);
      for (int i = -1; i >= neuePositionSmallRotary; i--)
      {
        SpeedAnzeige = SpeedAnzeige + "<";
      }
    }
    else
    {
      if (MitFuss[AktuellesEtikett]) SpeedAnzeige = "<FussT>";
      else SpeedAnzeige = "GlasDrauf";
      MotorStop();
    }



    u8g2.print(SpeedAnzeige);
    u8g2.sendBuffer();
    altePositionSmallRotary = neuePositionSmallRotary;
    PositionSmallRotary = neuePositionSmallRotary;
  }
#if !myDRIVE
  if (PositionSmallRotary != 0)
  {
    stepper.setEnablePin(MotorEnable_PIN);
    int SpeedOutput;
    if (PositionSmallRotary > 0) SpeedOutput = MaxSpeed[AktuellesEtikett] * 100 * PositionSmallRotary / 9;
    else SpeedOutput = -(MaxSpeed[AktuellesEtikett] * 100 * abs(PositionSmallRotary) / 9);
    stepper.setSpeed(SpeedOutput);
    stepper.runSpeed();
  }
  else stepper.disableOutputs();
#endif

}

//------------------------------------------
// Haltbarkeitsdatum Drucken
//------------------------------------------
void Drucken()
{
#if myDEBUG
  Serial.println(F("Stempeln"));
#endif

  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_courB12_tf);
  u8g2.setCursor(20, 20);
  u8g2.print("Stempeln");
  u8g2.setCursor(0, 50);
  u8g2.print("Warte...");
  u8g2.sendBuffer();


  // Warten zum Trocknen
  if (DruckTrockenZeit > 0)
  {
    unsigned long AktuelleZeit = millis();
    unsigned int  LetzteAnzeige;

    while (millis() - AktuelleZeit < (DruckTrockenZeit[AktuellesEtikett] * 1000))
    {
      unsigned int LaufZeit =  DruckTrockenZeit[AktuellesEtikett] - int((millis() - AktuelleZeit) / 1000);
      if (LaufZeit != LetzteAnzeige)
      {
        u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_courB12_tf);
        u8g2.setCursor(20, 20);
        u8g2.print("Stempeln");
        u8g2.setCursor(0, 50);
        u8g2.print("Warte...");
        u8g2.print(LaufZeit);
        u8g2.print("sec");
        u8g2.sendBuffer();
        LetzteAnzeige = LaufZeit;
      }
      if ((digitalRead(SmallRotary_PIN_SW) == LOW)) break; //Mit Rotary-Knopfdruck raus aus der Wartezeit
    }
    Entprellen();
  }
}
//----------------------------------------------------------------


//------------------------------------------
// Motor Stop
//------------------------------------------
void MotorStop()
{
#if myDRIVE
  digitalWrite(Motorsteuerung_PIN1, LOW);
  digitalWrite(Motorsteuerung_PIN2, LOW);
#endif

#if myDEBUG
  Serial.print(F("Motor Stop"));
#endif
}

#define myDRIVE 1 // oder 0, je nach Konfiguration

void MotorVor(int Speed) {
  #if myDRIVE
    int SpeedOutput = min(255, 75 + Speed * 20); // erst ab ca 100 dreht der 12V Gleichstrommotor
    Serial.print("MotorVor - Speed: ");
    Serial.println(Speed);
    Serial.print("SpeedOutput: ");
    Serial.println(SpeedOutput);
    analogWrite(MotorEnable_PIN, 255);
    digitalWrite(Motorsteuerung_PIN1, HIGH); // Motor läuft vorwärts
    digitalWrite(Motorsteuerung_PIN2, LOW);

    #if myDEBUG
      Serial.print(F("Motor vorwärts - mit "));
      Serial.print(SpeedOutput / 255 * 100);
      Serial.println(F("%"));
    #endif
  #endif
}


void MotorRueck(int Speed) {
  #if myDRIVE
    int SpeedOutput = 75 + Speed * 20; // Erst ab ca. 100 dreht der 12V Gleichstrommotor
    Serial.print("MotorRueck - Speed: ");
    Serial.println(Speed);
    Serial.print("SpeedOutput: ");
    Serial.println(SpeedOutput);
    analogWrite(MotorEnable_PIN, 255);
    digitalWrite(Motorsteuerung_PIN1, LOW);
    digitalWrite(Motorsteuerung_PIN2, HIGH);

    #if myDEBUG
      Serial.print(F("Motor rückwärts - mit "));
      Serial.println(SpeedOutput);
    #endif
  #endif
}




void DisplayNeutral()
{
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_courB14_tf);
  u8g2.setCursor(0, 20);
  u8g2.print(F("Etik."));
  u8g2.setFont(u8g2_font_courB08_tf);
  u8g2.print(" (");
  u8g2.print(AktuellesEtikett + 1);
  u8g2.print(")");
  u8g2.setCursor(0, 50);
  u8g2.setFont(u8g2_font_courB12_tf);
  if (MitFuss[AktuellesEtikett]) u8g2.print(F("<FussTaster>"));
  else u8g2.print(F("GlasRauf"));
  u8g2.sendBuffer();
}


//-----------------------------------------------------------------------------------------
//  // Menü Einstellungen
//-----------------------------------------------------------------------------------------
void Einstellungsmenue()
{
  if (digitalRead(SmallRotary_PIN_SW) == LOW)  //Rein ins Menü durch Tastendruck
  {
    //Hauptmenü
    int SpeicherAktuellesEtikett = AktuellesEtikett;
    Entprellen();

    altePositionSmallRotary = 99;
    SetzeSmallRotaryWert(AktuellesEtikett); //RESET
    while (digitalRead(SmallRotary_PIN_SW))
    {
      neuePositionSmallRotary = LeseSmallRotaryWert();
      if (neuePositionSmallRotary != altePositionSmallRotary)
      {
        if (neuePositionSmallRotary > 2)
        {
          neuePositionSmallRotary = 2;
          SetzeSmallRotaryWert(2);
        }
        if (neuePositionSmallRotary < 0)
        {
          neuePositionSmallRotary = 0;
          SetzeSmallRotaryWert(0);
        }
        altePositionSmallRotary = neuePositionSmallRotary;
        AktuellesEtikett = neuePositionSmallRotary;
        u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_courB08_tf);
        u8g2.setCursor(0, 10);
        u8g2.print(F("Einstellungen für"));
        u8g2.drawLine(0, 16, 128, 16); //horiz. Linie
        u8g2.setFontMode(0);

        for (int d = 1; d < 4; d++)
        {
          u8g2.setFont(u8g2_font_courB08_tf);
          sprintf(Ausgabe, "%d)", d);
          u8g2.setCursor(0, d * 15 + 15);
          if (d == AktuellesEtikett + 1)
          {
            u8g2.drawBox(0, d * 15 + 6, 10, 11);
            u8g2.setDrawColor(0);
          }
          u8g2.print(Ausgabe);
          u8g2.setDrawColor(1);
          u8g2.setFont(u8g2_font_courB10_tf);
          u8g2.setCursor(12, d * 15 + 15);
          u8g2.print(F("Etiketten"));
          u8g2.setFont(u8g2_font_courB08_tf);
          u8g2.setCursor(98, d * 15 + 15);
          sprintf(Ausgabe, "c:%d", Counter[d - 1]);
          u8g2.print(Ausgabe);
        }
        u8g2.sendBuffer();
        SetzeSmallRotaryWert(AktuellesEtikett); //RESET
      }
    } //while Taster nicht gedrückt
    //AktuellesEtikett = altePositionSmallRotary;
    // Ende Hauptmenü
    buzzer(BUZZER_SHORT);

    Entprellen();

    // Untermenü
    char* MenuePunkte[17] = { "Menü verlassen",     // 0
                              "Etikettenlänge",   // 1 + Wert
                              "Etikettenlänge", // 2 Untermenü
                              " Handbetrieb",       // 3 HANDMODUS falls der Näherungssensor nicht funktioniert
                              "    Buzzer",             // 4 Sound aktiv oder inaktiv
                              " Counterwert",       // 5
                              " Schrittmotor",   // 6 Speed
                              " Schrittmotor",   // 7 Acceleration
                              " Fußschalter",     //8 Aktiv Inaktiv
                              "   Drucken",           // 9 + Aktiv oder Inaktiv
                              "Druck-Position",     // 10 +Wert
                              "Druck-Position",// 11 Untermenü
                              "    Lüfter",           // 15 Inaktiv oder Spannung
                              " Trockenzeit"        // 16 WarteZeit nach Druck in Zehntelsekunden
                            };

    byte AktuellerMenuePunkt = 99;

    altePositionSmallRotary = 99;
    SetzeSmallRotaryWert(0); //RESET

    while (altePositionSmallRotary != 0) //bis Menü verlassen wird
    {

      while (digitalRead(SmallRotary_PIN_SW))
      {
        neuePositionSmallRotary = LeseSmallRotaryWert();
        if (neuePositionSmallRotary < 0)
        {
          neuePositionSmallRotary = 0;
          SetzeSmallRotaryWert(neuePositionSmallRotary);
        }
        if (neuePositionSmallRotary > 16)
        {
          neuePositionSmallRotary = 16;
          SetzeSmallRotaryWert(neuePositionSmallRotary);
        }

        if (MitDruck[AktuellesEtikett] == LOW) neuePositionSmallRotary = neuePositionSmallRotary % 10; //Drucken nicht aktiviert
        else neuePositionSmallRotary = neuePositionSmallRotary % 17;

        if (neuePositionSmallRotary == 6 && altePositionSmallRotary == 5) neuePositionSmallRotary += DriveJump;
        if (neuePositionSmallRotary == 7) neuePositionSmallRotary -=  DriveJump;

        if (neuePositionSmallRotary != altePositionSmallRotary)
        {
#if myDEBUG
          Serial.print(F("1neuePosRot:"));
          Serial.println(neuePositionSmallRotary);
#endif
          u8g2.clearBuffer();
          u8g2.setFont(u8g2_font_courB10_tf);
          u8g2.setCursor(5, 15);
          sprintf(Ausgabe, "DSatz (%d)", (AktuellesEtikett + 1));
          u8g2.print(Ausgabe);
          u8g2.drawLine(0, 20, 164, 20); //horiz. Linie
          u8g2.setCursor(1, 40);
          u8g2.print(MenuePunkte[neuePositionSmallRotary]);
          u8g2.setCursor(52, 60);

          if (neuePositionSmallRotary == 1) //Etikettenlänge
          {
            u8g2.print(Etikettenlaenge[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 2 || neuePositionSmallRotary == 11) //M)Etikettenlänge
          {
            u8g2.setCursor(1, 60);
            u8g2.print(F("man. anf."));
          }
          if (neuePositionSmallRotary == 3) //Handbetrieb
          {
            u8g2.setCursor(30, 60);
            u8g2.print(F("Inaktiv"));
          }
          if (neuePositionSmallRotary == 4) //Buzzer
          {
            u8g2.setCursor(12, 60);
            if (MitBuzzer[AktuellesEtikett] == LOW) u8g2.print(F("InAktiv"));
            else u8g2.print(F("Aktiv"));
          }
          if (neuePositionSmallRotary == 5) //Counter
          {
            u8g2.print(Counter[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 6) //SchrittMotor Speed
          {
            u8g2.setCursor(10, 60);
            u8g2.print(F("Speed"));
            u8g2.setCursor(90, 60);
            u8g2.print(MaxSpeed[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 7) //SchrittMotor Acceleration
          {
            u8g2.setCursor(10, 60);
            u8g2.print(F("Accel.:"));
            u8g2.setCursor(90, 60);
            u8g2.print(Acceleration[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 8) //Fußschalter
          {
            u8g2.setCursor(12, 60);
            if (MitFuss[AktuellesEtikett] == LOW) u8g2.print(F("InAktiv"));
            else u8g2.print(F("Aktiv"));
          }
          if (neuePositionSmallRotary == 9) //Drucken
          {
            u8g2.setCursor(12, 60);
            if (MitDruck[AktuellesEtikett] == LOW) u8g2.print(F("Deaktiviert"));
            else u8g2.print(F(" Aktiviert"));
          }
          if (neuePositionSmallRotary == 10) //Druckposition
          {
            u8g2.print(ZeitBisDatumDruck[AktuellesEtikett]);
          }
          if (neuePositionSmallRotary == 15) //Lüfter
          {
            u8g2.setCursor(12, 60);
            if (MitLuft[AktuellesEtikett] == 0) u8g2.print(F("Deaktiviert"));
            else
            {
              u8g2.setCursor(48, 60);
              u8g2.print(MitLuft[AktuellesEtikett] * 10);
              u8g2.print(F("%"));
            }
          }
          if (neuePositionSmallRotary == 16)
          {
            u8g2.print(DruckTrockenZeit[AktuellesEtikett]);
            u8g2.print(F(" sec"));
          }
          u8g2.sendBuffer();
          altePositionSmallRotary = neuePositionSmallRotary;
          SetzeSmallRotaryWert(neuePositionSmallRotary);
        }
      } //while Taster nicht gedrückt
      buzzer(BUZZER_SHORT);
      Entprellen();

      // Ende Untermenü


      // Position 1 Etikettenlänge per Wert einstellen
      if  (altePositionSmallRotary == 1) WertAendern(Etikettenlaenge, MenuePunkte[neuePositionSmallRotary]);

      // Position 2 Etikettenlänge (durch Wert Position anfahren) einstellen
      if (altePositionSmallRotary == 2) PositionAnfahren();

      // Position 3 Handbetrieb
      if  (altePositionSmallRotary == 3) Handbetrieb();

      // Position 4 Buzzer generell de-/aktivieren
      if  (altePositionSmallRotary == 4) WertInAktivAendern(MitBuzzer, MenuePunkte[neuePositionSmallRotary]);

      // Position 5 Counter Reset
      if  (altePositionSmallRotary == 5)
      {
        int oldPositionSmallRotary = 99;
        bool ResetCounter = HIGH;
        SetzeSmallRotaryWert(0); //RESET

        while (digitalRead(SmallRotary_PIN_SW))
        {

          neuePositionSmallRotary = LeseSmallRotaryWert();
          if (neuePositionSmallRotary != oldPositionSmallRotary)
          {
            u8g2.drawBox(15, 48, 103, 14);
            u8g2.setDrawColor(0);
            if (!ResetCounter)
            {
              u8g2.setCursor(42, 60);
              u8g2.setDrawColor(0);
              u8g2.print(F("Reset"));
              ResetCounter = HIGH;
            }
            else
            {
              u8g2.setCursor(52, 60);
              u8g2.print(Counter[AktuellesEtikett]);
              ResetCounter = LOW;
            }
            u8g2.setDrawColor(1);
            u8g2.sendBuffer();

            oldPositionSmallRotary = neuePositionSmallRotary;
          }
        } //while Taster nicht gedrückt
        if (ResetCounter)
        {
          Counter[AktuellesEtikett] = 0;
          EinWertNeu = HIGH;  //EEPROM-Write aktiviert - ein Wert geändert
        }
        SetzeSmallRotaryWert(altePositionSmallRotary); // zurück an die richtige Stelle
        altePositionSmallRotary = 99;
        buzzer(BUZZER_LONG);
        Entprellen();
      }

      // Position 6 MaxSpeed
      if  (altePositionSmallRotary == 6) WertAendern(MaxSpeed, MenuePunkte[neuePositionSmallRotary]);

      // Position 7 Acceleration
      if  (altePositionSmallRotary == 7) WertAendern(Acceleration, MenuePunkte[neuePositionSmallRotary]);

      // Position 8 Fußschalter generell de-/aktivieren
      if  (altePositionSmallRotary == 8) WertInAktivAendern(MitFuss, MenuePunkte[neuePositionSmallRotary]);

      // Position 9 Druck de-/aktivieren
      if  (altePositionSmallRotary == 9) WertInAktivAendern(MitDruck, MenuePunkte[neuePositionSmallRotary]);

      // Position 10 ZeitBisDruck per Wert einstellen
      if  (altePositionSmallRotary == 10) WertAendern(ZeitBisDatumDruck, MenuePunkte[neuePositionSmallRotary]);

      // Position 11  ZeitBisDruck per Anfahren einstellen
      if  (altePositionSmallRotary == 11) PositionAnfahren();

      // Position 15 Lüfter de-/aktivieren bzw Spannung einstellen
      if  (altePositionSmallRotary == 15) WertAendern(MitLuft, MenuePunkte[neuePositionSmallRotary]);


    }

    //Menü verlassen
    if (SpeicherAktuellesEtikett != AktuellesEtikett) EinWertNeu = HIGH; //Falls nur Etikett geändert auch abspeichern

    if (EinWertNeu)
    {
      WriteMem(); //Daten nur sichern, falls es eine Änderung gab
      //MenueHeader();
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.setCursor(0, 60);
      u8g2.setFont(u8g2_font_courB08_tf);
      u8g2.print(F("Daten abspeichern..."));
      u8g2.sendBuffer();
      for (int p = 0; p < 3; p++)
      {
        buzzer(BUZZER_SHORT);
      }
      EinWertNeu = LOW; //Reset
    }

    Entprellen();
    DisplayNeutral();

    //Es geht in den BEREITmodus zurück
    altePositionSmallRotary = 0; //RESET
    SetzeSmallRotaryWert(0); //RESET
  }
}


void Entprellen()
{
  while (digitalRead(SmallRotary_PIN_SW) == LOW) //ENTPRELLEN
  {
    delay (100);
  }
}

void Handbetrieb()
{
  int oldPositionSmallRotary = 0;
  SetzeSmallRotaryWert(100); //RESET

  Entprellen();
  HandModus = HIGH;
  while (digitalRead(SmallRotary_PIN_SW) && HandModus) //Warte bis RotarySwitch gedrückt und Modus inaktiv
  {
    while (digitalRead(SmallRotary_PIN_SW)) //Warte bis RotarySwitch gedrückt und Modus aktiv
    {
      neuePositionSmallRotary = LeseSmallRotaryWert();
      if (neuePositionSmallRotary != oldPositionSmallRotary)
      {
        u8g2.drawBox(1, 48, 128, 14);
        u8g2.setDrawColor(0);
        if (HandModus)
        {
          HandModus = LOW;
          u8g2.setCursor(30, 60);
          u8g2.print("Inaktiv");
        }
        else
        {
          HandModus = HIGH;
          u8g2.setCursor(1, 60);
          u8g2.print("Press to Start");
        }
        u8g2.setDrawColor(1);
        u8g2.sendBuffer();
        oldPositionSmallRotary = neuePositionSmallRotary;
      }
    } //while Taster nicht gedrückt - innere While-Schleife
    //Tastendruck Auswerten
    Entprellen();
    if (HandModus)
    {
      Etikettieren(); //Vorgang von Hand gestartet
      Entprellen(); // falls Abbruch im Etikettiervorgang
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.setCursor(5, 15);
      sprintf(Ausgabe, "Datensatz (%d)", (AktuellesEtikett + 1));
      u8g2.print(Ausgabe);
      u8g2.drawLine(0, 20, 164, 20); //horiz. Linie
      u8g2.setCursor(1, 40);
      u8g2.print(F(" Handbetrieb"));
      u8g2.setCursor(1, 60);
      u8g2.drawBox(1, 48, 128, 14);
      u8g2.setDrawColor(0);
      u8g2.print("Press to Start");
      u8g2.setDrawColor(1);
      u8g2.sendBuffer();
      oldPositionSmallRotary = neuePositionSmallRotary;
    }
  } //äussere Whileschleife
  SetzeSmallRotaryWert(altePositionSmallRotary); // zurück an die richtige Stelle
  altePositionSmallRotary = 99;
  buzzer(BUZZER_LONG);
}



void WertAendern(unsigned int *Was, char * MenuePunkt)
{
  int AlterWasWert = Was[AktuellesEtikett];
  int oldPositionSmallRotary = 0;
  int oldPositionBigRotary = 0;

  SetzeSmallRotaryWert(Was[AktuellesEtikett]); //RESET
  SetzeBigRotaryWert(0);

  while (digitalRead(SmallRotary_PIN_SW))
  {
    neuePositionSmallRotary = LeseSmallRotaryWert();
    PositionBigRotary = LeseBigRotaryWert();
    if ((neuePositionSmallRotary >= 0) && (neuePositionSmallRotary <= 10000))
    {
      if (neuePositionSmallRotary != oldPositionSmallRotary || PositionBigRotary != oldPositionBigRotary)
      {
        Was[AktuellesEtikett] = neuePositionSmallRotary + PositionBigRotary;
#if myDEBUG
        Serial.print(F("neu"));
        Serial.println(Was[AktuellesEtikett]);
#endif
        u8g2.setFont(u8g2_font_courB10_tf);
        u8g2.setCursor(1, 40);
        u8g2.print(MenuePunkt);
        if (altePositionSmallRotary == 6 || altePositionSmallRotary == 7) u8g2.drawBox(80, 48, 108, 14);
        else u8g2.drawBox(10, 48, 108, 14);
        if (altePositionSmallRotary == 6)
        {
          u8g2.setCursor(10, 60);
          u8g2.print(F("Speed"));
          u8g2.setCursor(90, 60);
        }
        else if (altePositionSmallRotary == 7)
        {
          u8g2.setCursor(10, 60);
          u8g2.print(F("Accel"));
          u8g2.setCursor(90, 60);
        }
        else u8g2.setCursor(50, 60);
        u8g2.setDrawColor(0);
        if (altePositionSmallRotary == 15)
        {
          analogWrite(MiniLuefterEnable_PIN, MitLuft[AktuellesEtikett] * 25);
          digitalWrite(MiniLuefter_PIN1, HIGH); //Lüfter starten
          if (Was[AktuellesEtikett] < 1)
          {
            u8g2.setCursor(12, 60);
            u8g2.print(F("inaktiv"));
            SetzeSmallRotaryWert(0);
            SetzeBigRotaryWert(0);
            Was[AktuellesEtikett] = 0;
          }
          else
          {
            if (Was[AktuellesEtikett] > 9)
            {
              SetzeSmallRotaryWert(10);
              SetzeBigRotaryWert(0);
              Was[AktuellesEtikett] = 10;
            }
            u8g2.setCursor(48, 60);
            u8g2.print(Was[AktuellesEtikett] * 10);
            u8g2.print("%");
          }
        }
        else u8g2.print(Was[AktuellesEtikett]);
        u8g2.setDrawColor(1);
        u8g2.sendBuffer();
        oldPositionSmallRotary = neuePositionSmallRotary;
        oldPositionBigRotary = PositionBigRotary;
        SetzeSmallRotaryWert(neuePositionSmallRotary);
      }
    }
    EinWertNeu = HIGH;  //EEPROM-Write aktiviert - ein Wert geändert
  } //while Taster nicht gedrückt
  digitalWrite(MiniLuefter_PIN1, LOW); //Lüfter stoppen, falls lief
  SetzeSmallRotaryWert(altePositionSmallRotary); // zurück an die richtige Stelle
  altePositionSmallRotary = 99;
  buzzer(BUZZER_LONG);
  Entprellen();
}






void WertInAktivAendern(bool *Was, char * MenuePunkt) //Für An/Aus-Werte
{
  int oldPositionSmallRotary = 99;
  SetzeSmallRotaryWert(0); //RESET
  while (digitalRead(SmallRotary_PIN_SW))
  {
    neuePositionSmallRotary = LeseSmallRotaryWert();
    if (neuePositionSmallRotary != oldPositionSmallRotary)
    {
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.setCursor(1, 40);
      u8g2.print(MenuePunkt);
      u8g2.setCursor(15, 60);
      u8g2.drawBox(10, 48, 108, 14);
      u8g2.setDrawColor(0);
      if (Was[AktuellesEtikett] == LOW)
      {
        u8g2.print(F("Deaktiviert"));
        Was[AktuellesEtikett] = HIGH;
      }
      else
      {
        u8g2.print(F(" Aktiviert"));
        Was[AktuellesEtikett] = LOW;
      }
      u8g2.setDrawColor(1);
      u8g2.sendBuffer();
      oldPositionSmallRotary = neuePositionSmallRotary;
      SetzeSmallRotaryWert(neuePositionSmallRotary);
      EinWertNeu = HIGH;  //EEPROM-Write aktiviert - ein Wert geändert
    }

  } //while Taster nicht gedrückt
  if (Was[AktuellesEtikett] == LOW) Was[AktuellesEtikett] = HIGH;
  else Was[AktuellesEtikett] = LOW;

  SetzeSmallRotaryWert(altePositionSmallRotary); // zurück an die richtige Stelle
  altePositionSmallRotary = 99;
  buzzer(BUZZER_LONG);
  Entprellen();
}


void PositionAnfahren() {
  int oldPositionSmallRotary = 0;
  Entprellen();
  PositionBigRotary = abs(LeseBigRotaryWert());

  SetzeSmallRotaryWert(0);
  SetzeBigRotaryWert(0);
  int OldBig = 99;
  char SpeedAnzeige[32]; 
  strcpy(SpeedAnzeige, "<<Drehregler>>"); 

  while (digitalRead(SmallRotary_PIN_SW)) {
    neuePositionSmallRotary = LeseSmallRotaryWert();

    // Motor steuern, unabhängig davon, ob sich die Position geändert hat
    if (neuePositionSmallRotary > 0) {
      if (neuePositionSmallRotary > 8) {
        SetzeSmallRotaryWert(9);
        neuePositionSmallRotary = 9;
      }
      snprintf(SpeedAnzeige, sizeof(SpeedAnzeige), "%d ", neuePositionSmallRotary); 
      MotorVor(neuePositionSmallRotary);
      for (int i = 1; i <= neuePositionSmallRotary; i++) {
        strcat(SpeedAnzeige, ">"); 
      }
    } else if (neuePositionSmallRotary < 0) {
      if (neuePositionSmallRotary < -8) {
        SetzeSmallRotaryWert(-9);
        neuePositionSmallRotary = -9;
      }
      snprintf(SpeedAnzeige, sizeof(SpeedAnzeige), "%d ", -neuePositionSmallRotary); 
      MotorRueck(-neuePositionSmallRotary);
      for (int i = -1; i >= neuePositionSmallRotary; i--) {
        strcat(SpeedAnzeige, "<"); 
      }
    } else {
      strcpy(SpeedAnzeige, "<<Drehregler>>"); 
      MotorStop();
    }

    // Display aktualisieren, wenn sich die Position geändert hat
    if (neuePositionSmallRotary != oldPositionSmallRotary) {
      u8g2.setDrawColor(0);
      u8g2.drawBox(0, 49, 128, 14); 
      u8g2.setDrawColor(1);
      u8g2.setCursor(1, 60);
      u8g2.print(SpeedAnzeige);
      u8g2.sendBuffer();
      oldPositionSmallRotary = neuePositionSmallRotary;
      SetzeSmallRotaryWert(neuePositionSmallRotary);
    }

    PositionBigRotary = abs(LeseBigRotaryWert());

    // Display aktualisieren, wenn sich PositionBigRotary geändert hat
    if (PositionBigRotary != OldBig) {
      // ... (Code zum Aktualisieren des Displays)
    }

    Serial.println("Ende PositionAnfahren"); // Neue Debug-Ausgabe
  } //while Taster nicht gedrückt

#if myDEBUG
  Serial.println(F("Startpos gef."));
#endif
  Entprellen();
  SetzeSmallRotaryWert(0);
  SetzeBigRotaryWert(0);
  OldBig = 99;
  strcpy(SpeedAnzeige, "<<Drehregler>>"); // Zurücksetzen des C-Strings
  while (digitalRead(SmallRotary_PIN_SW))
  {
    neuePositionSmallRotary = LeseSmallRotaryWert();
    if (neuePositionSmallRotary != oldPositionSmallRotary)
    {
#if myDEBUG
      Serial.print(F("SmallRot:"));
      Serial.println(neuePositionSmallRotary); // ...soll die aktuelle Position im seriellen Monitor ausgegeben werden.
#endif
      u8g2.setDrawColor(0);
      u8g2.drawBox(0, 49, 128, 14); //löschen der Zeile
      u8g2.setDrawColor(1);
      u8g2.setCursor(1, 60);
      if  (neuePositionSmallRotary > 0)
      {

        if (neuePositionSmallRotary > 8)
        {
          SetzeSmallRotaryWert(9);
          neuePositionSmallRotary = 9;
        }
        snprintf(SpeedAnzeige, sizeof(SpeedAnzeige), "%d ", neuePositionSmallRotary); 
        MotorVor(neuePositionSmallRotary); 
        for (int i = 1; i <= neuePositionSmallRotary; i++)
        {
          strncat(SpeedAnzeige, ">", sizeof(SpeedAnzeige) - strlen(SpeedAnzeige) - 1);
        }
      }
      else if (neuePositionSmallRotary < 0)
      {

        if (neuePositionSmallRotary < -8)
        {
          SetzeSmallRotaryWert(-9);
          neuePositionSmallRotary = -9;
        }
        snprintf(SpeedAnzeige, sizeof(SpeedAnzeige), "%d ", -neuePositionSmallRotary); 
        MotorRueck(-neuePositionSmallRotary); 
        for (int i = -1; i >= neuePositionSmallRotary; i--)
        {
          strncat(SpeedAnzeige, "<", sizeof(SpeedAnzeige) - strlen(SpeedAnzeige) - 1);
        }
      }
      else
      {
         if (MitFuss[AktuellesEtikett]) strncpy(SpeedAnzeige, "<FussT>", sizeof(SpeedAnzeige)); 
         else strncpy(SpeedAnzeige, "GlasDrauf", sizeof(SpeedAnzeige)); 
         MotorStop();
      }
      u8g2.print(SpeedAnzeige);
      u8g2.sendBuffer();
      oldPositionSmallRotary = neuePositionSmallRotary;
      SetzeSmallRotaryWert(neuePositionSmallRotary);
    }
    PositionBigRotary = abs(LeseBigRotaryWert());

    if (PositionBigRotary != OldBig)
    {
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.setCursor(1, 15);
      if (altePositionSmallRotary == 2)
      {
        u8g2.print(F("END-POSITION:"));
        u8g2.setFont(u8g2_font_courB08_tf);
        u8g2.setCursor(1, 30);
        u8g2.print(F("Etikett ans nächste"));
        u8g2.setCursor(1, 45);
        u8g2.print(F("Glas fahren ->"));
      }
      else
      {
        u8g2.print(F("DRUCK-POSITION:"));
        u8g2.setFont(u8g2_font_courB08_tf);
        u8g2.setCursor(1, 30);
        u8g2.print(F("Etikett an die Druck-"));
        u8g2.setCursor(1, 45);
        u8g2.print(F("Position fahren"));
      }
      u8g2.setCursor(93, 45);
      u8g2.setFont(u8g2_font_courB10_tf);
      u8g2.print(PositionBigRotary);
      u8g2.setCursor(1, 60);
      u8g2.print(SpeedAnzeige);
      u8g2.sendBuffer();
      OldBig = PositionBigRotary;
    }

  } //while Taster nicht gedrückt

  if (altePositionSmallRotary == 2)
  {
    Etikettenlaenge[AktuellesEtikett] = abs(LeseBigRotaryWert());
#if myDEBUG
    Serial.print(F("Endpos gef."));
    Serial.println(Etikettenlaenge[AktuellesEtikett]);
#endif
  }
  else
  {
    ZeitBisDatumDruck[AktuellesEtikett] = abs(LeseBigRotaryWert());
#if myDEBUG
    Serial.print(F("Druckpos.gef."));
    Serial.println(ZeitBisDatumDruck[AktuellesEtikett]);
    Serial.print(F("alte rotPOs:"));
    Serial.println(altePositionSmallRotary);
#endif
  }
  SetzeSmallRotaryWert(altePositionSmallRotary - 1); // zurück an die richtige Stelle
  altePositionSmallRotary = 99;
  buzzer(BUZZER_LONG);
  EinWertNeu = HIGH;  //EEPROM-Write aktiviert - ein Wert geändert
  Entprellen();
}


void buzzer(byte type)
{

  pinMode(Buzzer_PIN, OUTPUT);
  delay(100);
  switch (type)
  {
    case BUZZER_SHORT: //short
      if (MitBuzzer[AktuellesEtikett])
      {
        digitalWrite(Buzzer_PIN, HIGH);
        delay(100);
        digitalWrite(Buzzer_PIN, LOW);
      }
      else
      {
        delay(100);
      }
      break;

    case BUZZER_LONG: //long
      if (MitBuzzer[AktuellesEtikett])
      {
        digitalWrite(Buzzer_PIN, HIGH);
        delay(500);
        digitalWrite(Buzzer_PIN, LOW);
      }
      else delay(500);
      break;

    case BUZZER_SUCCESS: //success
      if (MitBuzzer[AktuellesEtikett])
      {
        digitalWrite(Buzzer_PIN, HIGH);
        delay(100);
        digitalWrite(Buzzer_PIN, LOW);
        delay(100);
        digitalWrite(Buzzer_PIN, HIGH);
        delay(100);
        digitalWrite(Buzzer_PIN, LOW);
        delay(100);
        digitalWrite(Buzzer_PIN, HIGH);
        delay(100);
        digitalWrite(Buzzer_PIN, LOW);
      }
      else delay(500);
      break;

    case BUZZER_ERROR: //error
      if (MitBuzzer[AktuellesEtikett])
      {
        digitalWrite(Buzzer_PIN, HIGH);
        delay(1500);
        digitalWrite(Buzzer_PIN, LOW);
      }
      else delay(1500);
      break;
  }
}

bool Ultraschallsensor(float Schwelle) {
  bool glasda = LOW;

  float Abstand = 0; //KUD Abstand initialisieren
  for (int i = 1; i <= n_pings; i++) {
    Abstand = Abstand + get_distance(); //KUD Ultraschallsensor auslesen
  }

  Abstand = Abstand / n_pings; //KUD Mittelwertbildung

  if (Abstand <= Schwelle) {
    glasda = HIGH;
  }

  return (glasda);

}

float get_distance() { //KUD Abstand Glas von Ultraschallsensor
  float duration = 0;
  float distance = 0;

  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  noInterrupts();
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  duration = pulseIn(NaeherungsSensor_PIN, HIGH); // Erfassung - Dauer in Mikrosekunden
  interrupts();

  distance = (duration / 2) / 29.1; // Distanz in CM
  return (distance);
}

//------------------------------------------
// StartLOGO
//------------------------------------------
void print_logo() {
  u8g2.clearBuffer();          // clear the internal memory
  u8g2.setFont(u8g2_font_courB10_tf);
  u8g2.setCursor(1, 10);    u8g2.print(F("Achtung:"));
  u8g2.setCursor(1, 25);    u8g2.print(F("Debug"));
  u8g2.setCursor(1, 40);    u8g2.print(F("an!!!"));


  u8g2.setFont(u8g2_font_courB14_tf);
#if mySYSTEM
  u8g2.setCursor(85, 20);    u8g2.print(F("Et"));
  u8g2.setCursor(80, 40);    u8g2.print(F("Vom"));
  u8g2.setCursor(52, 60);    u8g2.print(F("Schleck"));
#else
  u8g2.setCursor(85, 27);    u8g2.print("Etti");
  u8g2.setCursor(73, 43);    u8g2.print("MANDL");
  u8g2.setCursor(85, 54);
#endif
  u8g2.setFont(u8g2_font_courB10_tf);
  u8g2.setCursor(0, 62); u8g2.print(Version);
  u8g2.sendBuffer();
  delay(2000);
  DisplayNeutral();
}



//----------------------------------------------------------------
// Schreibe in Memory
//----------------------------------------------------------------
void WriteMem() {

#if mySYSTEM
  byte low, high, set;
  byte  AnzahlWerte = 23;

  set = 99;
  EEPROM.write(0, set); // Zeichen, dass bereits aktiv beschrieben wurde

  for (int w = 0; w < 3; w++) //Position 1-69
  {
    low = Etikettenlaenge[w] & 0xFF;
    high = (Etikettenlaenge[w] >> 8) & 0xFF;
    EEPROM.write(1 + (w * AnzahlWerte), low);
    EEPROM.write(2 + (w * AnzahlWerte), high);

    EEPROM.write(3 + (w * AnzahlWerte), MitBuzzer[w]);

    low = Counter[w] & 0xFF;
    high = (Counter[w] >> 8) & 0xFF;
    EEPROM.write(4 + (w * AnzahlWerte), low);
    EEPROM.write(5 + (w * AnzahlWerte), high);

    low = MaxSpeed[w] & 0xFF;
    high = (MaxSpeed[w] >> 8) & 0xFF;
    EEPROM.write(6 + (w * AnzahlWerte), low);
    EEPROM.write(7 + (w * AnzahlWerte), high);

    low = Acceleration[w] & 0xFF;
    high = (Acceleration[w] >> 8) & 0xFF;
    EEPROM.write(8 + (w * AnzahlWerte), low);
    EEPROM.write(9 + (w * AnzahlWerte), high);

    EEPROM.write(10 + (w * AnzahlWerte), MitFuss[w]);

    EEPROM.write(11 + (w * AnzahlWerte), MitDruck[w]);

    low = ZeitBisDatumDruck[w] & 0xFF;
    high = (ZeitBisDatumDruck[w] >> 8) & 0xFF;
    EEPROM.write(12 + (w * AnzahlWerte), low);
    EEPROM.write(13 + (w * AnzahlWerte), high);


    low = MitLuft[w] & 0xFF;
    high = (MitLuft[w] >> 8) & 0xFF;
    EEPROM.write(20 + (w * AnzahlWerte), low);
    EEPROM.write(21 + (w * AnzahlWerte), high);

    low = DruckTrockenZeit[w] & 0xFF;
    high = (DruckTrockenZeit[w] >> 8) & 0xFF;
    EEPROM.write(22 + (w * AnzahlWerte), low);
    EEPROM.write(23 + (w * AnzahlWerte), high);
  }

  EEPROM.write(70, AktuellesEtikett);
#else
  preferences.begin("EEPROM", false);
  preferences.putUInt("AktEtikett", AktuellesEtikett);
  preferences.putUInt("EtiLaenge0", Etikettenlaenge[0]);
  preferences.putUInt("EtiLaenge1", Etikettenlaenge[1]);
  preferences.putUInt("EtiLaenge2", Etikettenlaenge[2]);
  preferences.putBool("MitBuzzer0", MitBuzzer[0]);
  preferences.putBool("MitBuzzer1", MitBuzzer[1]);
  preferences.putBool("MitBuzzer2", MitBuzzer[2]);
  preferences.putUInt("Counter0", Counter[0]);
  preferences.putUInt("Counter1", Counter[1]);
  preferences.putUInt("Counter2", Counter[2]);
  preferences.putUInt("MaxSpeed0", MaxSpeed[0]);
  preferences.putUInt("MaxSpeed1", MaxSpeed[1]);
  preferences.putUInt("MaxSpeed2", MaxSpeed[2]);
  preferences.putUInt("Acceleration0", Acceleration[0]);
  preferences.putUInt("Acceleration1", Acceleration[1]);
  preferences.putUInt("Acceleration2", Acceleration[2]);
  preferences.putBool("MitFuss0", MitFuss[0]);
  preferences.putBool("MitFuss1", MitFuss[1]);
  preferences.putBool("MitFuss2", MitFuss[2]);
  preferences.putBool("MitDruck0", MitDruck[0]);
  preferences.putBool("MitDruck1", MitDruck[1]);
  preferences.putBool("MitDruck2", MitDruck[2]);
  preferences.putUInt("ZeitBisDruck0", ZeitBisDatumDruck[0]);
  preferences.putUInt("ZeitBisDruck1", ZeitBisDatumDruck[1]);
  preferences.putUInt("ZeitBisDruck2", ZeitBisDatumDruck[2]);
  preferences.putUInt("MitLuft0", MitLuft[0]);
  preferences.putUInt("MitLuft1", MitLuft[1]);
  preferences.putUInt("MitLuft2", MitLuft[2]);
  preferences.putUInt("TrockenZeit0", DruckTrockenZeit[0]);
  preferences.putUInt("TrockenZeit1", DruckTrockenZeit[1]);
  preferences.putUInt("TrockenZeit2", DruckTrockenZeit[2]);
  preferences.end();

#endif

/*
#if myDEBUG
  Serial.println(F("EE_Writing"));
  Serial.print( F("Aktuelles Etikett: ") );
  Serial.println(AktuellesEtikett + 1);

  for (int d = 0; d < 3; d++)
  {
    Serial.print( F("Etikettenlaenge") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(Etikettenlaenge[d]);

    Serial.print( F("ZeitBisDatumDruck") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(ZeitBisDatumDruck[d]);

    Serial.print( F("Buzzer") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(MitBuzzer[d]);

    Serial.print( F("Counter") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(Counter[d]);

    Serial.print( F("DruckOption") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(MitDruck[d]);

    Serial.print( F("DruckTrockenZeit") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(DruckTrockenZeit[d]);

    Serial.print( F("Lüfter") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(MitLuft[d]);

    Serial.println();
  }

#endif
*/
}
//----------------------------------------------------------------


//----------------------------------------------------------------
// Lese aus Memory
//----------------------------------------------------------------
void ReadMem() {

#if mySYSTEM //Arduino NANO
  byte low, high, set;
  byte  AnzahlWerte = 23;
  set = EEPROM.read(0);

  if (set == 99) //Gibt es bereits Daten im EEPROM?
  {
    for (int r = 0; r < 3; r++) //Position 1-69
    {
      low = EEPROM.read(1 + (r * AnzahlWerte));
      high = EEPROM.read(2 + (r * AnzahlWerte));
      Etikettenlaenge[r]  = low + ((high << 8) & 0xFF00);

      MitBuzzer[r] = EEPROM.read(3 + (r * AnzahlWerte));

      low = EEPROM.read(4 + (r * AnzahlWerte));
      high = EEPROM.read(5 + (r * AnzahlWerte));
      Counter[r]  = low + ((high << 8) & 0xFF00);

      low = EEPROM.read(6 + (r * AnzahlWerte));
      high = EEPROM.read(7 + (r * AnzahlWerte));
      MaxSpeed[r]  = low + ((high << 8) & 0xFF00);

      low = EEPROM.read(8 + (r * AnzahlWerte));
      high = EEPROM.read(9 + (r * AnzahlWerte));
      Acceleration[r]  = low + ((high << 8) & 0xFF00);

      MitFuss[r] = EEPROM.read(10 + (r * AnzahlWerte));

      MitDruck[r] = EEPROM.read(11 + (r * AnzahlWerte));

      low = EEPROM.read(12 + (r * AnzahlWerte));
      high = EEPROM.read(13 + (r * AnzahlWerte));
      ZeitBisDatumDruck[r]  = low + ((high << 8) & 0xFF00);


      low = EEPROM.read(20 + (r * AnzahlWerte));
      high = EEPROM.read(21 + (r * AnzahlWerte));
      MitLuft[r]  = low + ((high << 8) & 0xFF00);

      low = EEPROM.read(22 + (r * AnzahlWerte));
      high = EEPROM.read(23 + (r * AnzahlWerte));
      DruckTrockenZeit[r]  = low + ((high << 8) & 0xFF00);
    }
    AktuellesEtikett = EEPROM.read(70);
  }

#else //ESP32


  preferences.begin("EEPROM", false);

  AktuellesEtikett = preferences.getUInt("AktEtikett", 0);

  Etikettenlaenge[0] = preferences.getUInt("EtiLaenge0", 500);
  Etikettenlaenge[1] = preferences.getUInt("EtiLaenge1", 1000);
  Etikettenlaenge[2] = preferences.getUInt("EtiLaenge2", 2000);

  ZeitBisDatumDruck[0] = preferences.getUInt("ZeitBisDruck0", 250);
  ZeitBisDatumDruck[1] = preferences.getUInt("ZeitBisDruck1", 500);
  ZeitBisDatumDruck[2] = preferences.getUInt("ZeitBisDruck2", 1000);

  MitBuzzer[0] = preferences.getBool("MitBuzzer0", 1);
  MitBuzzer[1] = preferences.getBool("MitBuzzer1", 0);
  MitBuzzer[2] = preferences.getBool("MitBuzzer2", 0);

  Counter[0] = preferences.getUInt("Counter0", 0);
  Counter[1] = preferences.getUInt("Counter1", 0);
  Counter[2] = preferences.getUInt("Counter2", 0);

  MaxSpeed[0] = preferences.getUInt("MaxSpeed0", 1000);
  MaxSpeed[1] = preferences.getUInt("MaxSpeed1", 1000);
  MaxSpeed[2] = preferences.getUInt("MaxSpeed", 1000);

  Acceleration[0] = preferences.getUInt("Acceleration0", 0);
  Acceleration[1] = preferences.getUInt("Acceleration1", 0);
  Acceleration[2] = preferences.getUInt("Acceleration2", 0);

  MitFuss[0] = preferences.getBool("MitFuss0", 0);
  MitFuss[1] = preferences.getBool("MitFuss1", 0);
  MitFuss[2] = preferences.getBool("MitFuss2", 0);

  MitDruck[0] = preferences.getBool("MitDruck0", 0);
  MitDruck[1] = preferences.getBool("MitDruck1", 0);
  MitDruck[2] = preferences.getBool("MitDruck2", 0);



  MitLuft[0] = preferences.getUInt("MitLuft0", 0);
  MitLuft[1] = preferences.getUInt("MitLuft1", 0);
  MitLuft[2] = preferences.getUInt("MitLuft2", 0);

  DruckTrockenZeit[0] = preferences.getUInt("TrockenZeit0", 0);
  DruckTrockenZeit[1] = preferences.getUInt("TrockenZeit1", 0);
  DruckTrockenZeit[2] = preferences.getUInt("TrockenZeit2", 0);
  // preferences.clear();  Falls mal mal das EE-Prom leeren will
  preferences.end();

#endif

/*
#if myDEBUG
  Serial.println(F("EE_Reading"));
  Serial.print( F("Aktuelles Etikett: ") );
  Serial.println(AktuellesEtikett + 1);

  for (int d = 0; d < 3; d++)
  {
    Serial.print( F("Etikettenlaenge") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(Etikettenlaenge[d]);
    Serial.print( F("ZeitBisDatumDruck") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(ZeitBisDatumDruck[d]);

    Serial.print(d + 1);
    Serial.print( F(": ") );



    Serial.print( F("MitDruck") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(MitDruck[d]);

    Serial.print( F("MitLuft") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    if (MitLuft[d] > 10) MitLuft[d] = 10;
    Serial.println(MitLuft[d]);

    Serial.print( F("DruckTrockenZeit") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.print(DruckTrockenZeit[d]);
    Serial.print( F(" / ") );
    if (DruckTrockenZeit[d] > 60) DruckTrockenZeit[d] = 60;
    Serial.println(DruckTrockenZeit[d]);

    Serial.print( F("Buzzer") );
    Serial.print(d + 1);
    Serial.print( F(": ") );
    Serial.println(MitBuzzer[d]);
    Serial.println();
  }


#endif
*/
}

Was hast du für einen Antriebsmotor

Schrittmotor oder Gleichstrom-Motor?

Ich habe einen NEMA 17 Schrittmotor mit einem TMC2208 Treiber

Also das ist ja merkwürdig die functions motorVor / motorzurück enthalten keine Ansteuerung des Schrittmotors. Sondern nur Ansteuerung für einen Gleichstrommotor.

oder willst du mit dem encoder-drehen einen anderen Motor als den Schrittmotor ansteuern?

void MotorVor(int Speed) {
#if myDRIVE
  int SpeedOutput = min(255, 75 + Speed * 20); // erst ab ca 100 dreht der 12V Gleichstrommotor
  Serial.print("MotorVor - Speed: ");
  Serial.println(Speed);
  Serial.print("SpeedOutput: ");
  Serial.println(SpeedOutput);
  analogWrite(MotorEnable_PIN, 255);
  digitalWrite(Motorsteuerung_PIN1, HIGH); // Motor läuft vorwärts
  digitalWrite(Motorsteuerung_PIN2, LOW);

#if myDEBUG
  Serial.print(F("Motor vorwärts - mit "));
  Serial.print( (SpeedOutput * 100) / 100);
  Serial.println(F("%"));
#endif
#endif
}


void MotorRueck(int Speed) {

#if myDRIVE
  int SpeedOutput = 75 + Speed * 20; // Erst ab ca. 100 dreht der 12V Gleichstrommotor
  Serial.print("MotorRueck - Speed: ");
  Serial.println(Speed);
  Serial.print("SpeedOutput: ");
  Serial.println(SpeedOutput);
  analogWrite(MotorEnable_PIN, 255);
  digitalWrite(Motorsteuerung_PIN1, LOW);
  digitalWrite(Motorsteuerung_PIN2, HIGH);

#if myDEBUG
  Serial.print(F("Motor rückwärts - mit "));
  Serial.println(SpeedOutput);
#endif
#endif
}

Ich will den Schrittmotor ansteuern und das funktioniert ja auch schon in einem Menü vom Quellcode.

Hier wird der Schrittmotor angesprochen und er läuft hier
//----------------------------------------------------------------
// DIREKTE MOTORANSTEUERUNG: VORWÄRTS UND RÜCKWÄRTS ZUM JUSTIEREN
//----------------------------------------------------------------
void Handsteuerung()
{
  String SpeedAnzeige;
  neuePositionSmallRotary = LeseSmallRotaryWert();
  if (neuePositionSmallRotary != altePositionSmallRotary)
  {
    Serial.print("Neue Position SmallRotary: "); 
    Serial.println(neuePositionSmallRotary);
    
    u8g2.setDrawColor(0);
    u8g2.drawBox(0, 37, 128, 16); //löschen der Zeile
    u8g2.setDrawColor(1);
    u8g2.setCursor(1, 50);
    if  (neuePositionSmallRotary > 0)
    {

      if (neuePositionSmallRotary > 8)
      {
        SetzeSmallRotaryWert(9);
        neuePositionSmallRotary = 9;
      }
      SpeedAnzeige = String(neuePositionSmallRotary) + " ";
      MotorVor(neuePositionSmallRotary);
      for (int i = 1; i <= neuePositionSmallRotary; i++)
      {
        SpeedAnzeige = SpeedAnzeige + ">";
      }
    }
    else if (neuePositionSmallRotary < 0)
    {

      if (neuePositionSmallRotary < -8)
      {
        SetzeSmallRotaryWert(-9);
        neuePositionSmallRotary = -9;
      }
      SpeedAnzeige = String(-neuePositionSmallRotary) + " ";
      MotorRueck(-neuePositionSmallRotary);
      for (int i = -1; i >= neuePositionSmallRotary; i--)
      {
        SpeedAnzeige = SpeedAnzeige + "<";
      }
    }
    else
    {
      if (MitFuss[AktuellesEtikett]) SpeedAnzeige = "<FussT>";
      else SpeedAnzeige = "GlasDrauf";
      MotorStop();
    }



    u8g2.print(SpeedAnzeige);
    u8g2.sendBuffer();
    altePositionSmallRotary = neuePositionSmallRotary;
    PositionSmallRotary = neuePositionSmallRotary;
  }
#if !myDRIVE
  if (PositionSmallRotary != 0)
  {
    stepper.setEnablePin(MotorEnable_PIN);
    int SpeedOutput;
    if (PositionSmallRotary > 0) SpeedOutput = MaxSpeed[AktuellesEtikett] * 100 * PositionSmallRotary / 9;
    else SpeedOutput = -(MaxSpeed[AktuellesEtikett] * 100 * abs(PositionSmallRotary) / 9);
    stepper.setSpeed(SpeedOutput);
    stepper.runSpeed();
  }
  else stepper.disableOutputs();
#endif

}

Da zeigt sich mal wieder, dass es eben doch wichtig ist VIELE Informationen ins erste Posting zu packen. Als da wären

  • Link zum Originalprojekt
  • Fotos vom kompletten eigenen Aufbau
  • präzise Benennung der Baugruppen: Schrittmotor, Schrittmotortreiber, usw.

Ja aber nur in der Handsteuerung wird der Schrittmotor auch wirklich angesteuert.
mit diesen Zeilen hier

Da steht zwar auch was von motorVor() / motorRueck() drin
aber in den functions motorVor() / motorRueck()
ist (bisjetzt ) kein code der den Schrittmotor ansteuern würde.

Gehe jetzt ins Bett. Ich muss morgen früh raus.

Das mit den ein/ausklappbaren Details empfiehlt sich wenn das Posting "höher" als eine Bildschirmhöhe werden würde.

Ok, ein wenig mehr Infos machen schon sinn ...

Hier ist das Projekt beschrieben. Etikettiermaschine. - Heilbronner Gartenhonig

Weiter unten sieht man das Video "zweiter Prototyp einer Etikettiermaschine..." und ein paar Bilder zum Aufbaue.

Der Motor wird angesteuert und das Band treibt die Walze vom Drehgeber an und hier werden die Schritte gemessen die der Motor nachher drehen muss.

Über das Plastikteil zwischen den beiden schwarzen Rollen wird das Etikett abgestreift. Mit der Handsteuerung fährt man das Etikett bis ans Glas. Mit der Funktion anfahren wird das Etikett ausgemessen und wie weit der Motor drehen muss das das nächste Etikett am nächsten Glas anliegt.

Der eigentliche Programmierer hat mir den Quellcode geschickt und gemeint er hat ihn so im Einsatz und nutzt einen ESP32 und einen Steppermotor ....

Ob ich das Projekt auf einem ESP32 oder dem Nano umsetze ist mir egal, hab beide da.

Hier der Orignale Quellcode ohne Änderungen von meiner Seite:
EtVomSchleck2.6_210305.ino (78,8 KB)

Das kann NICHT sein. Das genau der Quellcode auf einem ESP32 läuft
Hier ist der Compiler-Schalter auf Nano-Every gesetzt

// Allgemeine Konfiguration DEBUG/GRAFIK/System Information
//----------------------------------------------------------------
#define mySYSTEM            1            // 1= Arduino Every / 0 = ESP32

Welcher Drehgeber?
Wieso braucht es bei einem Schrittmotor einen Drehgeber?

Wenn der Schrittmotor "im Bereich normaler Parameter" betrieben wird, dann weiß das Programm ganz genau wo sich der Schrittmotor befindet.
Das Video hier ist hilfreich für das Verständnis

hängt am Aufbau welche Rolle angetrieben wird.
Im Fall vom TO verändert sich durch das Aufwickeln des Trägerpapiers der Rollendurchmesser. Daher gibts eine extra Rolle mit Drehgeber.

Ähnliches Thema gabs bei der anderen Honig-Etikettiermaschine auch schon.

Es ist der Original Quellcode vom Programmierer, ich hab den Schalter für mich nur auf den Arduino Every gesetzt.

@noiasca so habe ich die Funktion auch verstanden warum er einen Drehgeber verwendet hat.

Ich habe diesen Aufbau nachgebaut, von der Mechanik her nur etwas stabiler.

Könnte es bei dem Problem mit dem ESP32 auch an einem falschen ESP32 Board liegen?

Es könnte sich um einen "AZDelivery ESP32 Dev Kit C V4 NodeMCU" handeln, zumindest ist die Rückseite identisch wenn ich es auf dem Bild richtig sehe.