Go Down

Topic: Projekt: LCDMenuLib - Menü mit mehreren Ebenen (4Bit/I2C/u8glib/SerialMonitor) (Read 150491 times) previous topic - next topic

Jomelo

Projekt: LCDMenuLib (LCDML)
Die Dokumentation befindet sich auf GitHub unter "doc/lcdml_german.pdf"


Aktuellste Version
Library:  Version 2.1.4     Download
Download nun auch über den Arduino Bibliotheksmanager möglich. Einfach nach "LCDMenuLib" suchen.

Beschreibung:
Mit der LCDMenuLib kann ein Menü mit mehreren Ebenen erstellt werden. Aber nicht nur dass, die Lib bietet die Möglichkeit Menüfunktionen und Hintergrundfunktionen logisch voneinander zu trennen. Dazu gibt es die Displayebene und die Backendebene.
Auf der Displayeben wird das Menü angezeigt. Diese kann maximal 254 Menüelemente enthalten, welche sich in verschiedenen Ebenen nach dem Vorbild einer Baumstruktur anordnen lassen. Sprich es gibt einen Stamm, von dem verschiedene Äste (Sub Menüs) abgehen. Dieses Modell wird auch Nested Set Model genannt. Der Stamm des Menüs wird beim Anlegen der Lib generiert, alle Äste sind konfigurierbar. Werden in einer Ebene mehr Elemente verwendet als auf dem Display angezeigt werden können, wird ein Scrollbalken eingeblendet. Der Inhalt einer Menüfunktion wird nur dann aktualisiert, wenn ein Aktion ausgeführt wird. Eine Aktion kann das Drucken eines Buttons sein oder aber ein Trigger. Trigger können auf eine feste Zeit konfiguriert werden, so dass die Menüfunktion in einem Intervall von XX Millisekunden aktualisiert wird.  In der Menüfunktion sollte wenn möglich nur der Inhalt für das Display stehen oder die Verarbeitung der Buttons stattfinden. Es sollte hier niemals die „delay(x)" Funktion verwendet werden.
Hintergrundfunktionen, z.B. das Einsammeln von Daten über den Ethernet-Anschluss oder die Serielle Schnittstelle finden im Backendsystem statt unabhängig davon welcher Menüpunkt gerade aktiv ist. Im Backendsystem können Funktionen angelegt werden, die dauerhaft in einem Intervall laufen. Z.B. alle 5000 Millisekunden die Raumtemperatur auslesen.
Die Lib erzwingt eine Trennung des Display und des Backensystems, so dass mehr Ordnung beim Programmaufbau gegeben ist. Dies ermöglicht eine einfachere Wartung, nicht alles muss in einer Datei erstellt werden.
In den folgenden Kapiteln wird ein einfacher Einstieg in die Lib gegeben.


Wichtiges vorweg:
  • Falls ihr in eurem Programm die  „delay(x)" Funktion verwenden solltet, beantworte ich keine Fragen dazu. (Schaut euch bitte das „Blink without delay" Bespiel oder die Beispiel die bei der Lib dabei sind  an.
  • Stellt eure Fragen bitte im Forum als Beitrag allen zur Verfügung, dann können auch alle von einer Lösung profitieren.


1.1 Features

  • 254 Menüpunkte maximal (meistens begrenzt der Ram die Anzahl)
  • 254 Menüpunkte pro Ebene möglich / keine Begrenzungen bei der Ebenen Anzahl
  • 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), Encoder, Keypad
  • 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 Menüelemente wie Zeilen im Display vorhanden sind
  • Cursor Position wird gespeichert, nachdem eine Ebene zurückgegangen wird
  • Möglichkeit direkt zwischen Menüelementen hin und her zu springen
  • Möglichkeit die Menüelement ID abzufragen
  • jegliche Displaytypen und Libs können verwendet werden. Das LCD Objekt liegt seit der neusten Version nicht mehr in der Lib. Es ist kein Problem ein Beispiel an ein grafisches Display anzupassen
  • Menüpunktbezeichnungen werden im Flash Speicher abgelegt
  • Funktioniert mit allen Arduino Version ab 1.0.xx
  • Windows / Linux / Mac
  • Es gibt ein Backendsystem für Hintergrundaufgaben, z.B. das Einsammeln von Messdaten
  • Es können maximal 255 Backendfunktionen angelegt werden
  • Backendfunktionen können in Gruppen zusammengefasst werden. Diese Gruppen lassen sich gleichzeitig stoppen oder Starten.
  • in der neusten Version werden auch grafische Displays unterstützt



1.2 Bilder










Bilder ohne Display mit dem Menü in der Konsole





 


Bilder grafisches Display mit u8glib








while(!success){try++;}

Jomelo

Projekt: LCDMenuLib (LCDML) - Kapitel 2: Displayfunktionen
2.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.
Code: [Select]

// 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.
Code: [Select]

#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:
Code: [Select]

// 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.
Code: [Select]

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
while(!success){try++;}

Yeahuno

läuft mit ein paar Veränderungen  :D 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




kurti

Hallo Jomelo,
allerherzlichsten Dank für die Projektvorstellung.

Gruss
Kurti
Zitat Jurs: falsche Verkabelung ist sowieso immer wenig förderlich für das Funktionieren der Hardware



hier könnte Ihre Werbung stehen

helix1

Hallo,

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

Jomelo

Update:
- Ich habe die Library auch für die Arduino Version 1.0.1 brauchbar gemacht.
while(!success){try++;}

michael_x

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: [Select]
#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 ...


Jomelo

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: [Select]

#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.


while(!success){try++;}

offtopic

Hallo Jomelo,
erstamals Vielen Dank für deine tolle Arbeit :)
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 =(
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

Jomelo

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.

while(!success){try++;}

offtopic

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ü  :~
Bitte um Hilfe

offtopic

Hallo,
gute Nachrichten  :)
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: [Select]

            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: [Select]

lcd.createChar(0,arrow_up);
lcd.createChar(1,arrow_down);   


und dann funktioniert zumindest bei mir  ;)

offtopic

Ich verzweifle langsam, was ist an dem Code falsch :(
es funktionier einfach nicht
Code: [Select]

/* ===============================================
* 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);
  }

Jomelo

while(!success){try++;}

offtopic

Es soll über LCD Display und  Keypad Shield Tasten das Datum einstellen.
Es fehlt noch am ende der Befehl
Code: [Select]

rtc.setDate(tag, monat, jahr);

ich wollte, sätzen des Datums mit enter bestätigen und auch beenden.
Wie etwa:
Code: [Select]

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 :(
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

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy