Hallo,
ich suche ein Menüsystem, bei dem man wärend des Programmablaufs
Menüeinträge hinzufügen kann. Das hat den Hintergrund, dass einige
Menüeinträge aus einem externen EEPROM geholt werden sollen. Kennt ihr
da Menüsysteme, die so etwas leisten? Bei allen, die ich gefunden habe
sind die Menüeinträge in Anzahl und/oder Inhalt durch das Programm von
vornherein festgelegt.
Ich hoffe, ihr habt mein Anliegen verstanden und wisst Rat ;)
mfG, Sven
Hallo Sven,
generell würde ich erstmal sagen, ein Menüsystem aus einem externen
EEprom könnte sich genaus verhalten, wie eins, dass aus dem Progmem
gelesen wird.
Wenn Du die Struktur kennst, in dem Deine Menüstruktur im EEProm
abgelegt ist, kannst Du es auslesen.
Der jeweils aktuelle Menüpunkt wird dabei in den RAM gelesen. Eine
Gesamtabbildung im RAM dürfte in den meisten Fällen zu Speicherproblemen
führen.
Gruß
Frank
Hallo Frank,
ich habe bis jetzt tinymenu
(http://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_id=249&item_type=project)
verwendet. Das System funktioniert auch sehr gut, hat aber eben zwei
entscheidene Nachteile:
1. Die Daten werden im SRAM abgelegt, nicht im PRGMEM. Das ist nicht
allzu tragisch, weil ich viel Speicher habe (4k) und mein Menü nicht
allzu groß wird.
2. Die Daten sind statisch in structs abgelegt. Ich weiß nicht, wie ich
das modifizieren soll, weil ich bei Pointern, Structs und Arrays in
Kombination einfach noch nicht so geübt bin.
Hier sind die Typedefinitions:
1
// So sieht ein (Sub-)Menu aus:
2
typedefstructmenu_s{
3
uint8_ttop_entry;// top displayed entry
4
uint8_tcurrent_entry;// currently highlighted entry
5
uint8_tnum_entries;// total # of entries in menu
6
structmenu_s*previous;// previous menu (for backtracking)
7
menu_entry_tentry[];
8
}menu_t;
9
10
// Und so ein Eintrag (entry)
11
typedefstructmenu_entry_s{
12
uint8_tflags;// see flag definitions above
13
void(*select)(void*arg,char*name);// routine to call when selected
14
charname[MENU_ENTRY_NAMELEN];// name to display for this entry
15
void*value;// value to pass to select function
16
}menu_entry_t;
Kann man das Ganze überhaupt nach meinen Bedürfnissen umstricken, oder
muss man sich über ein neues Konzept Gedanken machen?
Ich freue mich auf konstruktive Vorschläge. Gruß, Sven
Hallo Sven,
dazu müsste ich ein wenig mehr wissen.
1. Liegen in Deinem EEProm nur die reinen Menüinformationen also Texte
Vorgänger, Nachfolger usw.? Wie erfolgt die Abildung im EEprom?
2. Wo liegen die Nutzerroutinen, die aus dem Menüsystem heraus
angesprungen werden? Wie soll die Zuordnung von Menüeintrag zu
Nutzerroutine erfolgen?
3. Warum liegen die Menüdaten überhaupt in einem externen EEProm?
4. Ist mit externen EEProm tatsächlich ein Baustein gemeint der nicht im
Mikrocontroller steckt?
Grundsätzlich kannst Du jede Struktur im Speicher anlegen bzw.
erweitern. An Stelle eines Arrays kannst Du z.B. verkettete Listen
nehmen und diese über Dein EEProm initialisieren.
Ich arbeite zur Zeit an einem Konzept um Menü- und Dialogstrukturen auf
einem LCD abbilden zu können. Allerdings basiert das auf einer
Array-Struktur, indem das Menüsystem komplett über PROGMEM abgebildet
wird. Für Dich also in dieser Form nicht geeignet.
Gruß
Frank
Hi Frank,
ich merke schon, ich muss ein wenig weiter ausholen: Das Ganze wird eine
Art Universalfernbedienung, bei der die Befehle editierbar bleiben
sollen. Deshalb liegen sowohl Daten- (2), Kontroll- (1) als auch
Textbytes (15) im externen EEPROM (24LC64). Nun habe ich mir
vorgestellt, dass sobald ich im Menü auf den Punkt "Send Command" gehe,
die entsprechenden Befehle aus dem EEPROM geladen werden und die Texte
auf dem Display dargestellt werden. Ein Teil des Menüs kann also
weiterhin fest im ROM liegen, aber ein Teil soll eben immer dynamisch
aus dem EEPROM geladen werden.
Im Kontrollbyte eines jeden 18-Byte langen Befehl steht drin, für
welches Gerät er gedacht wird, wodurch dann eine entsprechende Funktion
mit den Datenbytes als Parameter aufgerufen wird. Die Einträge müssen im
Menu nicht besonders geordnet werden. Ich hoffe mein Anliegen ist etwas
klarer geworden...
mfG, Sven
Hallo Sven,
das heisst, Du willst für verschiedene Fernbedienungen die Codes im
EEPROM speichern und bei Bedarf entsprechend aus dem EEPROM laden und
verwenden. Ist das richtig?
Da die Fernebdienung aber immer nur einen Code ausführen kann, ist es
doch aus meiner Sicht gar nicht notwendig mehr als ein Kommando im
Speicher zu halten. Oder sehe ich das falsch?
Ich arbeite bei meinem LCD-Menü auschließlich mit PROGMEM. Wird ein Menü
angezeigt, lade ich die notwendigen Informationen aus dem PROGMEm in den
RAM. Dabei hole ich mir immer nur die aktuell notwendigen Information
und kopiere sie in einen Zwischenbereich der die Darstellung auf dem
Display übernimmt.
Du stellst vorher einmal ein, wie das Display aufgeteilt ist Anzahl
Menüspalten und Anzahl Menüzeilen im Display. Dem entsprechend
initialisiere ich durch den Compiler und Defines meine Struktur.
Alles andere passiert ausschliesslich durch direktes lesen aus PROGMEM.
Die gleiche Vorgehensweise kannst Du auch für Dein EEPROM verwenden.
Wenn ich es richtig verstanden habe, wählst Du aus welche Fernbedienung
Du benutzen möchtest (TV, TUNER, ... ), dann betätigst Du eine Taste.
Der Controller schaut an Hand der eingestellten Fernbedineung und dem
Tastendruck in der im EEPROM gespeicherten Tabelle nach welches Kommando
und welcher Text dazu gehört. Kopiert diese in das RAM und führt das
ganze aus (also Text auf Display und SendCMD).
Damit benötigst Du lediglich eine Lookuptabelle für die verschiedenen
Fernbdienungen und eine Tabelle mit den ganzen Befehlen pro
Fernbedienung
Korrigiere mich wenn ich falsch liege. In der Lookuptabelle für die
Fernbedienungen legst Du jeweils den Anfang und das Ende des Bereichs
innerhalb der Befehlstabelle fest der für die gewählte Fernbedienung
gültig ist. Wenn jetzt eine Taste gedrückt wird, kann sich der
Controller aus der Fernbedienungstabelle das Offset für den Beginn der
Befehlstabelle für diese eine Fernbedienung holen, hat er dieses Offset
kann er in der Befehlstabelle das entsprechende Kommando für die
gedrückte Taste holen. Kopier diesen Ausschnitt aus dem EEPROM in das
RAM und Du hast alle Daten die Du benötigst um das eine Kommando
auszuführen.
Gruß
Frank
Hi Frank,
ich glaube nun sind wir uns in den Grundzügen einig, nur dass wenn man
auf Tuner oder TV klickt, ein Submenü geöffnet wird, das aus den Texten
der einzelnen "Tasten" besteht. Also muss beim Klick auf TV bzw. Tuner
das Laden der Texte aus dem EEPROM beginnen.
1
Ich arbeite bei meinem LCD-Menü auschließlich mit PROGMEM. Wird ein Menü
2
angezeigt, lade ich die notwendigen Informationen aus dem PROGMEm in den
3
RAM. Dabei hole ich mir immer nur die aktuell notwendigen Information
4
und kopiere sie in einen Zwischenbereich der die Darstellung auf dem
5
Display übernimmt.
6
7
Du stellst vorher einmal ein, wie das Display aufgeteilt ist Anzahl
8
Menüspalten und Anzahl Menüzeilen im Display. Dem entsprechend
9
initialisiere ich durch den Compiler und Defines meine Struktur.
10
11
Alles andere passiert ausschliesslich durch direktes lesen aus PROGMEM.
12
13
Die gleiche Vorgehensweise kannst Du auch für Dein EEPROM verwenden.
Würdest du mir für diese Prozesse den Code zur Verfügung stellen, sodass
ich ihn für den EEPROM-Gebrauch umbauen kann?