Hallo,
ich baue von Zeit zu Zeit kleine Bedienteile mit vielen Tasten und LEDs. Diese Bedienteile geben RS-232 Befehle aus und werten diese auch aus.
Die Geräte, welche gesteuert werden haben mehrere Ebenen, durch die man dann mit den Tasten am Bedienteil navigieren kann.
Je größer und komplexer diese Bedienteile nun werden, desto wilder meine if-Bedinungen um Fehleingaben zu verhindern.
Hinzu kommt, dass ich auch Tastenkombinationen implementiere.
Hier exemplarisch ein kleiner Codeauszug:
/************************************************** Entprellung usw. */
t1_old_st = t1_st; // 3. "neuen Status" speichern
t2_old_st = t2_st;
t3_old_st = t3_st;
t4_old_st = t4_st;
t5_old_st = t5_st;
fz_old_st = fz_st;
t1_Bouncer.update ( ); // 1. Entprellten Zustand "erfragen"
t2_Bouncer.update ( );
t3_Bouncer.update ( );
t4_Bouncer.update ( );
t5_Bouncer.update ( );
fz_Bouncer.update ( );
t1_st = t1_Bouncer.read(); // 2. Tastenstatus aktualisieren
t2_st = t2_Bouncer.read();
t3_st = t3_Bouncer.read();
t4_st = t4_Bouncer.read();
t5_st = t5_Bouncer.read();
fz_st = fz_Bouncer.read();
t_st = (t1_st << 0 | t2_st << 1 | t3_st << 2 | t4_st << 3 | t5_st << 4 | fz_st << 5); // Speichern sämtlicher aktuellen(!) Tastzustände im Byte
/************************************************** Filterungen */
e_st = B00011111 & t_st; // Eingangstasten rausfiltern (XXXbbbbb)
e_fz_st = B00111111 & t_st; // Eingangstasten inkl. Freeze rausfiltern (XXbbbbbb)
}
/************************************************** Umschaltlogik für Ebenenwechsel */
void MSR_st_sw()
{
switch (sc_sel)
{
case 1: // Gerät "1"
{
if(IPHD_ready) // So lange eine gültige Verbindung besteht..
{
if(!tp_on && MSR_st != 1) // ..,kein Testbild aktiviert ist und das Hauptprogramm nicht aktiviert ist..
{
Serial.println("\t\t\t\tWechsel zum Hauptprogramm\n");
sw_time = millis();
MSR_st = 1;
}
if(tp_on && MSR_st != 2) // ..,ein Testbild aktiviert ist und das Testpattern-Programm nicht aktiviert ist..
{
Serial.println("\t\t\t\tWechsel zum Testpattern-Programm\n");
sw_time = millis();
MSR_st = 2;
}
}
}
}
}
if (t1_st != t1_old_st)
{
if (t1_st)
{
Serial.println("\t\t\t\t\t\tTaste 1 wurde gedrueckt");
t_hold_time = millis();
t_hold_st++;
}
else if (!t1_st)
{
Serial.println("\t\t\t\t\t\tTaste 1 wurde losgelassen");
t_hold_st--;
}
}
void t_func_main()
{
switch(sc_sel)
{
case 1: // Gerät "1"
{
if (t_st && sw_time < t_hold_time) // Wenn mind. ein Knopf gedrückt wird (weil das Byte != 0 ist) und erst nach einem Ebenen-Wechsel ein Knopf gedrückt wurde..
{
switch(e_st)
{
case B00000001: // Wenn Taste 1 betätigt wird..
{
if(t_hold_st == 1 && !t_act_st) // ..nur eine Taste gedrückt gehalten wird und diese "Aktion" noch nicht ausgeführt wurde..
{
Serial.println("Eingang 1 geschaltet");
Serial3.print("RTE 1\rFREEZ 0\r");
e_sw(1, 0, 0, 0, 0); // ..main_LED_st mit Schaltung für Eingang 1 beschreiben..
main_LED_st[5] = 0; // Freeze-LED ausschalten
t_act_st = 1;
}
if(e_fz_st == B00000001 && millis() - t_hold_time >= t_dur) // Wenn Taste 1 für ca. drei Sekunden gedrückt gehalten wird..
{
tp_1_sw();
}
if(e_fz_st == B00100001 && millis() - t_hold_time >= t_dur) // Wenn Taste 1 und Freeze für ca. drei Sekunden gedrückt gehalten werden..
{
Serial.println("Logocapture Eingang 1");
}
}
break;
Wie man dem Code entnehmen kann, breche ich mir fast Einen dabei ab, die "aktuelle Codeauswertung" (Gibt es hierfür eignetlich eine konkrete Bezeichnung?) dahin zu navigieren, wo ich sie gerne hätte, ohne dass dabei andere Aktionen ausgelöst werden.
Die Tasterzustände werden jeweils in einem Bit gespeichert, die Zustände der einzelnen LEDs jeweils als Byte in einem Array (eine 2x pro Sekunde blinkende LED hat dann z.B. den Wert 2).
Nun zu meiner Frage:
Gibt es bereits mehr oder weniger vorgefertigte Lösungen/ Libraries, die einem etwas von diesen mitunter äußerst komplexen Schaltlogiken abnehmen? Fehlersuche ist teilweise wirklich knallhart. :~
Gruß Chris