Forum: Mikrocontroller und Digitale Elektronik Ansätze für LCD Menüsteuerung


von Thomas S. (thomass)


Angehängte Dateien:

Lesenswert?

@all,

ich habe nun schon einige Beiträge hier im Forum durchgeschaut zum Thema 
Menüsteuerung.
Habe zwar einiges gefunden jedoch auch viele wiedersprüchliges.
Nun habe ich mich entschlossen einen neuen Beitrag zu starten.

Zum einen habe ich vieles mit einer Strukurierten Programmierung 
(Struktur) gefunden.
Ein weiterer Beitrag schlägt eine state machine mit switch-case operator 
vor.

Ich habe zwar noch keine Strukturen programmiert jedoch die Idee gefällt 
mir recht gut.
Leiter sieht es mit source codes oder Codeschnipsel recht mager aus.
Eventuell kann ja jemand der sowas schon gemacht hat mal was posten.

In einem Beitrag der über Strukturen ging wurde der Butterfly von Atmel 
genannt und man solle sich mal diesen Code anschauen.
Ich habe mir diesen mal heruntergeladen und ich denke da ist schon was 
dabei um Denkanstöße zu liefern.

Bevor ich mich jetzt für eine Variante entscheiden möchte ich mich mal 
nach Euren Meinungen/Erfahrungen erkundigen.

Ich hänge mal die Headerfiles vom Butterfly an.
Was meint Ihr zur Menu.h könnte man so programmieren?

Gruß Und schon mal DANKE für die Antworten.

Thomas

von Andreas K. (a-k)


Lesenswert?

Das wichtigste an Menusteuerung ist immer noch die Orientierung dieser 
Steuerung am Benutzer. Da kann es dann sein, dass die Bedienung mittels 
total flacher Eingabe numerierter Parameter besser ankommt als ein noch 
so schön programmierter Menuebaum, weil Nummern per Zettel daneben kein 
Problem sind, aber der Menubaum sofort ein undurchdringliches Labyrinth 
wird.

Wenn der Benutzer zu jeder Sorte Menschen gehört, die beim Telefonieren 
per Handy für alles was über das Eintippen der Ziffern hinausgeht ein 
Flussdiagramm brauchen, ist jedes Menu schon im Ansatz verkehrt. Und 
solche Menschen gibt es sehr viele.

von Michael H. (mah)


Lesenswert?

ich hab mir mal die state machine aus dem AVR Butterfly ausgelötet und 
verwende das - das ist ganz brauchbar; vor allem ist es daten-gesteuert.

Labyrinthe sind möglich, aber optional :)

-Michael

von Thomas S. (thomass)


Lesenswert?

@Andreas,

vermutlich min ich der einzige Benutzer.Daher muss nur ich mich 
auskennen.

Es sollten eigentlich nur Parameter geändert bzw. hinzugefügt werden.
Das ganze 5 Tasten RECHTS-LINKS-HOCH-RUNTER-OK.

Zum Menü noch ein paar Worte.

Im Hauptmenu 5-8 Menüpunkte und in den Untermenüs jenachdem 3-8 
Menüpunkte.
Das ganze bis max. 3 Untermenüs.

Ich möchte nur etwas anfangen was ich später auch leicht ergänzen kann 
ohne das ganze wieder komplett umschreiben zu müssen.Es sollte einfach 
erweiterbar sein daher die Strukturvariante.

Da ich das eine noch das andere schon gemacht habe kann ich mich nicht 
entscheiden.

von Thomas S. (thomass)


Lesenswert?

@all,

ich habe mich nun für die Strukturvariante entschlossen.
Hatte mich heute zum ersten Mal mit Strukturen beschäftigt und die 
Headerfiles von oben zur Grundlage genommen.
Ist zwar etwas gewöhnungsbedürftig aber eigentlich leichter als ich 
gedacht habe.
Habe nun ein Menu erstellt mir Untermenüs etc. und es funktioniert.
Einfach klasse!!!! :-)

Danke an alle für die Hilfestellungen.

Thomas

von Thomas S. (thomass)


Lesenswert?

Hallo,

ich habe nun meine Steuerung soweit gebracht das ich auch Funktion 
ausführen kann.
Nun wollte per menu ein uchar Array[20][40] auslesen und dabei immer 4 
Werte gleichzeitig anzeigen und ändern.
z.B.

zuerst Array[0][x] - Array[3][x]
danach Array[4][x] - Array[7][x]
danach Array[8][x] - Array[11][x]
usw.

Danach die zweite Zeile (x).
Im array gibt es max 40 Datensätze es können auch weniger sein und das 
ist mein Problem.
Wie kann ich Menu es machen das wenn nur 6 Datensätz enthalten sind nach 
dem anzeigen des 6 Datensatzes das menu nicht auf 7 springt sondern 
wieder auf 1 also Datensatz 1-->2-->3-->4-->5-->6-->1 usw.
Also flexibel.

