-         
Ergebnis 1 bis 4 von 4

Thema: Menü - ich krieg die Krise!!!

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    20.10.2004
    Ort
    Thüringen
    Beiträge
    133

    Menü - ich krieg die Krise!!!

    Anzeige

    Hi Leute,

    hoffentlich nerve ich nicht, mit meinen dauernden Fragen.
    Ich arbeite an einem Hausbussystem.
    Bin schon bei den ersten Tests.

    Nun möchte ich ein Menü in mein Prog einbringen und habe da einen Codeschnipsel gefunden. Nur blicke ich nicht so ganz durch...

    Vielleicht kann mir ein Profi unter Euch den entscheidenen Tip geben?

    Solang ich keine Taste drücke, bleibt das Display ohne ANzeige und das Prog im Schleife zur Tastenabfrage. Das Menü funktioniert super, nur ich komm nicht wieder raus in den Urzustand, wo ich in der Schleife bin und das Display mir wieder zur Verfügung steht.

    Habe auch den Simulator benutzt, aber ich komm nicht weiter...

    Ich möchte ein normales Hauptprogramm haben, wo bei Tastendruck in das Menü gesprungen wird. Wenn ich im Hauptmenü die Taste Menüzurück drücke, dann soll diese Schleife verlassen, das Display gelöscht, und ins Hauptprogramm zurück gekehrt werden.

    Kann mir mal jemand auf die Sprünge helfen?
    Code:
    $sim
    $regfile = "m32def.dat"                                     'Für ATMega 32
    $crystal = 14745000                                         '14 MHz-Quarz
    $baud = 9600
    $hwstack = 128
    $swstack = 40
    $framesize = 80
    
    'wenn Zeichen über RS485 empfangen, dann Interruptprogramm "Empfangen" anspringen
    'On Urxc Empfangen                                           'UART Interrupt bei Zeichen empfangen
    'Enable Urxc                                                 'UART Interrupt einschalten
    'Enable Interrupts                                           'Interrupts global ein
    
    Ddra = &B00110000
    Ddrb = &B00000000                                           '1=output ;  0=input
    Ddrd = &B11000000
    
    '*********** Belegung der Ein- und Ausgänge ********************
    '
    'PA0 bis PA3      Ein- oder Ausgänge anal. oder dig.
    'PA4              Buzzer
    'PA5              LED für Anzeigezwecke
    'PA6              SDA I2C
    'PA7              SCL I2C
    'PB0 bis PB7      8 Taster oder Tasten mit Inkrementalgeber
    'PC2 bis PC7      LCD-Anzeige
    'PD0              RXD
    'PD1              TXD
    'PD2              1wire-Sensor
    'PD4              DCF-77 Eingang
    'PD6              RS485 RX-TX-Umschaltung
    'PD7              RS485-RS232-Umschaltung
    
    
    Config Lcd = 20 * 4
    Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7 , E = Portc.3 , Rs = Portc.2
    Cursor Off                                                  ' Cursor ausschalten
    Cls                                                         'löschen display
    
    
    Dim Menuepunkt As Byte
    Menuepunkt = 2
    Dim Menuevor As Byte
    Menuevor = 2
    Dim Menuezurueck As Byte
    Menuezurueck = 2
    Dim Menuehoch As Byte
    Menuehoch = 2
    Dim Menuerunter As Byte
    Menuerunter = 2
    Dim Menuecase As Byte
    Dim Taste As Byte
    Dim Schonbearbeitet As Bit
    Declare Sub Menueupdate(submenupunkt As Byte , Submenucase As Byte , Submenuvor As Byte , Submenuzurueck As Byte , Submenuhoch As Byte , Submenurunter As Byte )
    
    Tastehoch Alias Pinb.0                                      'hier definiert ihr die tastenpins
    Tasterunter Alias Pinb.1
    Tastelinks Alias Pinb.3
    Tasterechts Alias Pinb.2
    Taster1 Alias Pinb.7
    Led Alias Porta.5
    
    'Initialisierung und Löschen evtl. Variablen
    Schonbearbeitet = 0
    Taste = 0
    
    Led = 1                                                     'led anschalten
    
    Startzeile:
    If Tastehoch = 0 Then
    Waitms 10                                                   'wegen Tastenprellen
    Taste = 1
    Goto Testen
    End If
    If Tasterunter = 0 Then
    Waitms 10
    Taste = 2
    Goto Testen
    End If
    If Tastelinks = 0 Then
    Waitms 10
    Taste = 3
    Goto Testen
    End If
    If Tasterechts = 0 Then
    Waitms 10
    Taste = 4
    Goto Testen
    End If
    Taste = 0
    Schonbearbeitet = 0
    Goto Startzeile
    
    Testen:
    If Schonbearbeitet = 0 Then Goto Neumenu
    Goto Startzeile
    
    Neumenu:
    Schonbearbeitet = 1
    Select Case Taste
    Case 1 : Menuepunkt = Menuehoch                             'je nach taste wird der neue menue-punkt gesetzt
    Case 2 : Menuepunkt = Menuerunter
    Case 3 : Menuepunkt = Menuezurueck
    Case 4 : Goto Caseauswertung
    End Select
    
    Menueupdaten:
    Call Menueupdate(menuepunkt , Menuecase , Menuevor , Menuezurueck , Menuehoch , Menuerunter)       'menue wird erneuert
    Menueende:
    
    Goto Startzeile
    
    Caseauswertung:
    If Menuecase = 0 Then
       Menuepunkt = Menuevor
       Goto Menueupdaten
    End If
    Cls
    Menuepunkt = 2
    Menuehoch = 2
    Menuerunter = 2
    Menuevor = 2
    Menuezurueck = 2
    'Select Case Menuecase                                       'hier kann die auswertung der ereignisse erfolgen
    'Case 1 :goto ..                                             'vor rückkehr zur tasten abfrage muß menuecase wieder auf 0
    'case 2 :goto ...                                            'gesetzt werden
    'case 3 :goto ...
    'End Select
    
    'Locate 2 , 1                                                'dies dient nur zum test
    'Lcd "Ereigniss  " ; Menuecase                               '      ""
    Menuecase = 0
    Goto Menueende
    
    Sub Menueupdate(submenupunkt As Byte , Submenucase As Byte , Submenuvor As Byte , Submenuzurueck As Byte , Submenuhoch As Byte , Submenurunter As Byte )       'sub zum erneuern des menues
    Cls
    Local Beendet As Byte
    Local Zahler As Byte
    Local Kurzstring As String * 4
    Local Langstring As String * 20
    Local Zeile1 As Byte
    
    Menurunter:
    Submenupunkt = Submenupunkt + 2                             'text und menuepunkt für taste runter-blättern wird gesucht und ausgegeben
    Kurzstring = Lookupstr(submenupunkt , Menue)
    Kurzstring = Left(kurzstring , 1)
    If Kurzstring = "#" Then
        Locate 4 , 1
        Lcd "********************"
        Submenupunkt = Submenupunkt - 2
        Submenurunter = Submenupunkt
    Else
        Submenurunter = Submenupunkt
        Langstring = Lookupstr(submenupunkt , Menue)
        Locate 4 , 1
        Lcd Langstring
        Submenupunkt = Submenupunkt - 2
    End If
    
    Aktuell:                                                    'text für aktuellen menuepunkt wird ausgegeben
    Langstring = Lookupstr(submenupunkt , Menue)
    Locate 3 , 1
    Lcd Chr(126) ; Langstring
    
    Menuevor:
    Submenupunkt = Submenupunkt + 1                             'text und menuepunkt für taste vor (rechts) wird gesucht und ausgegeben
    Kurzstring = Lookupstr(submenupunkt , Menue)
    Langstring = Left(kurzstring , 1)
    
    If Langstring = "!" Then
      Langstring = Right(kurzstring , 2)
      Submenucase = Val(langstring)
      Submenupunkt = Submenupunkt - 1
      Goto Menuehoch
      End If
    Submenucase = 0
    Kurzstring = "#" + Kurzstring
    Zahler = 0
    Beendet = 0
    Do
    Incr Zahler
    Langstring = Lookupstr(zahler , Menue)
    If Kurzstring = Langstring Then Beendet = 1
    Loop Until Beendet = 1
    Zahler = Zahler + 2
    Submenuvor = Zahler
    Submenupunkt = Submenupunkt - 1
    
    Menuehoch:                                                  'text und menuepunkt für taste hoch-blättern wird gesucht und ausgegeben
    Submenupunkt = Submenupunkt - 2
    Langstring = Lookupstr(submenupunkt , Menue)
    Kurzstring = Left(langstring , 1)
    If Kurzstring = "#" Then
         Locate 2 , 1
         Lcd "********************"
         Submenupunkt = Submenupunkt + 2
         Submenuhoch = Submenupunkt
    Else
         Submenuhoch = Submenupunkt
         Langstring = Lookupstr(submenupunkt , Menue)
         Locate 2 , 1
         Lcd Langstring
         Submenupunkt = Submenupunkt + 2
    End If
    
    Menuezuruck:
    Beendet = 0                                                 'text und menuepunkt für taste zurueck (links) wird gesucht und ausgegeben
    Zahler = 0
    Do
    Decr Submenupunkt
    Langstring = Lookupstr(submenupunkt , Menue)
    Kurzstring = Left(langstring , 1)
    If Kurzstring = "#" Then Beendet = 1
    Loop Until Beendet = 1
    If Submenupunkt = 0 Then
    Zeile1 = 1
    Else
    Zeile1 = 0
    End If
    Submenupunkt = Submenupunkt + 1
    Langstring = Lookupstr(submenupunkt , Menue)
    Kurzstring = Left(langstring , 2)
    Kurzstring = "#" + Kurzstring
    Beendet = 0
    Zahler = 0
    Do
    Langstring = Lookupstr(zahler , Menue)
    If Langstring = Kurzstring Then
    Beendet = 1
    Else
    Incr Zahler
    End If
    Loop Until Beendet = 1
    Kurzstring = Lookupstr(submenupunkt , Menue)
    Kurzstring = Right(kurzstring , 1)
    Submenupunkt = Val(kurzstring)
    Submenupunkt = Submenupunkt * 2
    Submenuzurueck = Zahler + Submenupunkt
    If Submenuzurueck = 2 Then
        If Zeile1 = 1 Then
        Locate 1 , 5
        Lcd "Hauptmenue"
        Zeile1 = 0
        Else
        Langstring = Lookupstr(submenuzurueck , Menue)
        Locate 1 , 5
        Lcd Langstring
        End If
    Else
        Langstring = Lookupstr(submenuzurueck , Menue)
        Locate 1 , 5
        Lcd Langstring
    End If
    
    
    End Sub
    
    ' hinter der #  steht die menueebene dahinter steht die rücksprungadresse für diese menueebene
    ' zB wird aus einem eintrag der ebene #04 (zB Abstand) in die ebene #3 eintrag 1 gesprungen (031) in diesem fall nach eingänge
    ' und von dort gehts zurück in ebene 1 eintrag 2 (012) das wäre dann "Tests"
    'nach der rücksprungadresse folgt der erste menuepunt (max 20 Zeichen)und danach dessen vorprung adresse
    'zB hinter "Einstellungen" steht 07 also verzweigt das menue von dort in die unter-ebene 7
    'falls aus einem Menuepunkt nicht weiter in ein Untermenue gesprungen werden soll sondern ein bestimmdes Ereigniss stattfinden soll
    'dann kommt als vor-sprung-adresse (die zahl hinter dem eintrag) ein ! und eine Zahl von 1-99 diese Zahl wird dann in der variable menuecase zurueckgegeben
    'zB wenn man im Menuepunkt "Akku Laden" die menue-vor taste drückt wird der wert 02 zurueckgegeben diese können dann ausgewertet werden
    
    Menue:
    Data "#01" , "011" , "Sauna" , "02" , "Pool" , "05" , "Garage" , "09"
    Data "#02" , "011" , "Licht innen" , "03" , "Licht aussen" , "04" , "Fertig-Signal" , "!05"
    Data "#03" , "021" , "an" , "!01" , "aus" , "!02"
    Data "#04" , "022" , "an" , "!06" , "aus" , "!07"
    Data "#05" , "012" , "Pool-Licht" , "06" , "Solarheizung" , "07" , "Reinigungsmodus" , "08"
    Data "#06" , "051" , "an" , "!08" , "aus" , "!09"
    Data "#07" , "052" , "freigeben" , "!10" , "sperren" , "!11"
    Data "#08" , "053" , "Pool reinigen" , "!12" , "Normalbetrieb" , "!12"
    Data "#09" , "013" , "Licht" , "10"
    Data "#10" , "091" , "an" , "!14" , "aus" , "!15"
    Data "#EO"                                                  'muß am ende stehen
    Danke fürs anschauen.
    Andreas

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    35
    Beiträge
    1.989
    Also ohne jetzt genau dein Programm zu kennen, verwende ich bei den Menüs folgende Technik:

    Benötigt werden 3 Variablen:
    Mlv (String, z.B. Länge 20)
    PressedKey (String mit Länge 1)
    MString (String mit Länge Mlv + Pressedkey, z.B. 21)

    Im String Mlv (Menulevel) wird der aktuelle Menüpunkt gespeichert (z.B. "Main" für das Hauptdisplay, "Settings1" für Einstellungen 1. Ebene, "SetTimeDate" für Datum/Zeit-Einstellungen etc);

    In PressedKey wird die gedrückte Taste gespeichert; also "U" für hoch, "D" für Runter, "M" Menü, "X" Escape/Exit... sowie "N" für keine
    Taste.

    Die beiden werden dann zu einem String MString vereinigt, dass der normalzustand z.B. "MainN" ist (also einfaches MString = Mlv + PressedKey). Wird eine Taste gedrückt (z.B. Menü "M"), ändert sich der String nach "MainM", wobei entsprechend dann reagiert wird.

    In nem grossen Select-Case-Block werden dann alle möglichen Kombinationen abgefragt..

    z.B.
    Case "MainN": Anzeigen des Haupt-Display
    Case "MainX": würde System abschalten
    Case "MainM": ruft Menü auf
    Case "Settings1X": springt von den Einstellungen zurück (z.B. nach Main)
    Case "VolumeU": dreht Lautstärke hoch
    ...


    Die Daten sind bei mir dann so angeordnet, dass bei "....N" (also keine Taste gedrückt) nur LCD-Ausgaben erfolgen und bei allen anderen Tasten
    entsprechend reagiert wird.
    Vorteil hier: man sieht gleich ohne Kommentare, was der jeweilige Case macht; Nachteil: Speicher wird mit den 3 Variablen belegt; aber sollte eh genug da sein.

    Nach dem Case-Select-Block bzw. bei der Tastenauswertung muss die gedrückte Taste natürlich wieder auf "N" gesetzt werden.

    Etwas kompliziert, aber so klappts bei mir mit den Menüs problemlos.


    Hier ein Beispiel-Ausschnitt aus nem Programm von mir:
    (Die Gedrückte Taste wurde hier mit mehr als nur 1 Zeichen angegeben; ein ! soll das als Befehl kennzeichnen)

    Code:
    'Ausschnitt aus dem Bereich der Tastenabfrage
    '(Tasten bei mir per Widerstandsmatrix an einem ADC angeschlossen)
    
       Adcval0 = Getadc(0)
       If Adcval0 < 15 Then                           'Keine Taste gedrückt
          Key = "!NON"
          End If
    
       If Adcval0 > 14 Then Waitms 25
       Key = Getkey()  'GetKey() besorgt sich aus der anliegenden Spannung die gedrückte Taste
    
             'Umschreiben der Tasten:
             If key = "E" then Key = "!ENT"
             If key = "X" then Key = "!ESC"
             If key = "C" then Key = "!F12"
             If key = "U" then Key = "!UP"
             If key = "D" then Key = "!DWN"
             If key = "L" then Key = "!LFT"
             If key = "R" then Key = "!RIG"
    
    
    'Ausschnitt aus Bereich: Datum einstellen: Jahr gewählt
    
    
          Case "SetDateY!NON"    'Zeit prüfen, Timer stoppen und Zeit anzeigen
             Checktime
             Stop Timer1
             Lcd1 = "<Set Date>"
             Lcd3 = "  " + Strdate
             Lcd4 = "     " + Chr(1)
    
          Case "SetDateY!RIG" : Mlv = "SetDateM"     'Zum Monat wechseln
          Case "SetDateY!UP" : Incr Tyear     'Jahr erhöhen
          Case "SetDateY!DWN" : Decr Tyear     'Jahr erniedrigen
          Case "SetDateY!ENT"     'Jahr übernehmen und vorher gestoppten Timer neu starten
             Mlv = "TimeDate2"
             Start Timer1
          Case "SetDateY!ESC" : Mlv = "TimeDate2"    'Zurück zu den Zeiteinstellungen

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    20.10.2004
    Ort
    Thüringen
    Beiträge
    133
    Hallo Jaecko,

    danke für Deine Antwort. Geht ganz anders an das Problem rein wie meine Variante (die nicht von mir ist, ich habe den Codeschnipsel gefunden und kenne den Autor nicht mehr. Nur das er "Daniel" heist).

    Habe aber jetzt mit Hilfe des Simulators und meheren Versuchen in der realen Schaltung die Funktion rausgefunden.
    Ich weis also jetzt wie es geht, und komme weiter mit meinem Proggi..

    Danke, vielleicht kann ja jemand mit den Menü-Ideen auch was anfangen...

    Andreas

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.02.2005
    Ort
    Südtirol
    Beiträge
    283
    Hi Andreas,

    klingt interessant, könntest du vielleicht etwas mehr von deinem Hausbus erzählen? Ich hab mir auch mal ein paar Überlegungen dazu gemacht, hab sie aber wieder verworfen, da nie was gescheites rausgekommen is

    Mfg
    Kalle

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •