//Quelle für die Codestruktur vom Menü:
//http://educ8s.tv/arduino-rotary-encoder-menu/#google_vignette
//Einbindung externer Bibliotheken
#include <LiquidCrystal_I2C.h> // Bibliothek für Display
//Deklaration der Variablen
int menuitem = 1; //Auswahl eines Menüpunktes
int frame = 1; //Variable für die Definition, welche Menüpunkte zum aktuellen Zeitpunkt zu sehen sind (relevant zum Scrollen)
int prevFrame = 0; //Variable zur Erkennung von Veränderungen im Frame
int page = 0; //Variable für Menüebene -> 0 = Statusanzeige; 1 = Hauptmenü; 2 = Untermenü
int prevPage = 0; //Variable zur Erkennung von Veränderungen in den Menüebenen
int lastMenuItem = 1; //Letzte Stelle, auf der der Cursor war
//Menüpunkte
String menuItem1 = "Filam.-Durchmesser";
String menuItem2 = "Spulen-Durchmesser";
String menuItem3 = "Geschwindigkeit";
String menuItem4 = "Stopp";
String menuItem5 = "Beleuchtung: AN";
String menuItem6 = "Reset";
String menuItem7 = "Zurueck";
//Konfigurationen in den einzelnen Untermenüs
boolean backlight = true; //Hintergrundbeleuchtung an
double reel = 217.0; //Spulendurchmesser
int speed = 10; //Start-Wert bei 10
String durchmesser[3] = { "1.75mm", "2.85mm", "3.00mm" }; //3 = Anzahl der Auswahlmöglichkeiten
int selectedDurchmesser = 0; //0 sagt, dass der 1. Wert, also 1,75mm, zuerst im Untermenü angezeigt wird
String stop[2] = { "System stoppen", "Zurueck" };
int selectedStop = 0;
//Pinbelegung des Drehencoders
#define ENCODER_CLK 2 //Drehencoder Puls(A) Daten Output 1
#define ENCODER_DT 3 //Drehencoder Puls(B) Daten Output 2
#define ENCODER_BTN 13 //Drehencoder Taster: Switch-Pin gibt LOW weiter bei Betätigen des Tasters
//Variablen für die Verarbeitung der Eingaben durch den Drehencoder
boolean up = false; //Nach oben im Menü, drehen gegen den Uhrzeigersinn
boolean down = false; //Nach unten im Menü, drehen mit dem Uhrzeigersinn
boolean middle = false; //Encoder Button wird gedrückt
int switchState_encoder; //Variable für den aktuellen Status des Encoder-Tasters
int prevSwitchState_encoder; //Variable, um den vorherigen Wert des Switchpins zu halten
int trueCursor; //Cursor zum Markieren des ausgewählten Menüpunktes
//Konfiguration des eingebundenen LCD-Displays
LiquidCrystal_I2C lcd(0x27, 20, 4);
//bewegendes Zeichen neben Hauptmenü
byte wheel1_1[8] = {
0b00011,
0b00100,
0b01010,
0b01001,
0b01001,
0b01010,
0b00100,
0b00011
};
byte wheel1_2[8] = {
0b11000,
0b00100,
0b01010,
0b10010,
0b10010,
0b01010,
0b00100,
0b11000
};
byte wheel2_1[8] = {
0b00011,
0b00100,
0b01000,
0b01111,
0b01001,
0b01001,
0b00101,
0b00011
};
byte wheel2_2[8] = {
0b11000,
0b10100,
0b10010,
0b10010,
0b11110,
0b00010,
0b00100,
0b11000
};
//Pfeil-Zeichen für Menü
byte arrow[8] = {
0b01000,
0b01100,
0b01110,
0b01111,
0b01110,
0b01100,
0b01000,
0b00000
};
//Durchmesser Symbol
byte durchmesser_1[8] = {
0b00001,
0b00010,
0b00100,
0b00100,
0b00100,
0b00101,
0b00010,
0b00101
};
byte durchmesser_2[8] = {
0b11101,
0b00010,
0b00101,
0b01001,
0b10001,
0b00001,
0b00010,
0b11100
};
void setup() {
lcd.begin(20, 4);
lcd.backlight();
lcd.print("Volkswagen - EIS20");
lcd.setCursor(0, 1);
lcd.print("APT2-Projekt");
lcd.setCursor(0, 2);
lcd.print("Filament-Aufwickler");
delay(1500);
lcd.clear();
//Initialisierung aller IN- und OUTPUTs
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
pinMode(ENCODER_BTN, INPUT_PULLUP); //Encoder SW-Pin
turnBacklightOn(); //Hintergrundbeleuchtung aktivieren
lcd.createChar(0, wheel1_1);
lcd.createChar(1, wheel1_2);
lcd.createChar(2, wheel2_1);
lcd.createChar(3, wheel2_2);
lcd.createChar(4, arrow); //Pfeil für Anzeige des ausgewählten Menüpunktes
lcd.createChar(5, durchmesser_1);
lcd.createChar(6, durchmesser_2);
drawMenu(); //Darstellung des Displayinhalts
Serial.begin(9600);
}
unsigned long curMillisA; //für Schnelligkeit der Animation hinter Hauptmenü
unsigned long prevMillisA; //für Schnelligkeit der Animation hinter Hauptmenü
void loop()
{
readRotaryEncoder(); //Auslesen der Drehrichtung
switchState_encoder = digitalRead(ENCODER_BTN); //Auslesen des Encoder-Buttons
/*Ist eine Veränderung des Encoder-Buttons wahrzunehmen, dann soll beim Betätigen (PullUp, deswegen LOW)
die dazugehörige Variable auf "true" (1) gesetzt und der Displayinhalt beim Öffnen eines neuen Fensters
gelöscht werden. Damit diese Funktion wiederholt funktioniert, wird die Variable für die aktuelle Seite
auf die Variable für die vorherige Seite gesetzt. */
if (switchState_encoder != prevSwitchState_encoder) { //Wenn der aktuelle Status des Encoders ungleich dem vorherigen Standes ist
switch (switchState_encoder) { //aktueller Status des Encoders
case LOW: // sonst immer auf high (Pull Up -> in Setup), wenn also Encoder gedrückt = LOW
middle = true; //Encoder Button wird gedrückt -> auf 1
if (page != prevPage) { //wenn die aktuelle Seite ungleich der vorherigen ist,
lcd.clear(); //wird der alte Inhalt gelöscht
prevPage = page; //und die neue Seite wird als vorherige Seite benannt
}
//break; //Verhindern von Ausführen nachfolgender Anweisungen
}
}
prevSwitchState_encoder = switchState_encoder; //Zwischenspeichern des aktuellen Zustandes
if (middle) //Wenn der Encoder-Button gedrückt wurde:
{
middle = false; //aktueller Wert, nachdem der Taster gedrückt wurde (true) wird auf Ausgangswert (false) zurückgesetzt
if (page == 0)
{
lcd.clear();
page = 1;
}
else if (page == 1 && menuitem == 5) //Kontrolle der Hintergrundbeleuchtung: wenn Seite 1 und Item 5 (Hintergrundbeleuchtung)
{
if (backlight) //Überprüfen der Hintergrundbeleuchtung
{
backlight = false; //wenn false
menuItem5 = "Beleuchtung: AUS"; //Ausgabe: Bleuchtung:AUS
turnBacklightOff(); //Beleuchtung wird ausgeschaltet
}
else
{
backlight = true; //wenn wahr
menuItem5 = "Beleuchtung: AN "; //Ausgabe: Bleuchtung:AN
turnBacklightOn(); //Beleuchtung wird eingeschaltet
}
}
else if (page == 1 && menuitem == 6) //Reset: Item 6 (Reset) ist im Hauptmenü ausgewählt -> wenn Reset betätigt wird...
{
resetDefaults(); //...werden Voreinstellungen zurückgesetzt
}
else if (page == 1 && menuitem <= 4) //Öffnen der Untermenüs(page = 2) der Menüpunkte 1-4
{
page = 2;
}
else if (page == 2) //Schließen des Untermenüs -> von Untermenü (page 2) in Hauptmenü (page 1) gehen
{
page = 1;
}
else if (page == 1 && menuitem == 7) //NEU
{
lcd.clear();
page = 0;
frame = 1;
menuitem = 1;
}
drawMenu(); //Ausgabe der Verarbeitung auf dem Display
}
//für ANIMATION hinter der Anzeige Hauptmenü
if (page == 1)
{
curMillisA = millis();
int fpsAnimation = 500; //Anzeige von 0,5 Sekunden
if (curMillisA - prevMillisA > fpsAnimation * 2)
{
prevMillisA = curMillisA;
}
else if (curMillisA - prevMillisA < fpsAnimation)
{
lcd.setCursor(15, 0); //Anzeigen der Animation in 1. Zeile, 16. Pixel -> 15, weil von 0 beginnend
lcd.write(byte(0)); //Verweis bei -> lcd.createChar(0, wheel1_1);
lcd.write(byte(1));
}
else if (curMillisA - prevMillisA > fpsAnimation)
{
lcd.setCursor(15, 0);
lcd.write(byte(2));
lcd.write(byte(3));
}
lcd.setCursor(0, trueCursor); //Cursor in 1. Pixel; vor Menüpunkt
lcd.write(byte(4));
}
lcd.display(); //alle Inhalte auf dem Display anzeigen
}
//DREHRICHTUNG DES ENCODERS
void encoderChanged()
{
//HAUPTMENÜ UP
if (up && page == 1 ) //Der Encoder wird im Hauptmenü gegen den Uhrzeigersinn gedreht, nach oben im Menü
{
up = false;
/*Beim Durchlauf der Menüpunkte von unten nach oben, sollen die Menüpunkte
wie beim Scrollen von oben auftauchen, bis man wieder beim Startpunkt ist.
Dazu wird kontrolliert, wann sich der Cursor im jeweilgen Frame in der
obersten Stellung befindet.*/
if (menuitem == 2 && frame == 2) //wenn 2. Menüpunkt an 1. Stelle im LCD ausgewählt ist (Cursor an dieser Stelle, oberer Rand) und 2.,3.,4. Menüpunkt sichtbar ist
{
frame--; //Beim nächsten Drehen gegen den Uhrzeigersinn wird frame verringert = frame 1
}
if (menuitem == 3 && frame == 3) //wenn 3. Menüpunkt ausgewählt ist (Cursor an dieser Stelle, oberer Rand) und 3.,4.,5. Menüpunkt sichtbar ist
{
frame--; //Beim nächsten Drehen gegen den Uhrzeigersinn wird frame verringert = frame 2
}
if (menuitem == 4 && frame == 4 ) //wenn 4. Menüpunkt ausgewählt ist (Cursor an dieser Stelle, oberer Rand) und 4.,5.,6. Menüpunkt sichtbar ist
{
frame--; //Beim nächsten Drehen gegen den Uhrzeigersinn wird frame verringert = frame 3
}
if (menuitem == 5 && frame == 5 ) //wenn 4. Menüpunkt ausgewählt ist (Cursor an dieser Stelle, oberer Rand) und 4.,5.,6. Menüpunkt sichtbar ist
{
frame--; //Beim nächsten Drehen gegen den Uhrzeigersinn wird frame verringert = frame 3
}
lastMenuItem = menuitem; //Abspeichern des letzten Menüpunktes im Hintergrund
menuitem--; //Da durch das Hochscrollen wieder die vorherigen Menüpunkte erscheinen sollen, wird der Wert der Variable dekrementiert.
//Grenze, dass der Wert von "menuitem" nicht ins Negative gehen kann
if (menuitem == 0)
{
menuitem = 7;
frame = 5;
}
}
//UNTERMENÜ UP
//Je nachdem, in welchem Untermenü man sich befindet, soll der Wert der jeweilgen Variable dekrementiert (verringert) werden
else if (up && page == 2 && menuitem == 1 ) //Filament-Durchmesser Untermenü
{
up = false; //Encoder gegen Uhrzeigersinn...
selectedDurchmesser--; //...Ausgabe des geringerern Werts
if (selectedDurchmesser == -1) //Wenn der ausgewählte Durchmesser-Wert kleiner als 0 (Encoder erneut gegen Uhrzeigersinn gedreht) wird,...
{
selectedDurchmesser = 2; //...soll der letzte bzw. größte Durchmesser-Wert angezeigt werden
}
}
else if (up && page == 2 && menuitem == 2 && reel) //Spulen-Durchmesser Untermenü
{
up = false; //Encoder gegen Uhrzeigersinn...
reel = reel - 0.1; //...Ausgabe eines geringeren Werts
}
else if (up && page == 2 && menuitem == 3 && speed > 0) //Geschwindigkeit Untermenü; Wert muss größer 0 sein
{
up = false; //Encoder gegen Uhrzeigersinn...
speed--; //...Ausgabe eines geringeren Werts
}
else if (up && page == 2 && menuitem == 4 ) //Stopp Untermenü
{
up = false; //Encoder gegen Uhrzeigersinn...
selectedStop--; //Ausgabe Wert: "Zurück"
if (selectedStop == -1) //Wenn der ausgewählte Wert kleiner als 0 (Encoder erneut gegen Uhrzeigersinn gedreht) wird,...
{
selectedStop = 1; //...soll der 2. Wert: hier "System stoppen" angezeigt werden
}
}
//HAUPTMENÜ DOWN
if (down && page == 1) //Der Encoder wird im Uhrzeigersinn gedreht
{
//Gleiches Prinzip wie bei Drehen gegen Uhrzeigersinn. Menüführung nach unten
down = false;
if (menuitem == 3 && lastMenuItem == 2) //Wenn ausgewähltes MenüItem 3 ist & Cursor zuletzte auf MenüItem 2 stand...
{
frame ++; //...wird beim nächsten Drehen bzw. Hochzählen der frame von 1 auf 2 geändert
}
else if (menuitem == 4 && lastMenuItem == 3) //Wenn ausgewähltes MenüItem 4 ist & Cursor zuletzte auf MenüItem 3 stand...
{
frame ++; //..wird beim nächsten Drehen bzw. Hochzählen der frame von 2 auf 3 geändert
}
else if (menuitem == 5 && lastMenuItem == 4) //Wenn ausgewähltes MenüItem 5 ist & Cursor zuletzte auf MenüItem 4 stand...
{
frame ++; //...wird beim nächsten Drehen bzw. Hochzählen der frame von 3 auf 4 geändert
}
else if (menuitem == 6 && lastMenuItem == 5 && frame != 5) //NEU
{
frame ++;
}
else if (menuitem==7 && frame==5)
{
lcd.clear();
frame = 1;
menuitem = 0;
}
lastMenuItem = menuitem; //MenüItem, auf dem der Cursor zuletzt Stand, wird nach Drehen im Uhrzeugersinn überschrieben zu aktuellem MenüItem
menuitem++; //nach Drehen des Encoders im Uhrzeigersinn wird MenüItem hochgezählt
//Menüitem kann den Wert von 7 nicht überschreiten
if (menuitem == 8)
{
menuitem--; //Wert 8 wird dekrementiert
}
}
//UNTERMENÜ DOWN
else if (down && page == 2 && menuitem == 1 ) //Filament-Durchmesser Untermenü und Encoder im Uhrzeigersinn
{
down = false; //Encoder wird im Uhrzeigersinn gedreht
selectedDurchmesser++; //Durchmesser-Wert wird hochgezählt bzw. nächster Wert wird angezeigt
if (selectedDurchmesser == 3) //Wenn der Durchmesser-Wert den höchsten bzw. letzten Wert erreicht,...
{
selectedDurchmesser = 0; //...wird beim nächsten Drehen im Uhrzeigersinn der 1. Wert wieder angezeigt
}
}
else if (down && page == 2 && menuitem == 2) //Spulen-Durchmesser Untermenü und Encoder im Uhrzeigersinn
{
down = false; //Encoder wird im Uhrzeigersinn gedreht
reel = reel + 0.1; //Spulen-Durchmesser-Wert wird hochgezählt bzw. nächster Wert wird angezeigt
}
else if (down && page == 2 && menuitem == 3 && speed < 30) //Geschwindigkeit Untermenü und Encoder im Uhrzeigersinn; Wert soll kleiner 30 sein
{
down = false; //Encoder wird im Uhrzeigersinn gedreht
speed++; //Geschwindigkeits-Wert wird hochgezählt
}
else if (down && page == 2 && menuitem == 4 ) //Schwierigkeit Untermenü und Encoder im Uhrzeigersinn
{
down = false; //Encoder wird im Uhrzeigersinn gedreht
selectedStop++; //Wert wird hochgezählt bzw. "Zurueck" wird angezeigt
if (selectedStop == 2) //wenn der Encoder erneut im Uhrzeigersinn gedreht wird und somit der Wert=2 ist...
{
selectedStop = 0; //...wird deer Wert wieder auf 0 gesetzt, da es nur 2 (0=System stoppem, 1=Zurueck) Werte gibt
}
}
drawMenu(); //Ausgabe der Verarbeitung auf dem Display
}
//Funktion für die Darstellung des Menüs auf dem Display
void drawMenu()
{
if (page == 0) //Statusanzeige
{
lcd.backlight();
lcd.setCursor(3, 0);
lcd.print("Statusanzeige");
lcd.setCursor(0, 2);
lcd.print("Drehgeschw.:");
lcd.setCursor(1, 3);
lcd.print("Fuellstand:");
}
if (page == 1) //wenn man sich im Hauptmenü befindet
{
//Anzeige der Überschrift des Hauptmenüs
lcd.setCursor(4, 0);
lcd.print("HAUPTMENUE");
//Sobald ein neuer Frame geöffnet wird, sollen die Begriffe gelöscht werden,
//um Buchstabenreste auf dem Display bei Überschreibungen zu vermeiden.
if (frame != prevFrame) { //Wenn der aktuelle Frame ungleich dem vorherigen ist
displayMenuItem(" ", 1, false);
displayMenuItem(" ", 2, false);
displayMenuItem(" ", 3, false);
prevFrame = frame; //Der vorherige Frame wird vom aktuellen überschrieben
}
/*Je nachdem, welcher Menüpunkt in welchem Frame ausgewählt ist, dienen die
folgenden If-Funktion der Vorbereitung für die Darstellung des Menüs auf dem Display.
Da immer drei Menüpunkte zu sehen sind, wird immer dreimal pro Funktion auf die Unterfunktion
"displayMenuItemX" zugegriffen. */
//Frame 1
if (menuitem == 1 && frame == 1) //Frame 1 & Filament-Durchmesser ausgewählt
{
displayMenuItem(menuItem1, 1, true); //Variablen und Werte aus der Klammer: (1. Name des Menüpunktes, Zeileneinordnung, Ausgewählt: Ja/Nein)
displayMenuItem(menuItem2, 2, false);
displayMenuItem(menuItem3, 3, false);
}
else if (menuitem == 2 && frame == 1) //Frame 1 & Spulen-Durchmesser ausgewählt
{
displayMenuItem(menuItem1, 1, false);
displayMenuItem(menuItem2, 2, true); //Cursor auf Spulen-Durchmesser
displayMenuItem(menuItem3, 3, false);
}
else if (menuitem == 3 && frame == 1) //Frame 1 & Geschwindigkeit ausgewählt
{
displayMenuItem(menuItem1, 1, false);
displayMenuItem(menuItem2, 2, false);
displayMenuItem(menuItem3, 3, true);
}
//Frame 2
else if (menuitem == 4 && frame == 2) //Frame 2 & Stopp ausgewählt
{
displayMenuItem(menuItem2, 1, false);
displayMenuItem(menuItem3, 2, false);
displayMenuItem(menuItem4, 3, true);
}
else if (menuitem == 3 && frame == 2) //Frame 2 & Geschwindigkeit ausgewählt
{
displayMenuItem(menuItem2, 1, false);
displayMenuItem(menuItem3, 2, true);
displayMenuItem(menuItem4, 3, false);
}
else if (menuitem == 2 && frame == 2) //Frame 2 & Spulen-Durchmesser ausgewählt
{
displayMenuItem(menuItem2, 1, true);
displayMenuItem(menuItem3, 2, false);
displayMenuItem(menuItem4, 3, false);
}
//Frame 3
else if (menuitem == 5 && frame == 3) //Frame 3 & Beleuchtung ausgewählt
{
displayMenuItem(menuItem3, 1, false);
displayMenuItem(menuItem4, 2, false);
displayMenuItem(menuItem5, 3, true);
}
else if (menuitem == 3 && frame == 3) //Frame 3 & Geschwindigkeit ausgewählt
{
displayMenuItem(menuItem3, 1, true);
displayMenuItem(menuItem4, 2, false);
displayMenuItem(menuItem5, 3, false);
}
else if (menuitem == 4 && frame == 3) //Frame 3 und Stopp ausgewählt
{
displayMenuItem(menuItem3, 1, false);
displayMenuItem(menuItem4, 2, true);
displayMenuItem(menuItem5, 3, false);
}
//Frame 4
else if (menuitem == 6 && frame == 4) //Frame 4 & Reset ausgewählt
{
displayMenuItem(menuItem4, 1, false);
displayMenuItem(menuItem5, 2, false);
displayMenuItem(menuItem6, 3, true);
}
else if (menuitem == 5 && frame == 4) //Frame 4 & Beleuchtung ausgewählt
{
displayMenuItem(menuItem4, 1, false);
displayMenuItem(menuItem5, 2, true);
displayMenuItem(menuItem6, 3, false);
}
else if (menuitem == 4 && frame == 4) //Frame 4 und Stopp ausgewählt
{
displayMenuItem(menuItem4, 1, true);
displayMenuItem(menuItem5, 2, false);
displayMenuItem(menuItem6, 3, false);
}
//Frame 5
else if (menuitem == 5 && frame == 5) //Frame 5 & Beleuchtung ausgewählt
{
displayMenuItem(menuItem5, 1, true);
displayMenuItem(menuItem6, 2, false);
displayMenuItem(menuItem7, 3, false);
}
else if (menuitem == 6 && frame == 5) //Frame 5 & Reset ausgewählt
{
displayMenuItem(menuItem5, 1, false);
displayMenuItem(menuItem6, 2, true);
displayMenuItem(menuItem7, 3, false);
}
else if (menuitem == 7 && frame == 5) //Frame 5 und Zurueck ausgewählt
{
displayMenuItem(menuItem5, 1, false);
displayMenuItem(menuItem6, 2, false);
displayMenuItem(menuItem7, 3, true);
}
}
//Darstellung der Einstellungen im Untermenü
else if (page == 2 && menuitem == 1) //Untermenü Filamentdurchmesser
{
displayStringMenuPage(menuItem1, durchmesser[selectedDurchmesser]); //Wert 0 (selectedDurchmesser) wird als 1. Wert für Durchmesser festgelegt
}
else if (page == 2 && menuitem == 2) //Untermenü Spulendurchmesser
{
displaydoubleMenuPage(menuItem2, reel); //Wert 217 wird als 1. Wert festgelegt; springt in Header displayIntMenüPage und überschreibt Werte beim Drehen des Encoders
}
else if (page == 2 && menuitem == 3) //Untermenü Geschwindigkeit
{
displayIntMenuPageSpeed(menuItem3, speed); //Wert 30 wird als 1. Wert festgelegt; springt in Header displayIntMenüPage und überschreibt Werte beim Drehen des Encoders
}
else if (page == 2 && menuitem == 4) //Untermenü Stopp
{
displayStringMenuPageStop(menuItem4, stop[selectedStop]); //Wert 0 (selectedStop) wird als 1. Wert für Stopp festgelegt
}
}
//Funktion für das Reset: Zurücksetzen aller Voreinstellungen
void resetDefaults()
{
//Variablen werden auf ihre Initialisierungswerte zurückgesetzt
reel = 217.0;
speed = 10;
selectedDurchmesser = 0;
selectedStop = 0;
backlight = true;
menuItem5 = "Beleuchtung: AN ";
turnBacklightOn();
}
//Funktionen für das Ein- bzw. Ausstellen der Hintergrundbeleuchtung
void turnBacklightOn()
{
lcd.backlight();
}
void turnBacklightOff()
{
lcd.noBacklight();
}
//DARSTELLUNG DER UNTERMENÜS
//Funktion zur Darstellung des Untermenüs des Spulendurchmessers
void displaydoubleMenuPage(String menuItem, double value)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(menuItem); //Überschrift des aktuellen Untermenüs
lcd.setCursor(0, 2);
lcd.print("Wert in mm:");
lcd.setCursor(0, 3);
lcd.print(value);
lcd.display();
}
//Funktion zur Darstellung der Untermenüs, bei denen Texte verändert werden
void displayStringMenuPage(String menuItem, String value)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(menuItem);
lcd.setCursor(0, 2);
lcd.print("Wert:");
lcd.setCursor(0, 3);
lcd.print(value);
lcd.display();
}
//Funktion zur Darstellung des Untermenüs der Geschwindigkeit
void displayIntMenuPageSpeed(String menuItem, int value)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(menuItem);
lcd.setCursor(0, 1);
lcd.print("in mm/s:");
lcd.setCursor(0, 3);
lcd.print(value);
lcd.display();
}
//Funktion zur Darstellung des Untermenüs Stopp
void displayStringMenuPageStop(String menuItem, String value)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(menuItem);
lcd.setCursor(0, 2);
lcd.print("Aktion:");
lcd.setCursor(0, 3);
lcd.print(value);
lcd.display();
}
//Funktion für das Festlegen des ausgewählten Menüpunktes
void displayMenuItem(String item, int position, boolean selected)
{
/*Wenn der übergebene Parameter für "selected" gleich true ist, dann soll die
Position dieses Menüpunktes zwischengespeichert werden*/
if (selected)
{
trueCursor = position;
}
lcd.setCursor(0, position); //In der 1. Spalte auf dem LCD...
lcd.print(">" + item); //...wird ">" vor dem Menüpunkt ausgegeben
/*Serial.println(menuitem);
if (menuitem == 1 || menuitem == 2)
{
lcd.setCursor(9,position);
lcd.write(byte(5));
lcd.setCursor(10,position);
lcd.write(byte(6));
}
if(menuitem == 2)
{
lcd.setCursor(7,2);
lcd.write(byte(5));
lcd.setCursor(8,2);
lcd.write(byte(6));
}*/
}
int lastClk = HIGH; //CLK-Pin am Encoder (Daten Output) = HIGH
//Funktion zum Auslesen der Drehrichtung des Encoders
//Definition der Drehrichtung grafisch dargestellt unter folgenden Link:
//https://docs.wokwi.com/parts/wokwi-ky-040
void readRotaryEncoder()
{
int newClk = digitalRead(ENCODER_CLK);
if (newClk != lastClk) { //Eine Veränderung am CLK-Pin wurde wahrgenommen
lastClk = newClk;
int dtValue = digitalRead(ENCODER_DT);
if (newClk == LOW && dtValue == HIGH) {
down = true; //im Uhrzeigersinn
}
if (newClk == LOW && dtValue == LOW) {
up = true; //gegen Uhrzeigersinn
}
encoderChanged();
}
}