Allgemeine Codegestaltung von mehreren Programmen im Code

Gast #62687
Lesenswert?

Hallo,

ich weis die Überschrift klingt komisch aber ich meine was ganz
einfaches. An meinem Roboter soll ein LCD (funktioniert bereits) und 2
Taster angeschlossen werden. Man kommt zunächst in ein Menü kann dann
wählen (per Taster), kommt dann in Programm B oder alternativ Programm
C (beim anderen Taster), bei erneutem drücken wieder in Programm A.
Dabei bezeichnet "Programm" eine Ausgabe auf dem LCD und evtl
Steuerungsabläufe des Roboters.

Nur wie mache ich sowas überhaupt am besten. Irgendwie stehe ich da
etwas auf dem Schlauch wie ich diese Sprünge in den Programmen
realisieren könnte.
Ich hoffe mir kann das jemand recht anschaulich erklären (Bin noch neu
und unerfahren auf dem Gebiet!)

Vielen Dank !
mfg
Johannes
Gast #62690
Lesenswert?

Hallo Johannes,
hoffentlich habe ich Deine Frage richtig verstanden.

Du hast dein Problem doch so beschrieben:

3 unterschiedliche Funktionen:
Der bietet sich ein Aufzählungstyp an (enum)
Der ist auf FUNKTION_LCD gesetzt.
in main wird ein switch mit den möglichen funktionen durchlaufen.
Solange Du nichts anderes auswählst halt Deine LCD.
Die Funktion LCD läuft solange, bis eine Taste gedrückt wird.
Bei diesem Tastendruck wird die globale Variable neue_funktion mit dem
wert der Funktion beschrieben und die LCD-Funktion wird verlassen.
Beim Durchlauf der switches in main wird nun die neue Funktion
aufgerufen.

Der Programmablauf verkompliziert sich noch etwas, wenn Du tatsächlich
mit der gleichen Taste aud der Funktion herausspringen wie
hineinspringen möchtest. Dann must Du noch eine Sperre gegen das
sofortige herausspringen einbauen. Ich mache in C++, also evtl. bool
usw. umschreiben.
Der nachstehende Code ist nicht compiliert oder gar getestet worden.
Nur als Anregung und Stichwortlieferant zu verstehen.


enum welche_funktion
{
  FUNKTION_LCD,
  FUNKTION_A,
  FUNKTION_B
};

welche_funktion neue_funktion;

bool tastenabfrage(void)
{
  bool retval = false;
  if (taste1 || taste2)
  {
    retval = true;
    if (taste1)
    {
      neue_funktion = FUNKTION_A;
    }else
    {
      if (taste2)
      {
        neue_funktion = FUNKTION_B;
      }
    }
  }
  return retval;
}

void lcd(void)
{
  while (!tastenabfrage())
  {
    // halt das Display verarbeiten
  }
}

void a_funktion(void)
{
  while (!tastenabfrage())
  {
    // halt Deine Funktion a ausführen
  }
  neue_funktion = FUNKTION_LCD;
}

// Die Funktion B genauso aufbauen

int main(void)
{
  for(;;)
  {
    switch (neue_funktion)
    {
      case FUNKTION_A:
        a_funktion();
        break;

      case FUNKTION_B:
        b_funktion();
        break;

      default:
        lcd();
        break;
    }
  }
}

Viel Spass
Oryx
Gast #62691
Lesenswert?

Okay das scheint mir n wirklich sehr brauchbares Konzept zu sein und
vielen dank für die mühe mit dem code, is echt gut verständlich. hab
echt selten so ne hilfsbereitschaft erlebt - 1A !!!

Riiiiießen Dankeschön !

mfg
johannes
Gast #62693
Lesenswert?

Ich versuche das mal etwas theoretischer und vielleicht auch allgemeiner
darzustellen:

Zunächst mal einen endlichen Automaten aufstellen. In dem oberen Fall
benötigt man 3 Zustände: ST_START, ST_A und ST_B. Im Anhang der Automat
als Grafik. Folgende Tabelle gibt die Übergänge an (für jede Eingabe in
einem Zustand der Folgezustand):

Eingabe  ST_START     ST_A       ST_B

   1       ST_A     ST_START     ST_A
   2       ST_B       ST_B     ST_START

Man darf auch Folgezustände leer lassen, muß dann aber aufpassen.

Als nächstes werden alle Zustände in ein enum gepackt und der
Startzustand definiert.

  enum state { ST_START, ST_A, ST_B } = ST_START;

Nun kann man den Automaten sehr einfach mit switch Statements
implementieren:

for(;;) {
  switch(state) {
     case ST_START:
        switch(eingabe) {
           case 1:
               state = ST_A;
               break;
           case 2:
               state = ST_B;
               break;
        }
        break;
     case ST_A:
        switch(eingabe) {
           case 1:
               state = ST_START;
               break;
           case 2:
               state = ST_B;
               break;
        }
        break;
     case ST_B:
        switch(eingabe) {
           case 1:
               state = ST_A;
               break;
           case 2:
               state = ST_START;
               break;
        }
        break;
  }
}

Als Schmankerl kann man das ganze auch noch minimieren, da spare ich
mir jetzt aber die Ausführungen dazu.

ciao, Stefan.

P.S. Solche Grundtechniken lernt man entweder im Studium (Technische)
Informatik oder auch in jeder Programmiererausbildung.
Angehängte Dateien:
Gast #62694
Lesenswert?

ich habe mir da vorhin auch Gedanken drüber gemacht und bin auf das
gekommen.

Und zwar habe ich einen Taster den man lang oder kurz drücken kann.
Bei kurzen drücken will ich nur durch die Menüs scrollen. menu wird um
eins erhöht.
Bleibt der taster länger gedrückt, soll etwas spwezielles ausgeführt
werden. menu wird um 10 erhöht.

Hab jetzt nur die ersten Untermenüs ausgeführt. was da im einzelnen
passiert ist ja auch egal..
1
switch (menu){
2
      case 0: TID8("-KMH    ");break;
3
  case 1: menu=100;break; 
4
  case 10: kmhmess();break;
5
  case 20: menu=10;break; //falls lang gedrückt wird, passiert nichts
6
  case 11: kmhmax();break;
7
  case 21: maxkmh=0;break;
8
  case 12: kmhschnitt();break;
9
  case 13: TID8("ZURUECK ");break;
10
  case 23: menu=0;break;
11
  
12
      case 100: TID8("-KM     ");break;
13
  case 101: menu=200;break;
14

15
  
16
  case 200: TID8("ZEITEN  ");break;
17
  case 201: menu=0;break;

ist das so auch mödlich oder gar schlecht?
gruss
Jens
Gast #62695
Lesenswert?

Switches sind zwar für den anfang ganz nett, aber für umfangreichere
menus eignen sich dann wohl eher callbacks. Vielfach verschachtelte
Menus sind mit einfachen swich-blocks nicht mehr sinnvoll zu handeln.
Das komplette Menu inklusive Aktionen kann man dann in ein großes Array
packen und hat so alle menu-spezifischen Daten an einem Fleck (->
Information Hiding).

Gruß,
Matthias

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren