Pages: [1] 2 3 ... 29   Go Down
Author Topic: Projekt: LCDMenuLib - LCD Menü mit mehreren Ebenen (4Bit/I2C/ShiftReg/...)  (Read 47248 times)
0 Members and 1 Guest are viewing this topic.
Germany, Osnabrück
Offline Offline
God Member
*****
Karma: 30
Posts: 646
E-Technik Student - Master
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Projekt: LCDMenuLib - Arduino - LCD Menü mit mehreren Ebenen ( Tree-Model / Nested Set ) - 4Bit - 8Bit - I2C - ShiftRegister (SR) - weitere Möglichkeiten

Last Update 25.07.2014

Wichtig: Wer 3 oder mehr Taster direkt an digitalen Eingängen anschließen möchte, sollte nicht  den Pin 1 dafür verwenden. Über Pin 0 und Pin 1 läuft die Serielle Schnittstelle. Die Beispiele pass ich heute an.

Download: LCDMenuLib

1. Beschreibung:
Mit der LCDMenuLib kann ein Menü mit mehreren Ebenen erstellt werden. Es werden maximal 254 Menu-Elemente unterstützt. Durch die Anwendung des Nested-Set-Models wird eine Baumstruktur erzeugt, wobei der Stamm an sich selbst nicht angezeigt wird. Der Stamm hat die Bezeichnung "Item". Jeder Zweig der von diesem ab geht, hat die Bezeichnung Item_xx für Ebene 0 und Item_xx_xx für Ebene 1. Hinter den Items befinden sich Zahlen die jeweils auf das vorherige Element verweisen. Mehr Informationen zum Nested-Set-Model können dem Link entnommen werden Nested-Set-Model. Die Verwendung der Items ersetzt das einsetzen der Zahlen.

2. Eigenschaften / Anforderungen / Grenzen / Bilder:
  • 254 Menüpunkte maximal
  • 254 Menüpunkte pro Ebene möglich / keine Begrenzungen bei der Ebenen Anzahl
  • automatischer Funktionsaufruf / Callback Funktionen
  • Trennung von Struktur- und Funktionsebene durch mehrere Tabs
  • Leitfaden für den sauberen Programmaufbau / saubere Strukturierung
  • Ansteuerung über mindestens 3 Taster / Funktionen (up, down, enter)
  • maximal 6 Taster werden unterstützt (up, down, enter, quit/back, left, right)
  • Ansteuerung z.B. auch über Drehgeber oder andere Möglichkeiten möglich
  • InitScreen aktivierbar, dieser wird nach X Sekunden und/oder zu Beginn angezeigt
  • Scrollbalken aktivierbar
  • Scrollbalken wird nur angezeigt, wenn mehr Menuelemente wie Zeilen im Display vorhanden sind
  • Cursor Position wird gespeichert, nachdem eine Ebene zurück gegangen wird
  • Möglichkeit direkt zwischen Menüelementen hin und her zu springen
  • Möglichkeit die Menüelement ID abzufragen
  • normale LiquidCrystal Lib wird unterstützt
  • mit einer neueren LiquidCrystal Lib wird auch I2C und andere Schnittstellen unterstützt. Die folgende Lib wird benötigt: LiquidCrystal New 1.2.1
  • DogLCD unterstützung
  • Menupunktbezeichnungen werden im Flash Speicher abgelegt
  • die letzte Position beim zurückgehen durch die Ebenen wird gespeichert
  • Funktionsnamen von vorgegebenen Funktionen werden graphisch hervorgehoben
  • es werden keine graphischen Displays unterstützt



3. Einbindung der Lib in die Arduino Umgebung:
Die Lib befindet sich am Ende des ersten Beitrages und muss heruntergeladen werden. Anschließend wird das Archiv entpackt und in das Verzeichnis arduino/libraries/ kopiert. Hierbei muss darauf geachtet werden, dass der Ordner LCDMenuLib direkt die *.h und *.cpp Dateien enthält und kein weiterer Unterordner mit der Bezeichnung "LCDMenuLib" existiert. Nach dem Einbinden der Lib muss, falls die Software gestartet war, die Software neugestartet werden. Der Beispiel Code kann über  Datei->Beispiele->LCDMenuLib->lcdml oder lcdml_i2c aufgerufen werden.

4. Schnittstellen:
Seit der letzten Version wird außer der LiquidCrystal Lib noch die LiqudiCrystal_New Lib 1.2.1 unterstützt. Diese verbessert die Ausführungsgeschwindigkeit der alten Lib und bringt neue Schnittstellen mit sich. Alle Funktionen sind zur "alten" Lib compatibel zudem werden I2C und ShiftRegister unterstützt. Um die neuen Schnittstellen nutzen zu können muss die LCDMenuLib___config.h im Lib Verzeichnis geöffnet werden. In dieser befindet sich ein #define welches verschiedene Zahlenwerte annehmen kann. Mit den Werten wird die Schnittstelle festgelegt.
Je Nach Schnittstellenkonfiguration müssen eventuell die folgenden Konstanten definiert werden
Code:
//Liquidcrystal 4Bit Mode    
#define _LCDMenuLib_LCD_rs                        4
#define _LCDMenuLib_LCD_e                         5
#define _LCDMenuLib_LCD_dat0                      8
#define _LCDMenuLib_LCD_dat1                      9
#define _LCDMenuLib_LCD_dat2                      7
#define _LCDMenuLib_LCD_dat3                      11
//read write
#define _LCDMenuLib_LCD_rw                        0
//8bit mode
#define _LCDMenuLib_LCD_dat4                      0    
#define _LCDMenuLib_LCD_dat5                      0    
#define _LCDMenuLib_LCD_dat6                      0      
#define _LCDMenuLib_LCD_dat7                      0
//backlight
#define _LCDMenuLib_LCD_backlight                 0
#define _LCDMenuLib_LCD_backlight_pol         POSITIVE  // oder NEGATIVE  sowie das LCD die Einstellung benötigt
//i2c address
#define _LCDMenuLib_LCD_addr                      0x20
Das fehlen der Konstanten wird durch eine Fehlermeldung beim kompelieren angezeigt.

5. Inbetriebnahme eines Beispiels (LCD-4Bit-Mode / I2C):
Zuerst muss die Arduino Umgebung geöffnet werden. Anschließen wird das Beispiel geladen :Datei->Beispiele->LCDMenuLib->lcdml. Die jenigen die ein I2C Display verwenden, sollten das lcdml_i2c Beispiel öffnen (bitte Punkt 4 beachten und die Konfiguration in der Datei "LCDMenuLib___config.h" anpassen).
Nun sollte das Beispiel mit drei Tabs geöffnet sein. Im ersten Tab "lcdml"/"lcdml_i2c" wird die Hardware Schnittstelle sowie die Menüstruktur festgelegt.  Im zweiten Tab "LCDML_control" befinden sich die Steuerungsmöglichkeiten, z.B. analoger Anschluss, digitale Pins, Serielle Steuerung. Zu Anfang ist immer die Serielle Steuerung ausgewählt. Bei dieser Auswahl kann das Menü über den seriellen Monitor mit "a"=>links, "d" => rechts, "w" => hoch, "s" => runter, "q" => quit, "e" => enter, gesteuert werden. Zu den Steuerungsmöglichkeiten gehört auch die Konfigurationsvariabel _LCDMenuLib_cfg_press_time. Mit dieser wird die Zeit eingestellt wie schnell nacheinander das Menü gesteuert werden kann.
Nach dem die Hardwareeinstellungen vorgenommen wurden kann das Beispiel auf den Arduino übertragen werden. Auf dem Display sollte nun eine ähnliche Darstellung erscheinen wie in den Bilder die unter Punkt 2 angegeben sind.

6. Aufbau des Beispiels

Anlegen von Menü Elementen

Als erstes müssen die Sprachelemente generiert werden.
Code:
 #define _LCDMenuLib_cnt    4    //muss der letzten verwendeten ID im Menü entsprechen
  LCDMenuLib_init(_LCDMenuLib_cnt);
  LCDMenuLib_element(0  , Item         , Item_1        , "Information"        , FUNC_information);
  LCDMenuLib_element(1  , Item         , Item_2        , "Zeit Info"          , FUNC_timer_info);
  LCDMenuLib_element(2  , Item         , Item_3        , "Einstellungen"      , FUNC);
  LCDMenuLib_element(3  , Item_3       , Item_3_1      , "Werte veraendern"   , FUNC);
  LCDMenuLib_element(4  , Item_3       , Item_3_2      , "Irgendwas"          , FUNC);
//.....
Beschreibung:
  • Parameter 1: Interne Bezeichnung um die Sprachelemente zu verknüpfen. Die Nummer am Ende der Bezeichnung muss von 0 aufwärts verlaufen.
  • Parameter 2: gibt die Ebene an in der ein neues Element erzeugt werden soll
  • Parameter 3: Item Name der für den Menüpunkt. Dieser ist wichtig um später die Struktur zu erzeugen. Es ist geschickt, wenn man hier die Items schon so benennt, dass diese der Struktur des Menüs entsprechen.  Items mit einer Zahl befindet sich auf der obersten Ebene. Items mit zwei Zahlen auf der darunter. Wenn man weiß, dass mehr als 10 Items in einer Ebene sind, sollte die Bezeichnung vielleicht so aussehen:  Item_1 für Ebene 1, Item_1_1 für erstes Element in Ebene zwei. Die Benennung der Items ist jedem selbst überlassen.
  • Parameter 4: Bezeichnung des Menüpunktes. Kann bei einem 20 Spalten LCD  18 Zeichen lang sein, bei einem 16 Spalten LCD 14 Zeichen.
  • Parameter 5: Beinhaltet die Funktion, die aufgerufen wird, wenn der Menupunkt mit "Enter" ausgewählt wird. Die ersten beiden Element rufen eine spezielle Funktion auf. Beim dritten Button ist nur "FUNC" angegeben. Das bedeutet, dass hier eine leere Funktion hinterlegt ist. Bei Menüpunkten die mit  "FUNC" erzeugt werden, sind keine Funktionen hinterlegt. Diese Eignen sich um weitere Ebenen im Menü anzulegen. Es ist sinnvoll sich hier das Beispiel anzuschauen.

Fortsetzung folgt im nächsten Beitrag:

Falls Fragen aufkommen, ihr Verbesserungen habt, oder nicht weiter kommt (im Bezug zum Menu), antwortet bitte auf dieses Thema oder legt auf GitHub ein "Issues" an.

Download: LCDMenuLib
« Last Edit: July 25, 2014, 12:16:02 am by Jomelo » Logged

Germany, Osnabrück
Offline Offline
God Member
*****
Karma: 30
Posts: 646
E-Technik Student - Master
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Menufunktionen anlegen / Callback Funktionen

Alle Funktionen die nicht "FUNC" heißen werden vom Menü als Callback Funktionen aufgerufen. Diese Funktionen müssen angelegt werden. In dem Vorgegebenen Beispiel befinden sich ein paar dieser Funktionen im dritten Tab "LCDML_function". Jede Funktion muss mit dem gleichen Gerüst, welches unten anhand einer Dummy Funktion beschrieben wird, aufgebaut werden.
Code:
void FUNC_dummy(void)
  {  
    /* --------- INIT ---------
     * Initialisierung dieser Funktion
     * wird nur einmal beim Start dieser Funktion ausgefuert
     * danach nur erneut, wenn die Menu Funktion verlassen wurde
     * wenn keine Variablen initialisiert werden müssen, kann diese
     * Funktion anstatt mit if(!LCDML.FuncInit()) ....     mit
     * LCDML.FuncInit();  aufgerufen werden    
     */  
    if(!LCDML.FuncInit())
    {
      /* Init Function */          
    }
    /* --------- LOOP ----------
     * Hier sollte der Code stehen der ständig neu geladen wird
     * z.B. eine Uhrzeit oder änliches.
     */    
    
    /* --------- STOP  ---------      
     * LCDML.FuncEnd(direct, enter, up, down, left, right)
     * Falls in dieser Funktion keine Variablen zurückgesetzt werden
     * müssen, kann diese Funktion auch vereinfacht mit LCDML.FuncEnd(0, 1, 1, 1, 1, 1);
     * aufgerufen werden. Die Endbedingungen können durch 1 aktiviert oder 0 deaktiviert  
     * werden
     * Wenn alles 0 ist, hängt das gesammte Programm in dieser Funktion fest
     */
    if(LCDML.FuncEnd(0, 1, 1, 1, 1, 1))
    {
    /* Bei allen Parameter gilt bei '0': nichts machen.
      * Parameter 'direct':
      * Die Funktion wird direkt beendet ohne auf weitere Ereignisse zu warten
      * Parameter 'enter', 'up', 'down', 'left', 'right':
      *   Wenn z.B. 'enter' = 1 ist, muss einmal die Enter Taste gedrückt werden,
      *   damit die Funktion beendet wird.
      *   Wenn z.B. 'enter' = 2 ist, muss zweimal die Enter Taste gedrückt werden,
      *   damit die Funktion beendet wird.
      * Dieses gilt bei den anderen Buttons 'up', 'down', ... genauso.
      */

      /* Falls noch Variablen zurückgesetzt werden müssen, bevor diese Funktion
       * verlassen wird, kann dies in dieser If Schleife geschehen
       */
    }    
  }
angelegt werden.
Der Funktionsaufruf erfolgt automatisch, sobald der Menüpunkt mit "Enter" aufgerufen wird. Im Beispiel sind drei Funktionen hinterlegt, die Beispielcode beinhalten.


zu 8. Unterstützende Funktionen:
Delays würden den Programmablauf stören und zu unerwarteten Problemen führen. Aus diesem Grund wurden eine Hilf Funktionen hinzugefügt, die dies vermeiden soll.
Code:
// Delay without Delays
// Variable global anlegen unter  "Globale Variables"
unsigned long g_timer_xxBezeichnung = 0;

// In der Menufunktion
if(LCDML.Timer(g_timer_xxBezeichnung, 500)) {
  //quellcode wird nur alle 500 ms einmal ausgeführt
}
Wenn man mehrere Timer in verschiedenen Menu Funktionen benötigt, sollte man nicht für jede Funktion eine eigene unsigned long Variable anlegen, sondern die Timer z.B.  g_timer_func_1, g_timer_func_2  nennen und in mehreren Funktionen verwenden. Dies spart pro Variable 4Byte Ram.

Abfragen ob ein Button betätigt wurde:
Code:
if(LCDML.checkButtons()) {
  //irgend ein Button wurde betätigt
}

zu 9. Steuerungsmöglichkeiten:
Das jetzige Beispiel sieht die Steuerung über die Serielle Schnittstelle mit den Tasten  'a'=links, 's'=down, 'w'=up, 'd'=right, 'e'=enter und 'q' für quit/back/exit  vor (Button mode = 0). Alternative kann das Menü über eine Tastatur die über eine geschickte Widerstandswahl an einen analogen Eingang angeschlossen ist bedient werden. Hier können auch beliebige andere Steuerungsmöglichkeiten vorgesehen werden. Folgende Möglichkeiten wurden schon im Forum gesehen:
  • über eine IR Fernbedienung
  • mit einem KeyPadShild
  • über Netzwerk
Für die Entwicklung einer eigenen Steuerung gibt es die folgenden Funktionen:
Code:
LCDML.Button_enter();
LCDML.Button_up_down_left_right(_LCDMenuLib_button_up);
LCDML.Button_up_down_left_right(_LCDMenuLib_button_down);
LCDML.Button_up_down_left_right(_LCDMenuLib_button_left);
LCDML.Button_up_down_left_right(_LCDMenuLib_button_right);      
LCDML.Button_quit();
Im Beispiel befindet sich der Code ganz unten im ersten Tab. z.B. bei  ButtonMode_analog()

