Projekt: LCDMenuLib / LCDMenuLib2 ( LCDML ) - Menü mit mehreren Ebenen

Zu 1: Es lassen sich nur Gruppen deaktivieren. (maximal 8 (ein Byte))
Zu 2: Ein Event läuft nur einmal durch. Da der Arduino nicht parallel läuft macht es meiner Meinung nach keinen Sinn ein Event mit isRun abzufragen. Ich hab das so nicht bedacht und auch nicht getestet. Also geht es auch nicht.

Hallo,

ich schaff es nicht, die Displaybeleuchtung richtig zu steuern.
Bei einem Tastendruck wird diese eingeschaltet und soll nach ca. 10 sek wieder aus gehen. Einschalten funktioniert

if(LCDML.checkButtons()){
digitalWrite(DisplayLed, LOW);
}

aber das Ausschalten bekomme ich nicht hin. Ich habe es über die eingebaute Timerfunktion versucht, weiß aber nicht so recht, wo ich die einbauen soll.
Ich habe es auch mit einer Abwandlung des "BlinkWithoutDelay" versucht, aber auch hier funktioniert es nicht richtig.

void LCDDisplayLed(void){
unsigned long currentMillis = millis();

  if(currentMillis - previousMillis >= 10000{
    previousMillis = currentMillis;   

    if (LCDledState == LOW)
      LCDledState = HIGH;
    digitalWrite(4, LCDledState);
  }

}

Wie starte ich die Funktion, damit die Beleuchtung nach 10 sek ausschaltet?
Aktuell starte ich die aus der Loop im init_screen, hier läuft meine RTC.

Check_SummerTime();                    // auf Sommerzeit prüfen
show_time_and_date();                  // Datum und Uhrzeit ausgeben
CheckSwitchTime(stunden,minuten);      // Schaltzeiten prüfen und anzeigen
SetRelaisOut();                        // Relaisausgänge ansteuern

LCDDisplayLed();                       //Diplaybeleuchtung

Ich hoffe ihr könnt helfen.
Vielen Dank für die Unterstützung

Ich mache es so (bei einem TFT):

const unsigned long DISPLAY_TIMEOUT = 10 * 1000UL;

bool display_is_on;
unsigned long display_timeout;

void display_backlight()
{
  if(display_is_on && (millis() - display_timeout > DISPLAY_TIMEOUT))
  {
     display_is_on = false;

     //hier ausschalten
  }
}

Und dann wenn eine Taste gedrückt wurde sowas in der Art:

display_timeout = millis();
 
if(display_is_on == false)
{
   display_is_on = true;

   //Display hier einschalten

   //hier sollte man return machen, damit der restliche Code nicht ausgeführt wird
}

Also immer wenn eine Taste gedrückt wird, wird der Timer "neu gestartet" und es müssen erst wieder x Sekunden vergehen

Das return deshalb damit der erste Tastendruck nur das Display aufweckt und keine Aktion ausführt

Und wenn du das Display am Anfang an haben willst, musst du noch in setup() display_on auf true setzen und display_timeout auf millis()

Hallo Serenifly,

prima, das funktioniert.

Vielen Dank für den Tipp.

Thanks for this V2 version that run very well with my sainsmart I2C 20x4 LCD .

I don't understand these two lines:

LCDML_BACK_new_timebased_static  (0  , ( 20UL )         , _LCDML_start  , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (1  , ( 1000UL )       , _LCDML_stop   , LCDML_BACKEND_menu);

I explain this lines next month. At the moment i have no time to make anything for arduino.
I renovate my new apartment and can only use the internet over my handy. The whole equipment is in boxes.

Jomelo:
I explain this lines next month. At the moment i have no time to make anything for arduino.
I renovate my new apartment and can only use the internet over my handy. The whole equipment is in boxes.

Ok good work into your apartment :slight_smile: !

i love this menu !!!

Kann es sein das die Option "_LCDML_DISP_cfg_scrollbar_custom_redefine" keine Auswirkung auf eigene angepasste Zeichen hat? Merke leider keinen Unterschied.

Ansonsten muss ich ein großen Lob aussprechen. Funktioniert im Dauerlauf seit 1 Woche in Verbindung mit I2C, DS18B20 und Lichtsteuerung ohne Probleme! Top!

Danke.

The best!! Danke, Jomelo!

Ich habe ein paar Fragen oder Anregungen. Ich splitte sie in mehrere Nachrichten, das mir das Forum nicht erlaubt, mehr als 9000 Zeichen (OMG! Habe ich wirklich sooo viele geschrieben/kopiert?)

LCD Display

Ich verwende ein 40x4 Display und habe es folgendermaßen zum Laufen gebracht:

  • Installiere LiquidCrystalFast von LiquidCrystal Arduino Library, using small character LCD modules with Teensy
  • Obwohl es ein drop-in replacement für die LiquidCrystal-Bibliothek ist, muss es im Verzeichnis LiquidCrystalFast installiert werden. Dies hat den Vorteil, dass es sich nicht mit der Originalbibliothek in die Quere kommt!
  • In der LCD Menu Lib habe ich untenstehende Änderungen gemacht, die Du gerne (sowie alle folgenden) in die Bibliothek übernehmen darfst.

... und alles funktioniert prächtig.

Eine Verständnisfrage: Wäre es nicht einfacher, den Anwender die ganze Initialisierung des Displays zu überlassen? Würde das nicht viel Aufwand Deinerseits ersparen? Ich als Anwender hab auch einige Zeit gebraucht, durch dieses System durchzusteigen... Oder einen _LCDMenuLib_cfg_lcd_type zu definieren (-1?), der es dem Anwender erlaubt, die Initialisierung selber zu machen. Nur so eine Idee...

LCDMenuLib__config.h:

# define _LCDML_DISP_cfg_max_string_length 40 // max string length witch can be display


/* **************************************************************************************************** */
/* 300:400  LiquidCrystalFast 40x4 LCD(extern) */
/*  https://code.google.com/p/liquidcrystal440/ */
/* **************************************************************************************************** */
// =========================
// 4 bit mode (8 bit unsupported by LiquidCrystalFast)
// =========================
//# define _LCDMenuLib_cfg_lcd_type 300 // 4Bit: 6 pin connection (slow): normal LCD, single HD44780 controller
//# define _LCDMenuLib_cfg_lcd_type 301 // 4Bit+rw: 7 pin connection (fast): normal LCD, single HD44780 controller
# define _LCDMenuLib_cfg_lcd_type 302 // 4Bit+rw+2e: 8 pin connection (fast): 4x40 LCD, two HD44780 controller chips
//# define _LCDMenuLib_cfg_lcd_type 303 // 8Bit: 10 pin connection - not recommended, for backwards compatibility only
//# define _LCDMenuLib_cfg_lcd_type 304 // 8bit+rw: 11 pin connection - not recommended, for backwards compatibility only

keywords.txt:

_LCDML_DISP_e1 LITERAL1
_LCDML_DISP_e2 LITERAL1

LCDMenuLib_class.h:

/* ******************************************************************************** */
/* LiquidCrystalFast */
/* ******************************************************************************** */
# if(_LCDMenuLib_cfg_lcd_type >= 300 && _LCDMenuLib_cfg_lcd_type < 400)
 //LCD Function
# define _LCDML_lcd_createChar(pos,char) createChar(pos,char)
# define _LCDML_lcd_setCursor(col,row) setCursor(col,row)
# define _LCDML_lcd_write(content) write(content)
# define _LCDML_lcd_clear() clear()
# define _LCDML_lcd_print(content) print(content)
# define _LCDML_lcd_begin() lcd.begin(_LCDML_DISP_cols,_LCDML_DISP_rows);

 // ====================
 // 4Bit/8Bit Mode
 // ==================== 
# if(_LCDMenuLib_cfg_lcd_type >= 300 && _LCDMenuLib_cfg_lcd_type < 310)
 //LCD type
# define _LCDML_lcd_type LiquidCrystalFast
 //LCD include
# include <LiquidCrystalFast.h>
 //LCD objects
# if(_LCDMenuLib_cfg_lcd_type == 300) //4Bit: 6 pin connection (slow): normal LCD, single HD44780 controller
# define _LCDML_lcd_obj LiquidCrystalFast lcd(_LCDML_DISP_rs, 255, _LCDML_DISP_e, _LCDML_DISP_dat4, _LCDML_DISP_dat5, _LCDML_DISP_dat6, _LCDML_DISP_dat7);
# elif(_LCDMenuLib_cfg_lcd_type == 301) //4Bit+rw: 7 pin connection (fast): normal LCD, single HD44780 controller
# define _LCDML_lcd_obj LiquidCrystalFast lcd(_LCDML_DISP_rs, _LCDML_DISP_rw, _LCDML_DISP_e, _LCDML_DISP_dat4, _LCDML_DISP_dat5, _LCDML_DISP_dat6, _LCDML_DISP_dat7);
# elif(_LCDMenuLib_cfg_lcd_type == 302) //4Bit+rw+2e: 8 pin connection (fast): 4x40 LCD, two HD44780 controller chips
# define _LCDML_lcd_obj LiquidCrystalFast lcd(_LCDML_DISP_rs, _LCDML_DISP_rw, _LCDML_DISP_e1, _LCDML_DISP_e2, _LCDML_DISP_dat4, _LCDML_DISP_dat5, _LCDML_DISP_dat6, _LCDML_DISP_dat7);
# elif(_LCDMenuLib_cfg_lcd_type == 303) //8Bit: 10 pin connection - not recommended, for backwards compatibility only
# define _LCDML_lcd_obj LiquidCrystalFast lcd(_LCDML_DISP_rs, _LCDML_DISP_rw, _LCDML_DISP_e, _LCDML_DISP_dat0, _LCDML_DISP_dat1, _LCDML_DISP_dat2, _LCDML_DISP_dat3, _LCDML_DISP_dat4, _LCDML_DISP_dat5, _LCDML_DISP_dat6, _LCDML_DISP_dat7); 
# elif(_LCDMenuLib_cfg_lcd_type == 304) //8bit+rw: 11 pin connection - not recommended, for backwards compatibility only
# define _LCDML_lcd_obj LiquidCrystalFast lcd(_LCDML_DISP_rs, _LCDML_DISP_rw, _LCDML_DISP_e, _LCDML_DISP_dat0, _LCDML_DISP_dat1, _LCDML_DISP_dat2, _LCDML_DISP_dat3, _LCDML_DISP_dat4, _LCDML_DISP_dat5, _LCDML_DISP_dat6, _LCDML_DISP_dat7); 
# endif
# endif
# endif

Und schließlich in meinem Sketch:

#include <LiquidCrystalFast.h>

// settings for lcd
#define _LCDML_DISP_cols 40
#define _LCDML_DISP_rows 4

// pin settings
#define _LCDML_DISP_rs         6    // LCD 11
#define _LCDML_DISP_rw         12   // LCD 10
#define _LCDML_DISP_e1         7    // LCD 9
#define _LCDML_DISP_e2         4    // LCD 15
#define _LCDML_DISP_dat4       11   // LCD 4
#define _LCDML_DISP_dat5       8    // LCD 3
#define _LCDML_DISP_dat6       10   // LCD 2
#define _LCDML_DISP_dat7       9    // LCD 1

Hier die Fortsetzung:

Rotary Encoder

Hier hatte ich kein Glück mit dem eingebauten Drehgeber (oder wie immer das auf Deutsch heißen mag). Manchmal übersprang er bis zu 3 Menüpunkte, manchmal ging er sogar in die andere Richtung. Meine Lösung lautete: Encoder (Encoder Library, for Measuring Quadarature Encoded Position or Rotation Signals), der mit Interrupts arbeitet.

Weiter unten wieder meine Änderungen, um ihn zum Laufen zu bringen.

Fehlende Zurück-Taste

Das Problem der fehlenden Zurücktaste löste ich dadurch, das ein Doppelklick auf die zentrale Taste das Menü verlässt. Dazu benutze ich die Switch-Bibliothek (Switch library).

Auch hier frage ich mich, ob es nicht einfacher wäre, dem Anwender die Initialisierung und Auswertung zu überlassen...

Hier die Änderungen für beides:

LCDML_control.ino:

// *********************************************************************
#elif(_LCDML_DISP_cfg_control == 5)
#include <Encoder.h>  // http://www.pjrc.com/teensy/td_libs_Encoder.html
Encoder interruptencoder(2, 3);
uint32_t g_LCDML_CONTROL_interruptencoder_timer  = 0;
#include "Switch.h"  // http://www.avdweb.nl/arduino/hardware-interfacing/simple-switch-debouncer.html
Switch btn = Switch(_LCDML_CONTROL_switch_pin, INPUT_PULLUP, LOW, 50, 150, 350);
void LCDML_CONTROL_interruptencoder()
// *********************************************************************
{
  // check encoder time to slow down encoder
  if((millis() - g_LCDML_CONTROL_interruptencoder_timer) >= _LCDML_CONTROL_interruptencoder_time) {
    g_LCDML_CONTROL_interruptencoder_timer = millis(); // reset encoder time

    long newLeft;
    newLeft = interruptencoder.read();
    if      (newLeft > 0) { LCDML_BUTTON_down(); interruptencoder.write(0); }
    else if (newLeft < 0) { LCDML_BUTTON_up()  ; interruptencoder.write(0); }
  }

  // Push button handling
  btn.poll();
  if (btn.longPress()) {
    btn.reset();  // Reset button
    LCDML_BUTTON_enter();
  }
  else if (btn.doubleClick()) {
    btn.reset();
    LCDML_BUTTON_quit();
  }
}

In meinem Sketch:

// Rotary encoder with double click control
void LCDML_CONTROL_interruptencoder();
#define _LCDML_DISP_cfg_control                5  // ClickEncoder
// settings encoder (input pins are INPUT_PULLUP!)
#define _LCDML_CONTROL_interruptencoder_pin_a  2  // pin encoder a
#define _LCDML_CONTROL_interruptencoder_pin_b  3  // pin encoder b
#define _LCDML_CONTROL_interruptencoder_time            200
// settings switch
#define _LCDML_CONTROL_switch_pin              A5 //13 // pin taster

Weitere buttons?

Wäre es möglich, weiter Schalter zu ermöglichen? Ich habe gesehen, dass die Zustände aller Schalter in einem Byte gespeichert werden, aber derzeit nur 6 bits verwendet werden (wenn ich den Code richtig deute). Somit wäre noch Platz für zwei weitere Schalter, gerne auch mit generischen Namen. Warum? In meinem Fall fange ich Enter, Up und Down in LCDML_DISP_loop(LCDML_FUNC_initscreen) ab, um den InitScreen zu steuern. Somit kann ich aber mit meinem rotary encoder nicht mehr ins Menü springen... Außer ich bekommen Zugang zum Doppelklick!

Einen schönen Sommer wünsche ich allen!

Hi,

Could someone help me how can I use it with SPI display module ? I have 20X4 display and I think _LCDMenuLib_cfg_lcd_type shoud by "0" in my case.

Regards,
Turkel.

trecords:
Hi,

Could someone help me how can I use it with SPI display module ? I have 20X4 display and I think _LCDMenuLib_cfg_lcd_type shoud by "0" in my case.

Regards,
Turkel.

I dont know if the New_LiquidCrystal 1.2.1 library accept your SPI version ?

Hi Jomelo!

Nice library! but i am pretty new with arduino ( about 3 month). but i don't understand how to use the library and i dont know the language of German. So can u please make a tutorial for how to use it?

Prithul:
Hi Jomelo!

Nice library! but i am pretty new with arduino ( about 3 month). but i don't understand how to use the library and i dont know the language of German. So can u please make a tutorial for how to use it?

If you know a little bit arduino, just install the library into your IDE libraries folder .
Search the file LCDMenuLib___config.h into this new library.
Open this file with notepad++ .
Into this file, search _LCDMenuLib_cfg_lcd_type and uncomment the ligne that correspond to your LCD type.
Mine is I2C, so i uncomment :

define _LCDMenuLib_cfg_lcd_type 115

All other ligne with _LCDMenuLib_cfg_lcd_type must to be commented...

I don't think that SPI LCD config exist for this library...

After that run the arduino IDE and load one example of this library and try ...

Version 2.01

Die Dokumentation werde ich den nächsten Wochen vervollständigen.

Hallo zusammen,

erstmal möchte ich an dieser Stelle ein riesen Lob an Jomelo loswerden für die geniale MenuLib.

Echt beeindruckend was du hier gezaubert hast :wink:

Nun zu meiner Frage:

Ich habe im tab LCDML_BACKEND eine Funktion durchgängig laufen mit der ich die aktuelle Temperatur eines Sensors auslese und in der Float-Variable temp ablege.
Dies funktioniert auch ohne Probleme.
Nun möchte ich diese Variable "temp" im tab LCDML_DISP nutzen um dort die Temperatur im initscreen auszugeben.

ich habe die Variable im tab LCDML_BACKEND mit float temp; deklariert und um im tab LCDML_DISP mit extern float temp; um die Werte der Variable dort ausgeben zu können.

Leider bekomme ich immer folgende Fehlermeldung bei kompilieren:
"undefined reference to `temp"

Kann mir hier jemand weiterhelfen?

Vielen Dank im Voraus.

Viele Grüße

Olli

Das einfachste ist, wenn du die Variable global definiert anstatt lokal in der Funktion. Lokale Variablen sind nur innerhalb der Funktion gültig, globale auch Funktionsübergreifend.
Definiere die Variable am besten oberhalb von der Setup Funktion im Haubttab.

Vielen vielen Dank,

es funktioniert :wink:

Grüße

Olli

trecords:
Hi,

Could someone help me how can I use it with SPI display module ? I have 20X4 display and I think _LCDMenuLib_cfg_lcd_type shoud by "0" in my case.

Regards,
Turkel.

Hi Turkel,

I'm not sure if your LCD and SPI module will work with this library or not, but the adafruit library(GitHub - adafruit/STEMMA_LiquidCrystal: Liquid Crystal Library for Arduino) supports SPI, which LCDMenuLib now supports.

I haven't tested the SPI mode or know what your exact module is, but you might want to download the adafruit library and get the latest version of LCDMenuLib and give it a try. Go to the config and uncomment the line for SPI.

Hope this helps,

Matt

Hallo zusammen,

ich bin von der LCDMenuLib 2.0 auf 2.01 umgestiegen, da ich gerne mein "Standard" 1602 Display gegen ein I2C 1602 Display ersetzten möchte.

Ist es ausreichend wenn ich die LCDMenuLib 2.0 einfach in den Libraries durch die 2.01 ersetzte und einen Code welche mit der LCDMenuLib 2.0 erzeugt wurde kompiliere oder muss ich den Code auf einem Beispiel der neuen LIB 2.01 erneut aufsetzen?

Also hat sich quasi in den 4 tabs (LCDML_BACKEND, DISP etc...) ebenfalls etwas entscheidendes mit der neuen LIB verändert?

Des Weiteren verstehe ich nicht ganz was ich genau in der LCDMenuLib___config für die Verwendung eines I2C Displays anpassen muss.

In einem "normalen" Code habe ich mein Display wie folgt deklariert: LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3,POSITIVE);

Ich habe wie von Jomelo beschrieben die neuste new liquid crystal lib in Verwendung und benutzte Arduino 1.6.5.

Es wäre sehr nett wenn mir hier jemand weiterhelfen könnte.

Vielen vielen Dank im Voraus.

Viele Grüße

Olli