Projekt: LCDMenuLib (LCDML) - Kapitel 2: Displayfunktionen2.1 Inbetriebnahme des ersten Beispiels Das Beispiel mit der Bezeichnung „LCDML_1_easy_01_first_test" soll zeigen wie ein einfaches Menü aussehen kann.
Vorweg kurz etwas zum Quellcode:
Alle Makros / Funktion die mit LCDML_DISP_... beginnen beziehen sich auf das Menü so wie die Funktionen die darin aufgerufen werden (Displaysystem). Alle weiteren Makros / Funktionen die mit LCDML_BACK_... anfangen beziehen sich auf Abläufe die im Hintergrundlaufen (Backendsystem)
Im Beispiel werden zuerst die benötigten Libraries eingebunden. Die Libs die benötigten werden hängen von der verwendeten Schnittstelle ab. Z.B. wird bei I2C noch die Wire.h benötigt, dazu später aber mehr.
// include libs
#include <LiquidCrystal.h>
#include <LCDMenuLib.h>
Nach den Libraries werden die Konstanten für das Menü angelegt. Beim oben genannten Beispiel sollte hier alles so belassen werden wie es ist. Später kann hier der Initscreen (Standby Screen) aktiviert werden oder die Buttonpresstime (für Buttons) eingestellt werden. Mit der Button Press Time werden die Buttons entprellt.
Nach der Lib Konfiguration werden die Einstellungen vom Display gesetzt. Es müssen die Reihen (row) und Spalten (cols) angegeben werden und die PINs an denen das Display angeschlossen ist. Falls ein Display verwendet wird, beidem die im Beispiel vorhandenen Konstanten nicht passen bitte in Kapitel 2.4 „Schnittstellen mit externen Libs" weiterlesen.
Das Beispiel „LCDML_1_easy_01_first_test" lässt sich der Einfachheit nur über die serielle Schnittstelle bedienen.
Folgende Tasten haben eine Bedeutung im Menü:
e = Enter (In eine Ebene wechseln)
q = Quit (Geht aus einer Ebene heraus)
u = Up (Navigation nach oben im Menü)
d = Down (Navigation nach unten im Menü)
Die folgenden Tasten können aber auch in Funktionen verwendet werden:
e = Enter (Benutzerdefiniert z.B. etwas setzen oder bestätigen)
q = Quit (verlässt die Funktion und kehrt ins Menü zurück)
u = Up (Benutzerdefiniert)
d = Down (Benutzerdefiniert)
l = Left (Benutzerdefiniert)
r = Right (Benutzerdefiniert)
Um das Menü mit Buttons oder Encodern steuern zu können ist das Kapitel 2.3 „Steuerungsmöglichkeiten" empfehlenswert.
Als nächstes wird im Beispiel das Menü angelegt. _LCDML_DISP_cnt bekommt die ID des letzten Menüelementes, sprich dieser Wert wird gesetzt wenn man weiß wie das Menü aussieht. Wird dieser Wert zu groß gewählt entstehen Fehlermeldungen. Wenn der Wert zu klein ist wird nicht das volle Menü angezeigt.
#define _LCDML_DISP_cnt 11 //ID des letzten Menü elementes
Danach wird mit der letzten Menü Element ID viele Variablen angelegt. Da dies nicht von Hand gemacht werden muss gibt es das Makro „LCDML_DISP_init(_LCDML_DISP_cnt);. Anschließend
wird die Menüstruktur aufgebaut. Für die ersten drei Elemente sieht das wie folgt aus:
// LCDMenuLib_element(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Information" , LCDML_FUNC_information);
LCDML_DISP_add (1 , _LCDML_G1 , LCDML_root , 2 , "Time info" , LCDML_FUNC_timer_info);
LCDML_DISP_add (2 , _LCDML_G1 , LCDML_root , 3 , "Settings" , LCDML_FUNC);
Der erste Wert im Makro ist die ID. Diese musst fortlaufend mit Null beginnend hochgezählt werden.
Als zweiter Wert folgt die Gruppe. Die Menüelemtne können in Gruppen eingeteilt werden. Die Gruppen können dann ausgeblendet werden z.B. um Funktion erst anzuzeigen nach dem eine Identifikation erfolgt ist oder für Funktionserweiterungen die erst später freigegeben werden sollen. In diesem Beispiel haben alle Element im Menü die Gleiche Gruppe.
Als drittes wird die Ebene in der sich das Element befinden soll angegeben. Mit LCDML_root ist die Hauptebene gemeint. Mit dem vierten Parameter wird die Reihenfolge in der zuvor angegeben Ebene festgelegt. Eine neue Untereben kann nur angelegt werden wenn zuvor das darüber liegende Element angelegt wurde. Z.B.
LCDML_DISP_add (3 , _LCDML_G1 , LCDML_root_3 , 1 , "Change value" , LCDML_FUNC);
Der Name der Ebene in der das „sub" Element angelegt wird setzt sich aus der Hauptebene und der Position des Elementes für das Ein Sub Element erzeugt werden soll zusammen.
Als fünften Parameter wird der Name der im Display für das Menüelement angezeigt wird angegeben. Hierbei muss beachtet werden, dass der Name zwei Zeichen kürzer sein muss als die Spalte im Display breit ist. Die Länge ist so definiert, dass vor dem Menüelement der Cursor gesetzt werden kann und hinter dem Namen der Scrollbalken Platz finden kann. Also bei einem 16x2 Display maximal 14 Zeichen und bei einem 20x4 maximal 18 Zeichen.
Der letzte Parameter gibt die Callback Funktion an. Dies ist die Funktion die ausgeführt wird, sobald das Menüelement Aufgerufen wird. Es macht keinen Sinn auf Menüs, die noch SubEbenen besitzen eine Funktion zu legen, diese würde nie ausgeführt werden. Für die Elemente, bei denen keine Funktion aufgerufen werden soll muss die Dummy-Funktion „LCDML_FUNC" eingetragen werden. Wenn ein Funktionsname im Menü eingetragen ist muss dazu auch eine Funktion existieren die aufgerufen werden kann, ansonsten entstehen Fehlermeldungen beim übersetzen
Nach dem Anlegen der Menüelemente wird mit dem Makro „LCDML_DISP_createMenu(_LCDML_DISP_cnt);" das Menü angelegt.
Als nächstes folgt die Definition des Backend. An dieser Stelle will ich hier noch nicht drauf eingehen. Dieser Teil sollte erstmal unbeachtet bleiben. Dazu mehr im Kapitel 3 „Backendsystem„.
Im Setup wird die für dieses Beispiele benötigte Serielle Schnittstelle initialisiert. Darauf folgend wird die Gruppe 1, in der sich alle oben angelegten Menüelemente befinden aktiviert, sodass diese sichtbar ist. Danach werden die oben automatisch angelegten Variablen mit dem Makro „LCDML_setup(_LCDML_BACK_cnt);" anhand der zuvor eingestellten Menükonfiguration initialisiert.
In der Loop Schleife befindet sich nur die LCDML_run(_LCDML_priority); Funktion, diese kümmert sich um den Aufruf der Funktion die im Backendsystem laufen. Dazu auch später mehr.
Das Beispiel beinhaltet drei Menüelemnte bei denen Funktionen hinterlegt sind:
LCDML_FUNC_information
Zeigt einfach nur eine Information an
LCDML_FUNC_timer_info
lässt einen Timer runter zählen
LCDML_FUNC_p2
Hier muss etwas mit Button gemacht werden
Um den Aufbau und das Anlegen von Menüfunktionen geht's im nächsten Beitrag.
Download