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 | typedef struct menu_s { |
3 | uint8_t top_entry; // top displayed entry |
4 | uint8_t current_entry; // currently highlighted entry |
5 | uint8_t num_entries; // total # of entries in menu |
6 | struct menu_s *previous; // previous menu (for backtracking) |
7 | menu_entry_t entry[]; |
8 | } menu_t; |
9 | |
10 | // Und so ein Eintrag (entry)
|
11 | typedef struct menu_entry_s { |
12 | uint8_t flags; // see flag definitions above |
13 | void (*select)(void *arg, char *name); // routine to call when selected |
14 | char name[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?
Hallo Sven, klar, schicke ich Dir nachher per Mail. Gruß Frank
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.