Thomas

von Karl H. (kbuchegg)


Lesenswert?

Deine Beschreibung ist nicht sehr klar.
Aber ich versuche mal einen Schuss ins Blaue.


Du brauchst eine Variable, die dir die tatsächliche Anzahl
angibt. In deinem konkreten Fall also die 6

Du wirst dann wahrscheinlich eine Funktion haben, die dir
immer 4 Einträge aus deinem Array anzeigt und zumindest einen
Button für 'Weiter' (der dann die nächsten 4 Einträge anzeigt)

Kern dieser Funktion ist die Schleife, die immer 4 Einträge
anzeigt:
1
void foo( ... )
2
{
3
  ....
4
5
  FirstEntry = 0;    // welches ist der erste anzuzeigende Eintrag
6
7
  ....
8
9
  do {
10
11
    for( i = FirstEntry; i < FirstEntry + 4; ++i ) {
12
      // gib den Eintrag i aus
13
14
      if( i + 1 == NrTotalEntries )    // das wars, mehr gibts nicht
15
        break;
16
    }
17
18
    if( Button_Next_Pressed && FirstEntry + 4 < NrTotalEntries )
19
      FirstEntry += 4;
20
21
  } while( !MenuFinished )

da ich die Details deines Menüsystems nicht kenne, ist obiges
als Pseudocode zu sehen, der dir eine Idee gibt, wie du die
Anzahl der Menüeinträge insgesamt einbauen kannst/sollst/musst.

Kann auch sein, dass ich da jetzt irgendwo um +- 1 bei den
Arrayindizes daneben bin, ich wollte nur die Idee skizzieren,
die Details überlasse ich dir :-)

von Thomas S. (thomass)


Lesenswert?

@ Karl Heinz,

vielen Dank für Deine Unterstützung hat wunderbar geklappt mit dem 
flexieblen auslesen von Daten.

Wenn ich nun die angezeigten Werte ändern will wie machen ich das am 
besten.

1. Auf den Display ändern und dann die Daten von Display auslesen und im 
Array speichern --> Habe irgentwo gelesen das dies funktioniert jedoch 
noch nie getestet.
2. Virtuell im Display ändern jedoch direkt den Arraywert ändern und das 
Display mit dem neuen Wert reloaden.
3. .....?

Was ist am besten geeignet?

Ich habe bis jetzt mir 4 Tasten gearbeitet  Hoch Runter Rechts Links um 
durch die Menüs zu zippen..
Wie es mir jedoch scheind brauche ich nun noch weitere 4 Tasten
Rechts Links um den Curser zu bewegen (arbeite nur auf einer Zeile mit 
den Werten)
Hoch Runter um die Werte zu ändern.

Sehe ich das Richtig ?

Ich denke wenn ich es nicht mache gibt es einen richtigen durcheinander.

Gruß und DANKE schon mal.

Thomas

von Karl H. (kbuchegg)


Lesenswert?

Thomas S. wrote:

> Wenn ich nun die angezeigten Werte ändern will wie machen ich das am
> besten.
>
> 1. Auf den Display ändern und dann die Daten von Display auslesen und im
> Array speichern --> Habe irgentwo gelesen das dies funktioniert jedoch
> noch nie getestet.

Würde ich so nicht machen.

> 2. Virtuell im Display ändern jedoch direkt den Arraywert ändern und das
> Display mit dem neuen Wert reloaden.

Das ist der Weg den ich gehen würde

> Ich habe bis jetzt mir 4 Tasten gearbeitet  Hoch Runter Rechts Links um
> durch die Menüs zu zippen..
> Wie es mir jedoch scheind brauche ich nun noch weitere 4 Tasten
> Rechts Links um den Curser zu bewegen (arbeite nur auf einer Zeile mit
> den Werten)
> Hoch Runter um die Werte zu ändern.
>
> Sehe ich das Richtig ?

Du brauchst auf jeden Fall noch eine 'Auslösetaste'.
Mit den Pfeiltasten navigierst du einen Eintrag an und mit
der Auslösetaste wird der, dem Meüpunkt zugeordnete, Eintrag
aktiviert.

Ob ich da jetzt rauf/runter/rechts/links machen würde. Bin
mir nicht sicher, aber ich denke nicht.
Ich würde versuchen mit 3 Tasten auszukommen:
Rauf, Runter, Return

die Rauf / Runter Tasten navigieren durch das Menü

     Menüpunkt 1            Menüpunkt 3
     Menüpunkt 2            Menüpunkt 4

