Ja, sieht gut aus 
Aber wie Du weißt, schaue ich genau:
- Ich kann "Auswahl?" nirgendwo in MenüCode finden.
Das Increment der Displayzeit funktioniert nicht. Ich drehe am Encoder und nichts ändert sich. Innerhalb der Menüpunkte funktioniert Increment und Decrement. Ursache konnte ich noch nicht entdecken.
- Wenn ich die veränderte Displayzeit mit einem kurzen Klick bestätige, bleibt die Zeit weiter angezeigt. Beim Drehen geht es aber zu WLAN. Da fände ich es besser, wenn die Anzeige verschwindet.
Mein Testprogramm für 20x4 LCD an I²C, aber nur zwei Zeilen genutzt:
#include <Wire.h>
#include <NoiascaLiquidCrystal.h> // use the library downloaded from https://werner.rothschopf.net/202009_arduino_liquid_crystal_intro.htm/
#include <NoiascaHW/lcd_PCF8574.h> // include the proper IO interface
LiquidCrystal_PCF8574 lcd(0x27, 20, 4); // create lcd object - with support of special characters
// Rotary
#include <rotary.h>
Rotary r = Rotary(45, 43);
const byte rotBut = 41;
const byte mutBut = 2;
const byte mutLed = LED_BUILTIN;
const uint32_t bounceTime = 20; // zeit in ms
// LCD
const byte lcdSpalten = 20;
const byte lcdZeilen = 2;
const char chars[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz1234567890"};
// Inhalt
struct inhalt
{
char name[lcdSpalten];
char hid[2];
};
inhalt MyFilter[]
{
{"Auswahl?", "" }, {"Filter 1", "a"},
{"Filter 2", "s"}, {"Filter 3", "d"},
{"Filter 4", "f"}
};
inhalt MySetup[]
{
{"Displayzeit" , "" }, {"Wlan" , "g"},
{"Filternamen" , "" }, {"Platzhalter 1", "j"},
{"Platzhalter 2", "k"}, {"Platzhalter 3", "l"},
{"Platzhalter 4", "q"}, {"Platzhalter 5", "w"},
{"exit" , "" },
};
uint32_t displayZeit = 1000UL * 10; // Zeit in ms
uint32_t displayTick = 0;
bool isDisplay = true; // Hilfsvariable
bool isMenu = true;
bool isSetup = !isMenu;
bool isTasteKurz = false;
bool isTasteLang = false;
bool isMute = false;
bool isWlan = false;
void setup()
{
Wire.begin(); // start I2C library
lcd.begin(); // initialize the LCD
lcd.backlight(); // turn on backlight
Serial.begin(115200);
Serial.println(F("Start..."));
startSequenz();
pinMode (rotBut, INPUT);
pinMode (mutBut, INPUT_PULLUP);
pinMode (mutLed, OUTPUT);
}
void loop()
{
if (isMute)
{
heartbeat(500);
}
else
{
if (digitalRead(mutLed)) digitalWrite(mutLed, LOW);
if (isMenu) myMenu();
if (isSetup) mySetup();
getRotaryButton();
}
getMute();
setDisplayLight();
if (!isDisplay)
{
isMenu = true; isSetup = false;
}
}
void myMenu()
{
const char displayZeileOben[] = "Filter wählen";
static int8_t rotaryPos = 0;
static int8_t lastRotaryPos = 100;
const uint8_t maxPos = sizeof(MyFilter) / sizeof(inhalt) - 1;
rotaryPos = getRotary(rotaryPos);
if (rotaryPos != lastRotaryPos)
{
if (rotaryPos > maxPos) rotaryPos = 0;
else if (rotaryPos < 0) rotaryPos = maxPos;
lastRotaryPos = rotaryPos;
Serial.print(F("menu "));
Serial.println(rotaryPos);
ausgabe(displayZeileOben, MyFilter[rotaryPos].name);
}
if (isTasteKurz)
{
sendHid(MyFilter[rotaryPos].hid);
isTasteKurz = false;
}
if (isTasteLang)
{
isMenu = false; isSetup = true;
isTasteLang = false;
lastRotaryPos = 100;
}
if (!isDisplay) rotaryPos = 0;
}
void mySetup()
{
const uint8_t maxPos = sizeof(MySetup) / sizeof(inhalt) - 1;
static int8_t rotaryPos = 0;
static int8_t lastRotaryPos = maxPos + 1;
static int8_t menuPos = 0;
uint32_t sekunde = 0;
if (menuPos == 0)
{
rotaryPos = getRotary(rotaryPos);
if (rotaryPos != lastRotaryPos)
{
if (rotaryPos > maxPos) rotaryPos = 0;
else if (rotaryPos < 0) rotaryPos = maxPos;
lastRotaryPos = rotaryPos;
Serial.println(F("setup "));
Serial.println(rotaryPos);
ausgabe(MySetup[rotaryPos].name, "");
}
}
switch (menuPos)
{
case 1:
{
sekunde = displayZeit / 1000;
menuPos = setupZahl(sekunde, menuPos);
if (sekunde < 5) sekunde = 5;
else if (sekunde > 84600) sekunde = 84600;
char buf[6] = {'\0'};
sprintf(buf, "%ld", sekunde);
ausgabe(MySetup[rotaryPos].name, buf);
displayZeit = 1000UL * sekunde;
}
break;
case 2:
// Wlan
isWlan = !isWlan;
sendHid(MySetup[rotaryPos].hid);
if (isWlan)
ausgabe(MySetup[rotaryPos].name, " ausgelöst");
else
ausgabe(MySetup[rotaryPos].name, " gestoppt");
menuPos = 0;
break;
case 3:
// Namen ändern....
menuPos = setMyName(menuPos);
break;
case 4 ... 8:
sendHid(MySetup[rotaryPos].hid);
break;
case maxPos+1:
menuPos = 0;
rotaryPos = 0;
isMenu = true;
isSetup = false;
isTasteKurz = false;
break;
}
if (isTasteKurz)
{
if (menuPos == 0)
menuPos = rotaryPos + 1;
else
menuPos = 0;
isTasteKurz = false;
}
if (isTasteLang)
{
isMenu = true; isSetup = false;
isTasteLang = false;
}
if (!isDisplay)
{
menuPos = 0;
rotaryPos = 0;
}
}
uint8_t setMyName(uint8_t menuWert)
{
uint8_t maxPos = 10;
//static byte pos = 0;
static int8_t rotaryPos = 0;
static int8_t lastRotaryPos = maxPos + 1;
static int8_t menuPos = 0;
if (menuPos == 0)
{
rotaryPos = getRotary(rotaryPos);
if (rotaryPos != lastRotaryPos)
{
if (rotaryPos > maxPos) rotaryPos = 0;
else if (rotaryPos < 0) rotaryPos = maxPos;
lastRotaryPos = rotaryPos;
Serial.println(F("setup "));
Serial.println(rotaryPos);
ausgabe(MySetup[rotaryPos].name, "");
}
}
if (isTasteLang)
{
menuWert = 0;
isTasteLang = false;
}
return menuWert;
}
uint8_t setupZahl(uint32_t &aenderZahl, uint8_t menuWert )
{
static uint32_t lastZahl = 0;
aenderZahl = getRotary(aenderZahl);
if (aenderZahl != lastZahl)
{
lastZahl = aenderZahl;
Serial.println(F("Zahl geändert: "));
Serial.println(aenderZahl);
}
if (isTasteKurz)
{
menuWert = 0;
isTasteKurz = false;
}
return menuWert;
}
void sendHid(char *zeichen)
{
Serial.print(F("HID: "));
Serial.println(zeichen);
}
void ausgabe(const char *zeile1, const char *zeile2)
{
char buf[21] = {'\0'};
snprintf( buf, sizeof(buf), "%s ", zeile1 );
lcd.setCursor(0, 0);
lcd.print(buf);
snprintf( buf, sizeof(buf), "%s ", zeile2 );
lcd.setCursor(0, 1);
lcd.print(buf);
static char lastZeileOben[lcdSpalten] = {'\0'};
static char lastZeileUnten[lcdSpalten] = {'\0'};
if (strcmp(lastZeileOben, zeile1))
{
memset(lastZeileOben, '\0', lcdSpalten);
strcpy(lastZeileOben, zeile1);
Serial.print(F("Zeile 1: "));
Serial.println(lastZeileOben);
}
if (strcmp(lastZeileUnten, zeile2))
{
memset(lastZeileUnten, '\0', lcdSpalten);
strcpy(lastZeileUnten, zeile2);
Serial.print(F("Zeile 2: "));
Serial.println(lastZeileUnten);
}
}
void setDisplayLight()
{
if (millis() - displayTick > displayZeit && !isMute)
{
if (isDisplay)
{
Serial.println(F("Display aus!"));
lcd.setBacklight(0);
isDisplay = false;
}
}
else
{
if (!isDisplay)
{
Serial.println(F("Display an!"));
lcd.setBacklight(255);
isDisplay = true;
}
}
}
void getMute()
{
static uint32_t lastmillis = 0;
static bool isPressed = false;
if (!digitalRead(mutBut) && !isPressed)
{
isPressed = true;
displayTick = millis();
lastmillis = millis();
isMute = !isMute;
if (isMute) ausgabe("Mute aktiv", "");
//sendHid("e");
}
else if ((millis() - lastmillis > bounceTime) &&
(digitalRead(mutBut) && isPressed))
{
isPressed = false;
}
}
void getRotaryButton()
{
static uint32_t lastmillis = 0;
static uint32_t pressTime = 0;
static bool isPressed = false;
if (!digitalRead(rotBut))
{
if (!isPressed)
{
pressTime = millis();
isPressed = true;
}
lastmillis = millis();
displayTick = millis();
}
else if (millis() - lastmillis > bounceTime)
{
if (isPressed)
{
if (millis() - pressTime < 500)
{
isTasteKurz = true;
Serial.println(F("kurz"));
}
else
{
isTasteLang = true;
Serial.println(F("lang"));
}
isPressed = false;
}
}
}
uint32_t getRotary(uint32_t posValue)
{
unsigned char val = r.process();
if (val)
{
if (val == r.clockwise() && isDisplay)
{
Serial.print(F("rechts"));
posValue++;
}
else if (val == r.counterClockwise() && isDisplay)
{
Serial.print(F("links"));
posValue--;
}
Serial.println(F(" gedreht"));
displayTick = millis();
}
return posValue;
}
void heartbeat(const uint32_t tik)
{
static uint32_t lasttik = 0;
if (millis() - lasttik >= tik)
{
lasttik += tik;
digitalWrite(mutLed, !digitalRead(mutLed));
}
}
void startSequenz()
{
uint32_t startTime = millis();
ausgabe("Willkommen", "");
while (millis() - startTime < 1500) {}
startTime = millis();
ausgabe("Booting", "");
char zeile2[lcdSpalten] = {'\0'};
uint8_t pos = 0;
while (pos < lcdSpalten - 1)
{
if (millis() - startTime > 1000)
{
displayTick = millis();
zeile2[pos] = '*';
ausgabe("Booting", zeile2);
startTime = millis();
pos++;
}
}
}