Die Ansteuerung mit LCDMenu_ButtonAnalog beinhaltet folgenden Code:
Code:
/* analog menu control */
void LCDMenuLib_control_analog()
{
  uint16_t value = analogRead(0);  // analogpin for keypad

  #define _BUTTON_analog_enter_min     850     // Button Enter
  #define _BUTTON_analog_enter_max     920  
  #define _BUTTON_analog_up_min        520     // Button Up
  #define _BUTTON_analog_up_max        590  
  #define _BUTTON_analog_down_min      700     // Button Down
  #define _BUTTON_analog_down_max      770  
  //optional if menu element "back" exists, look at FUNC_back in functions tab
  #define _BUTTON_analog_enable_quit   1
  #define _BUTTON_analog_back_min      950     // Button Back
  #define _BUTTON_analog_back_max      1020  
  //optional if needed
  #define _BUTTON_analog_enable_lr     1
  #define _BUTTON_analog_left_min      430     // Button Left
  #define _BUTTON_analog_left_max      500  
  #define _BUTTON_analog_right_min     610     // Button Right
  #define _BUTTON_analog_right_max     680  
      
  if(LCDML.Timer(g_LCDMenuLib_press_time, _LCDMenuLib_cfg_press_time)) {
    if(value >= _BUTTON_analog_enter_min && value <= _BUTTON_analog_enter_max) {        // control enter
      LCDML.Button_enter();
    }  
    else if(value >= _BUTTON_analog_up_min && value <= _BUTTON_analog_up_max) {      // control up
      LCDML.Button_up_down_left_right(_LCDMenuLib_button_up);
    }
    else if(value >= _BUTTON_analog_down_min && value <= _BUTTON_analog_down_max) {   // control down
      LCDML.Button_up_down_left_right(_LCDMenuLib_button_down);
    }    
    else if(value >= _BUTTON_analog_left_min && value <= _BUTTON_analog_left_max && _BUTTON_analog_enable_lr == 1) {   // control left
      LCDML.Button_up_down_left_right(_LCDMenuLib_button_left);
    }
    else if(value >= _BUTTON_analog_right_min && value <= _BUTTON_analog_right_max && _BUTTON_analog_enable_lr == 1) { // control right
      LCDML.Button_up_down_left_right(_LCDMenuLib_button_right);
    }
        
    if(value >= _BUTTON_analog_back_min && value <= _BUTTON_analog_back_max && _BUTTON_analog_enable_quit == 1) {          // control quit
      LCDML.Button_quit();
    }
  }
}

Wenn ihr z.B. nur mit vier Tastern (hoch, runter, links, rechts) euer Menü steuern wollt, dann passt die Funktion an und bindet die Änderung unter einem neuen Funktionsnamen in der Loop Schleife oberhalb der LCDMenuLib_loop() ein. Rechts kann auch = Enter sein und  Links = Quit. Die Standard Variante mit 6 Buttons wird von einem Makro in der Lib erzeugt. Eigene Anpassungen sollten kein Problem darstellen.

zu 10. Weitere Funktionen um gewisse Dinge Abzufragen:
Code:
LCDMenuLib_IS_reStartTime();   // restart initscreen wait time
LCDMenuLib_IS_startDirect(); // start initscreen direct
LCDMenuLib_getActiveFuncId() // get active function/menu element id

LCDML.getLayer()  // get the layer where the menu is now
LCDML.getInitScreenActive()  //


Ich hoffe dieses Tutorial hilft euch weiter.

Download: LCDMenuLib
« Last Edit: February 24, 2014, 07:56:33 am by Jomelo » Logged

Offline Offline
Jr. Member
**
Karma: 2
Posts: 89
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

läuft mit ein paar Veränderungen  smiley-grin DANKE !!!!

Quote
// Einstellungen für das verwendete LCD (20x4)  
  #define _LCD_cols                          16
  #define _LCD_rows                          2

// Pin Belegung für das LCD
  #define _LCD_PIN_rs                        12
  #define _LCD_PIN_e                         11
  #define _LCD_PIN_dat4                      5
  #define _LCD_PIN_dat5                      4
  #define _LCD_PIN_dat6                      3
  #define _LCD_PIN_dat7                      2
  
// Der Button mode gibt an wie die Tastatur (Tastenfeld) angeschlossen werden sollen
// 0 = Keine Buttons verwenden (Steuerung über Serialmonitor)
//     (w = up, a = left, s = down, d = right, q = back, e = enter)
//    

// Der Button mode gibt an wie die Tastatur (Tastenfeld) angeschlossen werden sollen
// 0 = Keine Buttons verwenden (Steuerung über Serialmonitor)
//     (w = up, a = left, s = down, d = right, q = back, e = enter)
//     
// 1 = Einen Eingang und Auswertung über Bereiche
// 2 = Für jeden Button einen Eingang
  #define _BUTTON_MODE                       0


« Last Edit: September 29, 2011, 07:30:13 am by Yeahuno » Logged

Offline Offline
Full Member
***
Karma: 4
Posts: 189
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Jomelo,
allerherzlichsten Dank für die Projektvorstellung.

Gruss
Kurti
Logged

Es gibt nur 10 Arten von Menschen: die, die das Binär-System verstehen und die, die es nicht verstehen.

Offline Offline
Newbie
*
Karma: 2
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

"WProgram.h" muss durch "arduino.h" ersetzt werden. Habe lange gesucht bevor ich als Neuling herausgefunden habe.
Gruss
helix1
Logged

Germany, Osnabrück
Offline Offline
God Member
*****
Karma: 30
Posts: 646
E-Technik Student - Master
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Update:
 - Ich habe die Library auch für die Arduino Version 1.0.1 brauchbar gemacht.
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 56
Posts: 2983
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Super, Jomelo.

Eine Frage zum Verständnis:
Du erzeugst Objekte vom Typ Menu, arbeitest aber meist mit den char* auf deren Texte. Hat das einen Grund ?
Falls der gleiche Text in verschiedenen Menu Objekten (z.B. auf verschiedenen Ebenen oder in verschiedenen Zweigen) auftaucht, bist du sicher, dass die zwei #define Anweisungen zwei unterschiedliche char* adressieren?

Code:
#define _LANG_MENU_setting1_2                     "Einstellungen"
#define _LANG_MENU_setting3_2                     "Einstellungen"

Menu Item1_2    (_LANG_MENU_setting1_2);
Menu Item3_2    (_LANG_MENU_setting3_2);

char * tmp =  _LANG_MENU_setting1_2;  // z.B.

if (tmp  == _LANG_MENU_setting3_2 ) {
 // eine sicher nicht gewollte eventuelle Optimierung des Compilers
 // wenn man hier landet
}




Für Uno (oder noch kleinere Arduinos), oder wenn der Arduino neben der Menu System Bedienung nebenbei noch möglichst viele dynamische Daten zwischenspeichern soll und/oder einen ganzen SD card block im RAM halten soll, oder ...,

... wäre es noch superer, wenn die konstanten Menü-Texte aus dem Flash genommen würden ...

Logged

Germany, Osnabrück
Offline Offline
God Member
*****
Karma: 30
Posts: 646
E-Technik Student - Master
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Du erzeugst Objekte vom Typ Menu, arbeitest aber meist mit den char* auf deren Texte. Hat das einen Grund ?
Ich habe das damals so gewählt, da ich dann die einzelnen Menü Ebenen mir über die Serielle Schnittstelle auch direkt ausgeben lassen konnte.
Außerdem war es zum damaligen Zeitpunkt leichter texte miteinander zu vergleichen (vom Verständnis her).

Falls der gleiche Text in verschiedenen Menu Objekten (z.B. auf verschiedenen Ebenen oder in verschiedenen Zweigen) auftaucht, bist du sicher, dass die zwei #define Anweisungen zwei unterschiedliche char* adressieren?
So wie in deinem Beispiel funktioniert der Aufruf nicht. Ich nutze dazu einen array in dem jeweils der Name der nächst höheren Ebene steht. "funcname"

Beispiel:
Code:
#define _LANG_MENU_setting1_2                     "Einstellungen"
#define _LANG_MENU_setting3_2                     "Einstellungen"

Menu Item1_2    (_LANG_MENU_setting1_2);
Menu Item3_2    (_LANG_MENU_setting3_2);

char * tmp =  _LANG_MENU_setting1_2;  // z.B.

void BACK_SelectMenuFunction(void)
  {
    char *tmp;
      // Selbsthaltung der ausführenden Funktion falls gesetzt
      // HIER NICHTS ÄNDERN
      if(func_loop_name != NULL) {
        tmp = func_loop_name;
      } else {
        tmp = lcd_display.curfuncname;
      }         
       
      // AB HIER KÖNNEN ÄNDERUNGEN GEMACHT WERDEN
     
      //Nur Menupunkte die Ausgeführt werden können sollten hier drin stehen
      if(tmp == _LANG_MENU_setting1_2 && lcd_display.funcname[1] == "Ebene 1")
      {
               
      }
      else if(tmp == _LANG_MENU_setting3_2 && lcd_display.funcname[2] == "Ebene 2")
      {
               
      }
Die Bezeichnungen der Ebene stimmen zwar in dem Beispiel nicht, aber das Prinzip sollte deutlich werden.
Und zur Adressverwaltung vermute ich, dass die Inhalte nicht an der gleichen Stelle liegen, da sie auch in unterschiedlichen Objekten angelegt werden.

Die Erweiterung mit dem Flashspeicher ist eine gute Idee. Damit werde ich mich mal beschäftigen. Für mein damaliges Projekt reichte der Ram aus.


Logged

Bardowick
Offline Offline
Newbie
*
Karma: 2
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Jomelo,
erstamals Vielen Dank für deine tolle Arbeit smiley
Bei mir zeigt es leider keine Pfeile nach oben und nach unten, nur die Ziffern 0 (Pfeil nach oben?) und 1 (Pfeil nach unten?),
habe schon versucht was zu machen, aber als Anfänger komme ich nicht weiter smiley-cry
Ist es auch möglich dass, erstmal zB. Datum und Zeit angezeigt werden und erst beim OK drücken spring es ins Menü?
Grüße
Jurek
Logged

Germany, Osnabrück
Offline Offline
God Member
*****
Karma: 30
Posts: 646
E-Technik Student - Master
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

das die Pfeile nicht angezeigt werden, liegt vermutlich am verwendeten Display oder aber daran, dass schon zuviele Benutzerdefinierte Zeichen für das Display belegt sind.

Du kannst das Display im Programm immer löschen und für eigene Zwecke verwenden.
Sobald du "lcd_display.display(); "  aufrufst, sollte das Menü wieder erscheinen.

Logged

Bardowick
Offline Offline
Newbie
*
Karma: 2
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
leider komme ich nicht weiter...
Wenn ich über lcd.write() im loop die Pfeile anzeige funktioniert das, aber im Programm selbst nicht.
Ich habe ein UNO R3 und ein LCD Keypad shield von DFRobot. Mein IDE ist 1.0.1
Code: https://www.dropbox.com/s/ebh4pj9ou12608a/Kirys_menu.txt
An welche Stelle muss ich in meinem Beispiel die display_RTC() setzen?
Wenn ich das in loop mache überlappen sich der Zeit und das Menü  smiley-confuse
Bitte um Hilfe
Logged

Bardowick
Offline Offline
Newbie
*
Karma: 2
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,
gute Nachrichten  smiley
dank den Tipp von Jamelo ist mir gelungen die Pfeile anzuzeigen.
Folgendes habe ich verändert:
in der Datei LCDMenu2.cpp
Zeilen von 199 bis 210, print auf write und die HEX weg
Code:
            if(curloc == 0) {
                lcd->setCursor((cols-1),(rows-1));
                lcd->write(arrow_down);
            }
            else if(curloc == j) {
                lcd->setCursor((cols-1),0);
                lcd->write(arrow_up);
            }
            else {
                lcd->setCursor((cols-1),0);
                lcd->write(arrow_up);

                lcd->setCursor((cols-1),(rows-1));
                lcd->write(arrow_down);
und in void setup()
Code:
lcd.createChar(0,arrow_up);
lcd.createChar(1,arrow_down);   

und dann funktioniert zumindest bei mir  smiley-wink
« Last Edit: November 15, 2012, 08:33:35 am by offtopic » Logged

Bardowick
Offline Offline
Newbie
*
Karma: 2
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich verzweifle langsam, was ist an dem Code falsch smiley-sad
es funktionier einfach nicht
Code:
/* ===============================================
 * SET DATE
 * ===============================================
 */
 void set_Date(char *func_name)
  {
    //CONTROL_refresh_button();
    t = rtc.getTime(); // Get data from the DS1307
    int tag, monat, jahr, pos;
    if (!CONTROL_set_func_active(func_name))
    {
      pos=0;
      tag=t.date;
      monat=t.mon;
      jahr=t.year;
      Serial.print(tag);
      Serial.print(monat);
      Serial.print(jahr);
      lcd.clear();
      lcd.setCursor(3,0);
      lcd.write("Set   date");
      lcd.setCursor(3,1);
      if (tag<10){lcd.print("0");}
      lcd.print(tag);
      lcd.write(".");
      if (monat<10){lcd.print("0");}
      lcd.print(monat);
      lcd.write(".");
      lcd.print(jahr);
    }
    if (menu_button_down == 1 && pos==0) //set tag-
      {
        if ((tag>1) && (tag<=31))
          {
            Serial.print(tag);
            Serial.print(" down ");
            delay(250);
            tag--;
            Serial.print(tag);
            menu_button_down=0;
            if (tag<10) {lcd.setCursor(3,1);lcd.print("0");lcd.print(tag);}
            else {lcd.setCursor(3,1);lcd.print(tag);}
            lcd.setCursor(3,1);
            lcd.blink();
          }
      }
    if (menu_button_up == 1 && pos==0)  //set tag+
      {
        if ((tag<31) && (tag>=1))
          {
            Serial.print(tag);
            Serial.print(" up ");
            delay(250);
            tag++;
            Serial.print(tag);
            menu_button_up=0;
            if (tag<10) {lcd.setCursor(3,1);lcd.print("0");lcd.print(tag);}
            else {lcd.setCursor(3,1);lcd.print(tag);}
            lcd.setCursor(3,1);
            lcd.blink();
          }
      }
    if (menu_button_up == 1 && pos==1)  //set monat+
      {
        if ((monat<12) && (monat>=1))
          {
            Serial.print(monat);
            Serial.print(" up ");
            delay(250);
            monat++;
            Serial.print(monat);
            menu_button_up=0;
            if (monat<10) {lcd.setCursor(6,1);lcd.print("0");lcd.print(monat);}
            else {lcd.setCursor(6,1);lcd.print(monat);}
            lcd.setCursor(6,1);
            lcd.blink();
          }
      }
    if (menu_button_down == 1 && pos==1)  //set monat-
      {
        if ((monat<=12) && (monat>1))
          {
            Serial.print(monat);
            Serial.print(" down ");
            delay(250);
            monat--;
            Serial.print(monat);
            menu_button_down=0;
            if (monat<10) {lcd.setCursor(6,1);lcd.print("0");lcd.print(monat);}
            else {lcd.setCursor(6,1);lcd.print(monat);}
            lcd.setCursor(6,1);
            lcd.blink();
          }
      }
    if (menu_button_up == 1 && pos==2)  //set jahr+
      {
        if (jahr<2100 && jahr>=2000)
          {
            Serial.print(jahr);
            Serial.print(" up ");
            delay(250);
            jahr++;
            Serial.print(jahr);
            menu_button_up=0;
            lcd.setCursor(9,1);
            lcd.blink();
            lcd.print(jahr);
          }
      }
    if (menu_button_down == 1 && pos==2)  //set jahr-
      {
        if ((jahr<=2100) && (jahr>2000))
          {
            Serial.print(jahr);
            Serial.print(" down ");
            delay(250);
            jahr--;
            Serial.print(jahr);
            menu_button_down=0;
            lcd.setCursor(6,1);
            lcd.blink();
            lcd.print(jahr);
          }
      }
    if (menu_button_right == 1)
    {
      pos++;
      if (pos>3)
      {
        pos=0;
      }
    }
    // CONTROL_func_end (direct, enter, up, down, left, right)
    CONTROL_set_func_end(0, 1, 0, 0, 0, 0);
  }
Logged

Germany, Osnabrück
Offline Offline
God Member
*****
Karma: 30
Posts: 646
E-Technik Student - Master
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Was funktioniert denn genau nicht, und was hast du vor ?
Logged

Bardowick
Offline Offline
Newbie
*
Karma: 2
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Es soll über LCD Display und  Keypad Shield Tasten das Datum einstellen.
Es fehlt noch am ende der Befehl
Code:
rtc.setDate(tag, monat, jahr);
ich wollte, sätzen des Datums mit enter bestätigen und auch beenden.
Wie etwa:
Code:
if (menu_button_enter == 1)
{
rtc.setDate(tag, monat, jahr);
CONTROL_set_func_end(0, 1, 0, 0, 0, 0);
}
Leider wenn ich diese Code ausführe passiert nichts, es werden keine tasten erfasst (außer back)
dafür habe ich mir die Ereignise im Serial anzeigen lassen. Es wird nichts angezeigt smiley-sad
Variable "pos" sagt ob ein Tag, Monat oder Jahr zu stellen ist (0 - Tag, 1 - Monat, 2 - Jahr) und dort soll auch der Blinkcursor stehen.
Tasten nach oben und nach unten sollen den jeweiligen Wert ändern.
Der Hauptcode kommt von deinem Beispiel, ich habe nur das Menü (läuft Prima) und die ausführende Funktionen verändert.
Gruß
offtopic
Logged

Pages: [1] 2 3 ... 29   Go Up
Jump to: