Es animiert mich aber auch, mal zu überlegen, wie ich das eventuell realisieren würde, denn derzeit ist das noch Neuland für mich.
Mein Ansatz wäre "weniger Programm", die "Daten steuern die Abläufe". Also mache ich ein Feld mit den Texten und eine Struktur für die Menüpunkte. Als Elemente neben dem Textzeiger noch Min- und Maxwert und die einzustellende Variable, derzeit immer 0 bis 255 für uint8_t, nur bei den Fahrspuren 1 bis 6 mit 4 als Startwert.
Die Anzahl der Fahrspuren könnte man also menue[5].wert entnehmen.
Meine Idee als getestetes Programm:
// Tower-Control auf MEGA 2560
const char ver[] = {"TC-V1.0.1 rotary"};
// LCD
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
// RotaryEncoder
#include <rotary.h>
Rotary r = Rotary(5, 3, 23); // Rotary(Encoder Pin 1, Encoder Pin 2, Button Pin)
const char *text[] = {
// 0 1 2 3 4
" Hauptmenue " , " Verlassen " , " Turm-Anzeige " , " Turm-Licht " , " Helligkeit " ,
// 5 6 7 8 9 10
" RGB-1 Werte " , " Fahrspuren " , " Startanzeige " , " IDNummer " , " Funkkanal " , " WerksWerte "
};
struct Menue
{
const char *zeile1;
const char typ;
const uint8_t min, max;
const uint8_t abwerk;
uint8_t wert;
};
Menue menue[] =
{
{text[ 0], '0', 1, 10, 0, 0}, // Hauptmenue
{text[ 1], 'V', 0, 0, 0, 0}, // Verlassen
{text[ 2], '1', 0, 255, 127, 127}, // Turm-Anzeige
{text[ 3], '2', 0, 255, 127, 127}, // Turm-Licht
{text[ 4], '3', 0, 255, 127, 127}, // Helligkeit
{text[ 5], '4', 0, 255, 127, 127}, // RGB-1 Werte
{text[ 6], '5', 1, 6, 4, 4}, // Fahrspuren
{text[ 7], '6', 0, 255, 127, 127}, // Startanzeige
{text[ 8], '7', 0, 255, 127, 127}, // IDNummer
{text[ 9], '8', 0, 255, 127, 127}, // Funkkanal
{text[10], 'W', 1, 10, 0, 0} // WerksWerte
};
void menueanzeige()
{
static uint8_t aktMenu = 255;
if (aktMenu > (sizeof(text) / sizeof(text[0])) )
{
r.process();
if (r.buttonPressedReleased(20))
{
aktMenu = 0; // Hauptmenü
menue[aktMenu].wert = 0;
}
} else {
menueausfuehrung(menue[aktMenu], aktMenu);
}
}
void menueausfuehrung(Menue &m, uint8_t &aktMenu)
{
uint8_t aktRotary = getRotary(m.wert, m.min, m.max); // Abfrage RotaryEncoder
static uint8_t altMenu = 255;
switch (m.typ)
{
case 'V':
lcd.clear();
lcd.print("Ende Menue Verl"); // Text nur jetzt zum Testen
aktMenu = 255;
altMenu = 255;
break;
case 'W':
for (uint8_t j = m.min; j < m.max; j++)
{
menue[j].wert = menue[j].abwerk;
}
lcd.clear();
lcd.print("Ende Menue Werk"); // Text nur jetzt zum Testen
aktMenu = 255;
altMenu = 255;
break;
default:
if ( (altMenu != aktMenu) || (m.wert != aktRotary) )
{
altMenu = aktMenu;
m.wert = aktRotary;
lcd.setCursor(0, 0);
lcd.print('*'); lcd.print(m.zeile1); lcd.print('*');
lcd.setCursor(0, 1);
if (aktRotary > m.min)
{
lcd.print("< ");
} else {
lcd.print(" ");
}
if (aktRotary < m.max)
{
lcd.print(">");
} else {
lcd.print(" ");
}
lcd.setCursor(1, 1);
if (aktMenu)
{
lcd.print(aktRotary);
} else {
lcd.print(text[aktRotary]);
}
}
if (r.buttonPressedReleased(20))
{
if (aktMenu)
{
aktMenu = 0;
} else {
aktMenu = aktRotary;
}
}
}
}
void setup()
{
Serial.begin(115200);
Serial.println(F("Start..."));
//lcd.begin(); // Für XY Projekt
lcd.init(); // Für Benziner und agmue
lcd.backlight();
// ************ Anfang LCD Start-Anzeige ***********
lcd.setCursor(0, 0);
lcd.print(ver);
// *************Ende LCD Start-Anzeige *************
}// Ende Setup
void loop()
{
//Serial.println("tak"); /debug non-Blocking anzeige();
menueanzeige();
}
uint8_t getRotary(uint8_t rotaryWert, const uint8_t rotaryMin, const uint8_t rotaryMax)
{
uint8_t lastRotary = rotaryWert; // fuer debugausgabe
uint8_t val = r.process(); // Check the encoder
if (val == r.clockwise())
{
rotaryWert ++;
}
else if (val == r.counterClockwise())
{
rotaryWert --;
}
if (rotaryWert > rotaryMax)
{
rotaryWert = rotaryMax;
}
else if (rotaryWert < rotaryMin)
{
rotaryWert = rotaryMin;
}
if (lastRotary != rotaryWert) Serial.println(rotaryWert); // debugausgabe
return rotaryWert;
}
Ich finde es kürzer und übersichtlicher ![]()
Nicht alle Ideen der letzten Beiträge sind berücksichtigt, ich hatte schon vorher angefangen ![]()
EDIT: Ich habe das Verlassen des Menüs überarbeitet. Ergänzt habe ich die Werkswerte und den Menütyp.