Go Down

Topic: Projekt: LCDMenuLib - LCD Menü mit mehreren Ebenen (4Bit/I2C/ShiftReg/...) (Read 63200 times) previous topic - next topic

flybysun

Ja, ich hab so etwas auch schon befürchtet und muss der Sache mal genauer nachgehen.
Wie siehst du das denn mit der Einbindung der Zeitabfrage? Würdest du das auch mit der Init_Screen-Funktion machen, oder doch besser über die Loop und dann über threads oder ähnlich? Wie hast du das mit den Zeiten (automatische Rückkehr zum Init_Screen) eigentlich in der lib realisiert wenn du keine Interrupts benutzt?

Was koka_tr geschrieben hat, kann ich übrigens auch bestätigen. Die LCDMenuLib ist dir wirklich sehr gut gelungen und wenn man einmal verstanden hat wie sie funktioniert, ist sie relativ einfach zu benutzen.
Für den Anfang wäre aber eine Art Ablaufplan zum Einbinden oder ein kleines Howto wirklich sehr hilfreich, da es nicht so leicht ist, sich hineinzudenken (ging mir jedenfalls so).

Aber hey, dafür ist ja das Forum da ;)

Jomelo

So,
also das Menü ist so aufgebaut, dass es nie steht und an keiner Stelle irgendwo ein "delay" verursacht. Die Funktionen die aufgerufen werden, sind in einer Variable im Hintergrund zwischengespeichert, so dass die gestartete Funktion beim nächsten Durchlauf erneut aufgerufen wird. Ein Durchlauf wird immer in der Loop Funktion gestartet mit LCDMenuLib_loop();.

Wenn nun ein Ereignis z.B. durch einen abgelaufene Zeit oder einen Taster ausgelöst wird, wird eventuell je nach Bedingung der interne Ablauf unterbrochen und die Funktion läuft noch einmal bis zur "FuncEnd" Funktion führt den enthaltenen Code aus und wird beendet.

Das ganz ist mal grob in der folgenden PDF Datei abgelegt. Vieles von den Dingen die in den Kästchenstehen laufen im Hintergrund ab und werden über Macros generiert. In der Dokumentation sind längst nicht alle Verzweigungen eingezeichnet, das benötigt eigentlich niemand. Die Dokumentation ist noch nicht komplett Vollständig. Irgendwann, wenn Zeit ist wird das weiter angepasst.


@flybysun
Ich weiß nicht genau was der beste Weg ist. Deine Zeitabfrage muss ja kontinuierlich aufgerufen werden, damit sie überprüfbar ist.

@All
Im Moment ist die Version 1.03 die neuste Version, bei dieser hat sich die Funktion des Quit Buttons leicht verändert. Um Sicherzustellen, dass der Code, der unter "FuncEnd" eingefügt wird, beendet der Quit Button nicht mehr immer direkt die gerade ausgeführte Funktion. Sollte dieses Verhalten weiterhin gewünscht sein, muss am ende jeder Funktion der folgende Code eingefügt werden:
Code: [Select]

// check if the function ends hard
  if(LCDML.FuncEndQuitButton())
  {
    // do something bevor this function is closed     
  }

Der Quellcode der in diese If Schleife eingefügt werden kann wird definitiv ausgeführt, wenn der Quit Button betätigt wird.

Download neuste Version:
https://github.com/Jomelo/LCDMenuLib/releases/tag/v1_03

Sobald die Edit Funktion im Forum wieder geht, werde ich den ersten Beitrag bearbeiten und auch die Dokumentation dort einfügen.


Djam

Hi, and thanks for the Lib, she works great with my rotary encoder + switch.

I have some question about:

-goBack function : I want return to the previous Layer when I click on the encoder Switch, that work with this function:

Code: [Select]
void FUNC_back(void)
{    
        
LCDML.FuncInit();            /* setup function */  
if( LCDML.FuncEnd(0, 1, 0, 0, 0, 0))/* (direct, enter, up, down, left, right) */
{ LCDML.goBack(); }  

    }


But I need to click two time on the switch. there's a different way to make what I want or it's not possible?


-I want to change the cursor with LCD create Char, with this one:

Code: [Select]
byte Menu_SELECT[8] = {0, 4, 6, 7, 6, 4, 0, 0};// ►

///////

lcd.createChar(2, Menu_SELECT);


If it's possible, What I must do for undefine this ligne # define _LCDMenuLib_cfg_cursor 0x7E, and replace it with my char ?

-And, I want to make something like you say HERE, but that don't work fine.
It's fine when I don't touch encoder, but when I navigate in the menu the value go anywhere..

Like This:
Code: [Select]

Humidity         xx%
xx%p. BED      xx°
XXmp. AIR      xx°

.....

 

And after three or four time I turn encoder, all disappear on the screen...

I have to change something in the lib to get this kind of thing I suppose? or it's absolutely impossible?

Something here:

Code: [Select]
#define LCDMenuLib_element(name, item_old, item_new, content, function)\
const char g_LCDMenuLib_lang_ ## name ##_var[] PROGMEM = {content};\
void function(void);\
LCDMenu item_new(name); \
void LCDMenuLib_##name##_function() { g_LCDMenuLib_functions[name] = function; item_old.addChild(item_new); }

#define LCDMenuLib_add(name, item_old, item_new, content, function)\
const char g_LCDMenuLib_lang_ ## name ##_var[] PROGMEM = {content};\
void function(void);\
LCDMenu item_old ## _ ## item_new(name); \
void LCDMenuLib_##name##_function() { g_LCDMenuLib_functions[name] = function; item_old.addChild(item_old ## _ ## item_new); }


Here the code I use:

Code: [Select]



/* include libs */
#include <LiquidCrystal.h>
#include <LCDMenuLib.h>
#include "DHT.h"

//DHT Sensor
#define DHTPIN 15
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

/* settings for lcd */
#define _LCDMenuLib_LCD_cols             20
#define _LCDMenuLib_LCD_rows             4

/* pin settings */  
#define _LCDMenuLib_LCD_rs               7
#define _LCDMenuLib_LCD_e                4
#define _LCDMenuLib_LCD_dat0             3
#define _LCDMenuLib_LCD_dat1             2
#define _LCDMenuLib_LCD_dat2             1
#define _LCDMenuLib_LCD_dat3             0
//#define _LCDMenuLib_LCD_backlight         19
//#define _LCDMenuLib_LCD_backlight_pol     POSITIVE // NEGATIVE

/* lib config */
#define _LCDMenuLib_cfg_initscreen       0      /* 0=disable, 1=enable */
#define _LCDMenuLib_cfg_initscreen_time  0      /* 0=time disabled, >0 wait time in ms */
#define _LCDMenuLib_cfg_scrollbar 0      /* 0=no scrollbar, 1=complex scrollbar, 2=easy scrollbar */
#define _LCDMenuLib_cfg_lcd_standard 0      /* 0=HD44780 standard / 1=HD44780U standard */
#define _LCDMenuLib_cfg_press_time       200    /* button press time in ms */
#define _LCDMenuLib_cnt    19  
/* init lcdmenulib */
LCDMenuLib_init(_LCDMenuLib_cnt);

#define ENC_CTL DDRB
#define ENC_WR PORTB
#define ENC_RD PINB
volatile uint16_t counter=0;
int ENC_SW = 14;

/* LCDMenuLib_element(id, prev_layer_element, new_element_num, lang_string, callback_function) */
LCDMenuLib_add(0  , root         , 1  , "Humidity"           , FUNC_information);
LCDMenuLib_add(1  , root         , 2  , "Temp. AIR"          , FUNC_p2);
LCDMenuLib_add(2  , root         , 3  , "Temp. BED"          , FUNC);
LCDMenuLib_add(3  , root         , 4  , "Fan Speed"          , FUNC);
LCDMenuLib_add(4  , root         , 5  , "Configuration"      , FUNC);
LCDMenuLib_add(5  , root_5       , 1  , "Set PID BED"        , FUNC);
LCDMenuLib_add(6  , root_5_1     , 1  , "Set PID BED"        , FUNC);
LCDMenuLib_add(7  , root_5_1     , 2  , "KP"                 , FUNC);
LCDMenuLib_add(8  , root_5_1     , 3  , "KI"                 , FUNC);
LCDMenuLib_add(9  , root_5_1     , 4  , "KD"                 , FUNC);
LCDMenuLib_add(10 , root_5_1     , 5  , "Back"               , FUNC_back);
LCDMenuLib_add(11 , root_5       , 2  , "Set PID Humidity"   , FUNC);
LCDMenuLib_add(12 , root_5_2     , 1  , "Set PID Humidity"   , FUNC);
LCDMenuLib_add(13 , root_5_2     , 2  , "KP"                 , FUNC);
LCDMenuLib_add(14 , root_5_2     , 3  , "KI"                 , FUNC);
LCDMenuLib_add(15 , root_5_2     , 4  , "KD"                 , FUNC);
LCDMenuLib_add(16 , root_5_2     , 5  , "Back"               , FUNC_back);
LCDMenuLib_add(17 , root_5       , 3  , "Sampling Interval"  , FUNC);//Fonction Réglage intervalle sauvegarde donné sur SD
LCDMenuLib_add(18 , root_5       , 4  , "Set CLOCK"          , FUNC);//Fonction Réglage Heure
LCDMenuLib_add(19 , root_5       , 5  , "Back"               , FUNC_back);
LCDMenuLib_createMenu(_LCDMenuLib_cnt);


void setup()
{    
LCDMenuLib_setup(_LCDMenuLib_cnt);  
PCMSK0 |= (( 1<<PCINT0 )|( 1<<PCINT1 ));
PCICR |= ( 1<<PCIE0 );
PCMSK1 |= ( 1<<PCINT8 );
PCICR |= ( 1<<PCIE1 );  
dht.begin();
}

void loop()
{  
  int Temperature = dht.readHumidity();
  LCDMenuLib_loop();
}


ISR(PCINT0_vect)
{
static uint8_t old_AB = 3;
uint8_t encport;
uint8_t direction;
static const int8_t enc_states [] PROGMEM = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
old_AB <<=2;
encport = ENC_RD & 0x03;
old_AB |= encport;
direction = pgm_read_byte(&(enc_states[( old_AB & 0x0f )]));
if( direction && ( encport == 3 )) {
  if( direction == 1 ) {
    LCDML.Button_up_down_left_right(_LCDMenuLib_button_up);
    }else{
    LCDML.Button_up_down_left_right(_LCDMenuLib_button_down); }
  }
}

ISR (PCINT1_vect)
{
 if(digitalRead(ENC_SW)== LOW) {
    LCDML.Button_enter();
   }
}


And here the Loop to display some info in the Menu first layer, and doesn't work

Code: [Select]
void loop()
{  
  int Humidity = dht.readHumidity();
  int Temp_DHT = dht.readTemperature();
  LCDMenuLib_loop();
  if(LCDML.getLayer() == 0){
  lcd.setCursor(15,0);
  lcd.print(Humidity);
  lcd.setCursor(15,1);
  lcd.print(Temp_DHT);
  }
}


PS Sorry My very very bad english, and for my total ignorance of the German language (and maybe about arduino ^^)
By the way, Thank for your answer (if you understand me....)

++

Go Up