Angenommen der Cursor steht auf 1. Einmal 'Runter' drücken
bringt mich zur 2. Nochmal Runter -> 3, Nochmal -> 4.
Beim nächsten Druck auf Runter erfolgt ein Umscrollen des
Displays

     Menüpunkt 3            Menüpunkt 5
     Menüpunkt 4            Menüpunkt 6

und die Auswahlmarkierung steht bei der 5. Druck auf 'Runter'
-> es geht zur 6. Nochmal Runter -> Umscrollen und Cursor steht
auf 7, etc.

Sinngemäß alles umgekehrt bei einem Druck auf 'Rauf'.


Bei meinem letzten Menü auf einem 2-zeiligen LCD hab
ich überhaupt die Dinge anders gemacht.
Die 1. Zeile ist eine Art Überschrift, quasi der Menüpunkt
die 2. Zeile ist exklusiv für ev. Eingaben in diesem Menüpunkt
reserviert.
Dazu 3 Taste: Links, Rechts und Auslöser

Das Menü sieht zb so aus

      > Name
        Kalle

(Der Haken zeigt an, an welcher Stelle der nächste Tastendruck
wirkt)

Name ist der Menüpunkt, Kalle ist der zugehörige Wert

Drücke ich jetzt 'Rechts' so wird der nächste Menüpunkt
sichtbar

     > Akku
       LiPo

Ein Druck auf Auslöser, lässt den Haken in die 2. te Zeile
wechseln

       Akku
     > LiPo

wo ich dann, wieder mit den Links/Rechts Tasten einen anderen
Wert auswählen kann

       Akku
     > NiCd

Wieder Auslöser drücken, aktiviert diesen Punkt und der Cursor-Haken
geht wieder nach oben

     > Akku
       NiCd

wo mich dann ein Druck auf Links wieder in die Ausgangssituation
zurückbringt

     > Name
       Kalle

Ich denke, dass man Menüfuhrungen mit dem begrenzten Platz und
Tastenangebot, das man auf einem µC mit LCD hat, sowieso meistens
an das jeweils zu bauende Gerät anpassen muss/soll. Die Universal-
techniken, wie man sie auf einem PC benutzt, greifen hier nicht
so recht.

von Thomas S. (thomass)


Lesenswert?

@Karl Heinz,

Danke mal wieder für Deine Antwort finde ich echt Klasse.

Ich habe eine 5 Tasten Version mal versucht.

                 Hoch
     Zurück      Enter     Weiter
                 Runter

Soweit funktioniert es schon zumindest die ersten Versucht.

Bis jetzt habe ich immer nichts zu den nicht benutzten Tasten 
geschrieben, das war vermutlich ein Fehler.
Wenn ich mal versehentlich eine Falsche drücke springt das Menü irgentwo 
hin.
Naja aus Fehlern lernt man ja.

Werde mir heute mal eine längere Nacht gönnen.

Gruß

Thomas

von Thomas S. (thomass)


Lesenswert?

@Karl Heinz,

bin etwas Ratlos was ich mit den nicht benötigten tasten machen soll?

Teilweise navegiere ich mit alle Tasten und in bestimmten Untermenus 
benötige ich eben nur 1,2 oder 3 Tasten da dort die Auswahl begrenzt 
ist.
Drücke ich aber an dieser Stelle ein falsche nicht definierte Taste 
springt das Prog immer in den letzten ausgeführten Menupunkt.
Kann man einen pseudo Menupunkt erstellen der einfach nichts tut aber 
wie geht hier die Lösung?

OK die einfachste währ immer die richtige Taste drücken jedoch das ist 
etwas schwierig.
Jedoch bei der menu.h oben gepostet gibt es auch Menupunkte die nur mit 
einer Taste belegt sind und das ist ja von Atmel.

Gibt es dort nicht dieses Phänomen?!?
Eventuell liegt es auch an meiner Programmierung

Ich habe nun die *.c Dateien von Butterfly nochmals angeschaut.
Dort wird immer die Tastercode übertragen und in der Funktion zu Schluss 
nochmals geprüft, wenn dieser nicht übereinstimmt wird eine Ebene nach 
OBEN gesprungen.
Nun habe ich auch folgenden code gesehen und dieser ist mit nicht ganz 
klar bzw ich habe nur eine Vermutung was passiert.
1
    else if (input == KEY_ENTER)    
2
    {
3
        enter = 1;
4
        return ST_TIME_CLOCK_FUNC;
5
    }        
6
    return ST_TIME_CLOCKFORMAT_ADJUST_FUNC;
Der Auszug ist aus einer Funktion.
Wenn jetzt KEY_ENTER erfüllt ist wird der return ST_TIME_CLOCK_FUNC 
zurückgegeben.
Was passiert dann mit dem
1
return ST_TIME_CLOCKFORMAT_ADJUST_FUNC;

Wird dieser übersprungen und nicht ausgeführt?!?!? :-)

In dieser Art sind alle Funktionen aufgebaut, alle nicht benutzten 
Tasten sind so abgefragt bzw. so ähnlich.

Gruß

Thomas

von Falk B. (falk)


Lesenswert?

@ Thomas S. (thomass)

>Drücke ich aber an dieser Stelle ein falsche nicht definierte Taste
>springt das Prog immer in den letzten ausgeführten Menupunkt.

Es darf keine undefinierten Tasten geben. Die unbenutzten müssen halt ne 
Dummyfunktion auslösen, die keinerlei Wirkung hat.

MFG
Falk

von Michael H* (Gast)


Lesenswert?

hallo thomas,
hättes du vllt eine aktuelle version von deinem menü?
danke schon mal, grüße,
holli

von Thomas S. (thomass)


Lesenswert?

@Michael,

also schon wieder Menusteuerung.
Ich habe eigentlich nichts anderes gemacht als mit die AVR Butterfly 
Programmierung angeschaut und verstanden wie es dort gemacht wird.
Diese kannst Du herunterladen unter

http://www.atmel.com/dyn/resources/prod_documents/AVRButterfly_application_rev07.zip
http://www.atmel.com/dyn/Products/tools_card.asp?tool_id=3146
           -->     AVR Butterfly - Application Rev07  (64 KB, updated 
01/07)

Hier sind im Prinzip drei Dateien zum ersten die menu.h und dieser ist 
die Struktur der Menusteuerung definiert.
Also wenn Du im Menu1 bist und next drückst dann ins Menu 1.1 wechselst 
bei einer gedrückten PLUS Taste wechselst Du ins Menu 2 usw. Das musst 
Du Dir mal anschauen ist eigentlich recht simpel und gut verständlich.

Die 2 Datei ist die Main.c in dieser musst Du dir eigentlich nur 
anschauen wie das Menu.h ausgerufen wird ich glaube es läuft alles über 
Funktionspointer.
Es ist alles mit einer Art Tasterurmatrix programmiert.

Die 3 Datei ist die eigentlich sind diese verstreut auf mehrere Dateien. 
Es ist im Prinzip die Funktion die ausgeführt werden soll bei einem 
bestimmten Menupunkt.
Hier mal ein Auszug aus der Menu.h:
1
MENU_STATE menu_state[] = {
2
//  STATE                               STATE TEXT                  STATE_FUNC
3
    {ST_AVRBF,                          MT_AVRBF,                   NULL},
4
    {ST_AVRBF_REV,                      NULL,                       Revision},
5
    {ST_TIME,                           MT_TIME,                    NULL},
6
    {ST_TIME_CLOCK,                     MT_TIME_CLOCK,              NULL},
7
    {ST_TIME_CLOCK_FUNC,                NULL,                       ShowClock},
8
    {ST_TIME_CLOCK_ADJUST,              MT_TIME_CLOCK_ADJUST,       NULL},
9
    {ST_TIME_CLOCK_ADJUST_FUNC,         NULL,                       SetClock},
10
    {ST_TIME_CLOCKFORMAT_ADJUST,        MT_TIME_CLOCKFORMAT_ADJUST, NULL},
11
    {ST_TIME_CLOCKFORMAT_ADJUST_FUNC,   NULL,                       SetClockFormat},

Es sind 3 Spalten die erste ist der Menupunkt z.B 1.0,1.1,1.1.1,1.1.2 
usw die 2 Spalte ist der definierte Text der auf dem Display angezeigt 
werden soll ist weiter oben definiert.
Die 3 Spalte sind die Funktionen die beim jeweiligem Menupunkt 
ausgeführt wird.
Ich habe diese alle in ein Funk_Display.c gepackt.

Achja eines noch, war mir am Anfang nicht ganz klar weshalb bei jeder 
Funktion die tasterturauswertung übergeben wird dies ist jedoch wichtig 
das es immer definiert ist was innerhalb der Funktion bearbeitet werden 
soll.Also unterschiedliche Dinge je Taste.
Dies ist wichtig da Du von verschiedenen Menupunkten in ein Menu kommen 
kannst.Eventuell soll ja ein Wert mit plus minus verändert werden d.h Du 
bist immer im gleichen Menu jedoch mit einem Plus addierst Du und mit 
Minus Subtrahierst Du.

Ich hoffe es ist verständlich. :-)

Wenn nicht melde Dich nochmal.
Mein Menuaufbau ist nur etwas komplizierter da ich ein 4x40 Display habe 
daher immer 2 Texte da 2 Controller.

Thomas

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.