M2tklib , more sub menus - how ?

Hi all !

I've got a m2tklib menu working on 128x64 GLCD . I'm using X2LMENU element to get menu structure like in an example to change about 10 variables. But now I need more sub-menus - something like this :

MENU_1 
         *SUB_MENU_A
         *SUB_MENU_B
                     - SUB_MENU_B_1
                           [change var_1]
                           [change var_2]
                     - SUB_MENU_B_2
                           [change var_3]
                           [change var_4]
         *SUB_MENU_C
                      - SUB_MENU_C_1
                      - SUB_MENU_C_2
MENU_2
            *.......
            *.......

I just can't get the " SUB_MENU_B_1 and SUB_MENU_B_2 " part working ...
I'm experimenting with m2_SetRoot funktion but without any luck .
Could anyone give me some ideas where to start , please ? Thank you in advance ! :slight_smile:

Hi

Have a look at the rapunzel example. It has a very simple toplevel menu. Beyond this you can Use the two different X2LMENUs. This will give you 3 levels. In fact you could compose as many levels as you want with the menu style, used in the "rapunzel" example.

Oliver

Oliver, thank you so much for your great work. This library is very powerfull tool. And thank you for your help with my "problem" but I must say I'm more lost now ... I've got lots of your egzamples working, I modified them to suit mu needs but this little task is over my head - I think I need hollidays :slight_smile:
Ok.. I'll try to manage it somehow. Thank you again ! :slight_smile:

ok, then please let me know if there are further questions.
But in order to clarify things a little bit:
There are two types of nested menues:

  1. Nested menues, where more than one level is visible (This includes the X2LMENU). This is currently limited to 2 levels only. A single m2tklib element handles everything.
  2. Nested menues, where the user only sees the "current" menu level. This allows unlimited nesting with unlimited depth of nested menues. Such menues are composed of several atomic m2tklib elemens, such as M2_ROOT and M2_GRIDLIST (or other container elements).

This is a typical menu composed of M2_ROOT and M2_VLIST:

/* each menu line is defined by a M2_ROOT element */
/* in this example, all four menues refer to the same submenu: top_el_vlist_submenu */
M2_ROOT(el_vlistmm_m1, NULL, "Menu 1", &top_el_vlist_submenu1);
M2_ROOT(el_vlistmm_m2, NULL, "Menu 2", &top_el_vlist_submenu2);
M2_ROOT(el_vlistmm_m3, NULL, "Menu 3", &top_el_vlist_submenu3);
M2_ROOT(el_vlistmm_m4, NULL, "Menu 4", &top_el_vlist_submenu4);

/* all menu lines are grouped by a vlist element */
M2_LIST(list_vlistmm) = { &el_vlistmm_m1, &el_vlistmm_m2, &el_vlistmm_m4, &el_vlistmm_m4 };
M2_VLIST(el_vlistmm_list, NULL, list_vlistmm);

/* center the menu on the display */
M2_ALIGN(top_el_vlist_mainmenu, "-1|1W64H64", &el_vlistmm_list);

Only the toplevel menus are visbile (one toplevel entry per line).
Each of the four toplevel entries refer to another submenu.
Submenues are defined like this:

/* each menu line is defined by a M2_ROOT element */
M2_ROOT(el_vlistsum_m1, NULL, "Sub-Menu 1", ...);
M2_ROOT(el_vlistsum_m2, NULL, "Sub-Menu 2", ...);
M2_ROOT(el_vlistsum_m3, NULL, "Sub-Menu 3", ...);
/* all menu lines are grouped by a vlist element */
M2_LIST(list_vlistsum) = { &el_vlistsum_m1, &el_vlistsum_m2, &el_vlistsum_m3, &el_vlistsum_m4 };
M2_VLIST(el_vlistsum_list, NULL, list_vlistsum);
/* center the menu on the display */
M2_ALIGN(top_el_vlist_submenu1, "-1|1W64H64", &el_vlistsum_list);

But again: First the user will only see "Menu 1", "Menu 2", ...
Once Menu 1 is selected, the user will see "Sub-Menu 1", Sub-Menu 2", ...
This is different to X2LMENU whre both levels are always visible.

Oliver

Ahhh.. And now it make sense! I don't know why, but I was trying to achieve what I want only by X2LMENU! I thought that this will give me deeper sub menu structure. I'm going to try your suggestions after work and for now - thank you again! You're a legend :slight_smile:

let me know if you have further questions.

Oliver

Oliver - those two examples - do they supposed to "work" together ? I'm trying to combine them together but I'm getting nowhere.. I'm getting errors or , after succesfull compilation and writing to flash - arduino hangs. This might be simple but I just can't see it ...

I've searched for working menu that we are talking about but - no luck. I don't want to ask you but... i really want to learn how to use your library and examples are the best way for me. Thank you so much for giving a hand to a newbie :slight_smile:

You could post your code and i can check what is missing or wrong.

You could also describe what kind of menu you want. Based on this, we could implement something together.

Oliver

I'm trying to get something like this :

WINDOWS // Menu 1
*ALL // sub menu

  • close // change boolean varialbe
  • open // change boolean varialbe
  • set angle // set value in range 0 - 100
    button OK button cancel
  • ROOM 1 // sub menu
    *LEFT // deeper sub menu
  • close // change boolean varialbe
  • open // change boolean varialbe
  • set angle // set value in range 0 - 100
    button OK button cancel

*RIGHT // sub menu

  • close // change boolean varialbe
  • open // change boolean varialbe
  • set angle // set value in range 0 - 100
    button OK button cancel

TEMPERATURES // MENU 2
... // sub menu
....

The code I have is in mess now - I'm trying everything. I've got examples frimj library folder to work offcourse , and modify them by adding buttons I want, ways to change walues etc. But I can't workout how to add "deeper" sub menu ... ( MENU_1 -> SUB_MENU -> SUB_SUB_MENU )...

It often makes sense to do some “ascii” art.
So the “ALL” menu might look like this (correct me if i wrong).
I will use the following convention:
[000] numeric entry field (M2_U8NUM or M2_U32NUM)

First of all - thank you for reply. This make sense but my problem is different - I don’t understand the actual “programing language” needed to make menu I want. I’ll try to explain on an example what you gave me before :

Main menu :

M2_ROOT(el_vlistmm_m1, NULL, "WINDOWS", &top_el_vlist_submenu1);                    // main menu 1
M2_ROOT(el_vlistmm_m2, NULL, "TEMPERATURES", &top_el_vlist_submenu2);                   // main menu 2

M2_LIST(list_vlistmm) = { &el_vlistmm_m1, &el_vlistmm_m2, };
M2_VLIST(el_vlistmm_list, NULL, list_vlistmm);

M2_ALIGN( top_el_vlist_mainmenu, "-1|1W64H64", &el_vlistmm_list );

Now, to get a sub menu of WINDOWS :

M2_ROOT( top_el_vlist_submenu1, NULL, "ALL", &el_vlist_subsub1 );
M2_ROOT( top_el_vlist_submenu2, NULL, "ROOM 1", &el_vlist_subsub2 );

M2_LIST(list_vlistsum) = { &top_el_vlist_submenu1, &top_el_vlist_submenu2 };
M2_VLIST(el_vlistsum_list, NULL, list_vlistsum);

M2_ALIGN( top_el_vlist_submenu1, "-1|1W64H64", &el_vlistsum_list);

And another level - submenu for ALL :

M2_ROOT( el_vlist_subsub1, NULL, "CLOSE", & ?????????????);
M2_ROOT( el_vlist_subsub2, NULL, "OPEN", & ???????????? );

M2_LIST(list_vlistsum_sub) = { &el_vlist_subsub1, &el_vlist_subsub2 };
M2_VLIST(el_vlistsum_sub_list, NULL, list_vlistsum_sub);

M2_ALIGN(el_vlist_subsub1, "-1|1W64H64", &el_vlistsum_sub_list);

Is this correct? What the last sub menu ( CLOSE and OPEN ) should refer to ( part with question marks ??? ) a NULL element ( &m2_null_element ) ? What have to be put in forward declariation ? I can design different layouts of menu, but first I need to understand the basic relations beetween elements and I just can’t get it from library examples and library wiki page … I’m sorry for bothering you with so simple questions …

PS ( I can’t test this code at the moment - It’s just a “concept” so sorry for bad naming , I hope you’ll get my “point”)

// ADDED

I think I catched my mistake : M2_ROOT element shouldn’t refer to another M2_ROOT element but to a VLIST containing more M2_ROOT elements in this case , am I right ? Is forward declaration ok ?

#include <stdlib.h>
#include "U8glib.h"
#include "M2tk.h"
#include "utility/m2ghu8g.h"

U8GLIB_KS0108_128 u8g(5, 6, 7, 8, 9, 10, 11, 12, 4, 13, A0, 2, 3, A1);         // LCD pins

uint8_t uiKeyUpPin = A2;
uint8_t uiKeyDownPin = A3;
uint8_t uiKeySelectPin = A4;
uint8_t uiKeyExitPin = A5;

//=================================================
// Forward declaration of the toplevel element
M2_EXTERN_VLIST(windows_sub);
M2_EXTERN_VLIST(el_vlistmm_list);
M2_EXTERN_VLIST(temperature_sub);
M2_EXTERN_VLIST(el_all_submenu);
M2_EXTERN_VLIST(el_room_submenu );
//=================================================

M2_ROOT(el_windows, NULL, "WINDOWS", &windows_sub);                      // main menu 1
M2_ROOT(el_temperature, NULL, "TEMPERATURES", &temperature_sub);         // main menu 2
M2_LIST(list_vlistmm) = { &el_windows, &el_temperature, };
M2_VLIST(el_vlistmm_list, NULL, list_vlistmm);
M2_ALIGN( top_el_vlist_mainmenu, "-1|1W64H64", &el_vlistmm_list );

M2_ROOT( el_all, NULL, "ALL", &el_all_submenu );                        // sub menu for WINDOWS
M2_ROOT( el_room_1, NULL, "ROOM 1", &el_room_submenu );
M2_LIST(list_vlistsum) = { &el_all, &el_room_1 };
M2_VLIST(windows_sub, NULL, list_vlistsum);
M2_ALIGN( windows_sub_aligned, "-1|1W64H64", &windows_sub);

M2_ROOT( el_close, NULL, "CLOSE", &m2_null_element );                   // deeper sub menu for ALL
M2_ROOT( el_open, NULL, "OPEN", &m2_null_element );
M2_LIST(list_vlistsum_all) = { &el_open, &el_close };
M2_VLIST(el_all_submenu, NULL, list_vlistsum_all);
M2_ALIGN( al_sub_aligned, "-1|1W64H64", &el_all_submenu);

M2_ROOT( el_close_room, NULL, "CLOSE", &m2_null_element );             // deeper sub menu for ROOM 1
M2_ROOT( el_open_room, NULL, "OPEN", &m2_null_element );
M2_LIST(list_vlistsum_room) = { &el_open_room, &el_close_room };
M2_VLIST(el_room_submenu, NULL, list_vlistsum_room);
M2_ALIGN( all_sub_aligned, "-1|1W64H64", &el_all_submenu);


M2_ROOT( el_wyswietl, NULL, "Wyswietl", &m2_null_element );           // sub menu for TEMPERATURES
M2_ROOT( el_ustaw, NULL, "Ustaw", &m2_null_element );
M2_LIST(list_temp) = { &el_wyswietl, &el_ustaw };
M2_VLIST(temperature_sub, NULL, list_temp);
M2_ALIGN( temp_sub_aligned, "-1|1W64H64", &windows_sub);
//=================================================

M2tk m2(&el_windows, m2_es_arduino, m2_eh_4bs, m2_gh_u8g_ffs);

void draw(void) {
  m2.draw();
}

void setup(void) {
  // Connect u8glib with m2tklib
  m2_SetU8g(u8g.getU8g(), m2_u8g_box_icon);

  // Assign u8g font to index 0
  m2.setFont(0, u8g_font_6x13r);

  // Assign icon font to index 3
  m2.setFont(3, u8g_font_m2icon_7);

  // Setup keys
  m2.setPin(M2_KEY_SELECT, uiKeySelectPin);
  m2.setPin(M2_KEY_PREV, uiKeyUpPin);
  m2.setPin(M2_KEY_NEXT, uiKeyDownPin);
  m2.setPin(M2_KEY_EXIT, uiKeyExitPin);
}

void loop() {
  // menu management
  m2.checkKey();
  if ( m2.handleKey() != 0 ) {
    u8g.firstPage();
    do {
      m2.checkKey();
      draw();
    } while ( u8g.nextPage() );
  }
}

How’s that ? This code compiles without any error but it’s not tested - I will try it this evening but now I just want to now if my thinking is right. Later I can add buttons, callbacks and change layout.

I've got it working with the above code.. well.. sort of. Menu is displayed in left , bottom corner and only WINDOWS menu and it's sub menu are visible. And when i click on last sub menu ( CLOSE or OPEN ) i get blank screen from I cannot go back - but this is because i used NULL element there . But this makas me thinking - how can I get ESCAPE button ( aktual button connected to arduino ) to go back one level up ? I know i can create screen button for this, but would be nice to have phisical button for this.

So, to do list is :

-Center the whole menu at top center

  • make labels in each sub menu so i can see where am i in menu
  • create buttons and callbacks for them
  • make exit button work .

But I'm happy I got menu structure I wanted ( after many hours of starring at every example and library wiki ) :slight_smile:

ADDED :

All sub menus are visible. But I'm having problem with aligment. On top of each menu and sub menu I've added a LABEL. First label is aligned properly. But every next label ( in sub menus ) is displayed lower and lower , and sub menus are still i left bottom corner - I'm trying diferrent options but no joy . I want all labels to be allways on top , and sub menu option to be centered - now they are aligned to right ( I've tried modyfying the format string for ALIGN ) .

First of all, let me say that you make real good progress. I know it is somehow difficult to understand the concept, but i think you got the idea already.

M2_ROOT:
Yes, it usually referes to a VLIST or ALIGN element. In fact it should refer to some toplevel element. Usually a dialog box looks like this:
ALIGN contains VLIST or GRIDLIST, which contain atomic elements like ROOT or BUTTON. Of course, for more complex dialog boxes, VLIST/HLIST/GRIDLIST can be nested with each other. So M2_ROOT refers to the ALIGN element.

So let me have a look at your top level menu:

M2_ROOT(el_vlistmm_m1, NULL, "WINDOWS", &top_el_vlist_submenu1);                    // main menu 1
M2_ROOT(el_vlistmm_m2, NULL, "TEMPERATURES", &top_el_vlist_submenu2);                   // main menu 2
M2_LIST(list_vlistmm) = { &el_vlistmm_m1, &el_vlistmm_m2, };
M2_VLIST(el_vlistmm_list, NULL, list_vlistmm);
M2_ALIGN( top_el_vlist_mainmenu, "-1|1W64H64", &el_vlistmm_list );

A classical menu with two entries. The two ROOT elements will directly jump to a different menu/dialogbox, which are given as "top_el_vlist_submenu1" and "top_el_vlist_submenu2"

One of your question was: How to jump back. There is no concept of "jumping back". Instead you need to add a ROOT element in the submenu, which jumps back to the previous/top level menu.
So in "top_el_vlist_submenu1" you may want to jump back to "top_el_vlist_mainmenu". This is obviously done by:
M2_ROOT(el_back_to_top, NULL, "MAIN MENU", &top_el_vlist_mainmenu);

Let me apply this to your WINDOWS Menu:

M2_ROOT( top_el_vlist_submenu1, NULL, "ALL", &el_vlist_subsub1 );
M2_ROOT( top_el_vlist_submenu2, NULL, "ROOM 1", &el_vlist_subsub2 );
M2_ROOT(el_back_to_top, NULL, "MAIN MENU", &top_el_vlist_mainmenu);

M2_LIST(list_vlistsum) = { &top_el_vlist_submenu1, &top_el_vlist_submenu2, &el_back_to_top };
M2_VLIST(el_vlistsum_list, NULL, list_vlistsum);

M2_ALIGN( top_el_vlist_submenu1, "-1|1W64H64", &el_vlistsum_list);

However there are some mistakes in your code.
First: Each element name (first argument) must be unique. So the two ROOT elements need to be renamed. Same applies to LIST and VLIST.

M2_ROOT( el_root_all, NULL, "ALL", &el_vlist_subsub1 );
M2_ROOT( el_root_room1, NULL, "ROOM 1", &el_vlist_subsub2 );
M2_ROOT(el_back_to_top, NULL, "MAIN MENU", &top_el_vlist_mainmenu);

M2_LIST(list_windows) = { &el_root_all, &el_root_room1, &el_back_to_top };
M2_VLIST(el_windows_vlist, NULL, list_windows);

M2_ALIGN( top_el_vlist_submenu1, "-1|1W64H64", &el_windows_vlist);

Then there is another problem, that needs to be solved. Now, your WINDOWS menu refers to the MAIN MENU und the MAIN MENU refers to the WINDOWS menu. Since there is a sequencial list of menu definitions, one of the menus need to defined first and will lead to an error (undeclared identifier or something) when refering to the later menu.

Solution is to add a "extern" declaration, which does not define the menu, but makes it available for use before the actual definition.
In your case, you need to use:
M2_EXTERN_ALIGN(top_el_vlist_mainmenu);
So to complete the WINDWOS menu, it should look like this:

M2_EXTERN_ALIGN(top_el_vlist_mainmenu);  // forward declaration


M2_ROOT( el_root_all, NULL, "ALL", &el_vlist_subsub1 );
M2_ROOT( el_root_room1, NULL, "ROOM 1", &el_vlist_subsub2 );
M2_ROOT(el_back_to_top, NULL, "MAIN MENU", &top_el_vlist_mainmenu);

M2_LIST(list_windows) = { &el_root_all, &el_root_room1, &el_back_to_top };
M2_VLIST(el_windows_vlist, NULL, list_windows);

M2_ALIGN( top_el_vlist_submenu1, "-1|1W64H64", &el_windows_vlist);

// code for "top_el_vlist_mainmenu" will follow here 
// ...

Another question is related to OPEN and CLOSE. First you should be clear, what exactly should happen here.
Let me assume, you want to open and close a window.
Independently from M2tklib, you will need a state machine for the window (for each window if there are more windows).
The state machine will have more than just the two states OPEN and CLOSE, thare are also: OPENING and CLOSING, which usually refere to some engines which perform the opening and closing of the windows. So the transitions of the state machine are:

OPEN --> CLOSING
CLOSING --> CLOSE
CLOSE --> OPENING
OPENING --> OPEN
Of course there might be more transitions, like
CLOSING --> OPENING
if you change your mind during closing.

Leaving a state depends on several conditions. Leaving "CLOSING" state and entering "CLOSE" state usually is done if some sensor detects, that the window is closed.

After this short discussion of some independet state machine, here is the connection to M2tklib: It can serve as a trigger to leave the OPEN state of the "CLOSE" menu is pressed. For example the CLOSE menu may do this:

  1. Check if the window is open and the state is OPEN
  2. Start the engine to close the window
  3. move the state of the state machine above to CLOSING

All in all you may want to use M2_BUTTON instead of M2_ROOT, because M2_BUTTON allows you to attach a procedure which in turn can contain any advice to your actors and state machines.

To complete the discussion on state machines and M2tklib, please have a look at tutorial 5 (Google Code Archive - Long-term storage for Google Code Project Hosting.). It partly repeats what i wrote here. Especially have a look at the STOP state and how M2tklib starts and stops the state machine.

So, i hope i answered these two questions:

  • create buttons and callbacks for them
  • make exit button work .

For CLOSE and OPEN, consider buttons and callbacks, for the exit button use M2_ROOT to the main menu (or previous menu)

-Center the whole menu at top center

Instead of
M2_ALIGN( top_el_vlist_submenu1, "-1|1W64H64", &el_windows_vlist);
use
M2_ALIGN( top_el_vlist_submenu1, "-1|2W64H64", &el_windows_vlist);
as described in the reference manual.

  • make labels in each sub menu so i can see where am i in menu

Here is a simple solution:

M2_LABEL(el_vlistmm_label, NULL, "MAIN MENU");
M2_ROOT(el_vlistmm_m1, NULL, "WINDOWS", &top_el_vlist_submenu1);                    // main menu 1
M2_ROOT(el_vlistmm_m2, NULL, "TEMPERATURES", &top_el_vlist_submenu2);                   // main menu 2
M2_LIST(list_vlistmm) = { &el_vlistmm_label, &el_vlistmm_m1, &el_vlistmm_m2 };
M2_VLIST(el_vlistmm_list, NULL, list_vlistmm);
M2_ALIGN( top_el_vlist_mainmenu, "-1|1W64H64", &el_vlistmm_list );

hope, i got all your questions answered.

Oliver

All sub menus are visible. But I'm having problem with aligment. On top of each menu and sub menu I've added a LABEL. First label is aligned properly. But every next label ( in sub menus ) is displayed lower and lower , and sub menus are still i left bottom corner - I'm trying diferrent options but no joy . I want all labels to be allways on top , and sub menu option to be centered - now they are aligned to right ( I've tried modyfying the format string for ALIGN ) .

Not sure if i understand this correctly. Maybe you can post your code. Of course now you are more talking about beautification than concept. In general, try to use the format options instead of M2_ALIGN: For example "f8W64" will center the BUTTON/ROOT/LABEL in your display (https://code.google.com/p/m2tklib/wiki/elref#Fonts). You may think about adding some space (M2_SPACE) between label and menu entries. Then you may also consider to use M2_XYLIST instead of M2_VLIST, which gives you full controll on any element. Disadvantage is, you need to provide the xy position of each element.

Oliver

Oliver, thank you again for complete explanation ! All infos are verry welcome :slight_smile:

Well, I think i got everything working as I wanted. Closing and opening windows is not a problem - this is runnig allready for 24 huge windows ( 150 meters long , 3kW 3 phase motors for each window ) in greenhouses. State of each window is defined by limit switches and MPU5060 gyro , mounted on each window to give me accurate angle. Then there are 17 pumps, 3 huge furnaces , CO2 level measuring, 6 motorised shades for each greenhouse ( 1,5kW motors ) and some temperatures - 36 in total :slight_smile: Some features are available from internet and GSM modem. Ewerything is working and I had "nice " menu done with ..... switch -case statements and if - elses :wink: but It was pain in **** to change anything or add more features.

As for aligment - got XYLIST instead - little bit of tweaking and things are looking good. Offcourse code I posted was simplified - now I've added buttons , labels , num field etc . But one thing is still in my mind - there is reference to exit button. And it woudl be really nice, to have a phisical button to jump back one level .. Is is possible ?

Code , more or less looks like this for now as I'm still working and adding more features :

// Forward declaration of the toplevel element
M2_EXTERN_XYLIST(windows_sub);
M2_EXTERN_XYLIST(el_vlistmm_list);
M2_EXTERN_XYLIST(temperature_sub);
M2_EXTERN_XYLIST(el_all_submenu);
M2_EXTERN_XYLIST(el_okna_l_submenu );
M2_EXTERN_XYLIST(el_okna_p_submenu );
//=================================================

M2_LABEL(el_etykieta_menu, "b1,f12,w128", "- MENU -");
M2_SPACE(el_space, "w128h2");
M2_ROOT(el_windows, NULL, " OKNA ", &windows_sub);                      // main menu 1
M2_ROOT(el_temperature, NULL, " TEMPERATURY ", &temperature_sub);         // main menu 2
M2_LIST(list_vlistmm) = { &el_etykieta_menu,&el_space,&el_windows, &el_temperature, };
M2_VLIST(el_vlistmm_list, NULL, list_vlistmm);
M2_ALIGN( top_el_vlist_mainmenu, "1|2W64H64", &el_vlistmm_list );

M2_LABEL(el_etykieta_okna, "x0y49b1,f12,w128", "MENU -> OKNA");
M2_ROOT( el_all, "x5y25", "WSZYSTKIE", &el_all_submenu );                        // sub menu for WINDOWS
M2_ROOT( el_okna_l, "x45y25", "LEWE", &el_okna_l_submenu );
M2_ROOT( el_okna_p, "x85y25", "PRAWE", &el_okna_p_submenu );
M2_LIST(list_vlistsum) = {&el_etykieta_okna, &el_all, &el_okna_l, &el_okna_p };
M2_XYLIST(windows_sub, NULL, list_vlistsum);

M2_LABEL(el_etykieta_wszystkie, "x0y49b1,f12,w128", "OKNA -> WSZYSTKIE");
M2_ROOT( el_close, "x10y25", "ZAMKNIJ", &el_windows );                   // deeper sub menu for ALL
M2_ROOT( el_open, "x70y25", "OTWORZ", &el_windows );
M2_LIST(list_vlistsum_all) = {&el_etykieta_wszystkie, &el_open, &el_close };
M2_XYLIST(el_all_submenu, NULL, list_vlistsum_all);

M2_LABEL(el_etykieta_lewe, "x0y49b1,f12,w128", "OKNA -> LEWE");
M2_ROOT( el_close_okna_l, "x10y25", "ZAMKNIJ", &el_windows );             //  Kontrola okien lewych
M2_ROOT( el_open_okna_l, "x70y25", "OTWORZ", &el_windows );
M2_LIST(list_okna_l) = { &el_etykieta_lewe, &el_open_okna_l, &el_close_okna_l };
M2_XYLIST(el_okna_l_submenu, NULL, list_okna_l);

M2_LABEL(el_etykieta_prawe, "x0y49b1,f12,w128", "OKNA -> PRAWE");
M2_ROOT( el_close_okna_p, "x10y25", "ZAMKNIJ", &el_windows );             //  Kontrola okien prawych
M2_ROOT( el_open_okna_p, "x70y25", "OTWORZ", &el_windows );
M2_LIST(list_okna_p) = { &el_etykieta_prawe, &el_open_okna_p, &el_close_okna_p };
M2_XYLIST(el_okna_p_submenu, NULL, list_okna_p);


M2_ROOT( el_wyswietl, NULL, "Wyswietl", &m2_null_element );           // sub menu for TEMPERATURES
M2_ROOT( el_ustaw, NULL, "Ustaw", &m2_null_element );
M2_LIST(list_temp) = { &el_wyswietl, &el_ustaw };
M2_VLIST(temperature_sub, NULL, list_temp);
M2_ALIGN( temp_sub_aligned, "1|2W64H64", &temperature_sub);
//=================================================

M2tk m2(&top_el_vlist_mainmenu, m2_es_arduino, m2_eh_4bs, m2_gh_u8g_ffs);

Well, there is no back/exit button, but you can make one phys. button be the “Home” key and jump to a predefined toplevel menu.
Use setHome (https://code.google.com/p/m2tklib/wiki/fnref#setHome) to define the toplevel menu, which should be called once the Home key is pressed.
Use setPin(M2_KEY_HOME, ) to connect a physical button at the given pin with the KEY_HOME event.

All in all i am glad, that you managed to setup the menu so quickly.I guess, that building such a greenhouse takes much more time…

Oliver

I see. I'll try to do something witch this button - thank you for hint ! :slight_smile:

I was trying to understand general concept of your library. For many, many day. Reading, searching ... And sudenly, after your explanations, everything became so clear :slight_smile: It's so much easie to do menus thi way !

I've build few controls based on AVR for greenhouses and houses. The oldest is working for 2 years , 24/7 . Now I got very powerfull tool - your library ! :slight_smile: I'll say it again - you're a legend and I'll contribute to your work somehow :slight_smile:

Thank you again !!!

So I've got nearly everything up and running :slight_smile: But I met some problem : following the " Graphics" example form M2tklib folder, I created a screen where I want to display some live data. It's working till I want to use the F macro on " u8g.print " statements -
with F macro in place I get error : Ster_ino:598: error: __c causes a section type conflict . Removing F macro helps, but there is many static strings to be displayed ....
How can I use F macro with M2tklib ??

Is it M2tklib or U8glib?
For U8glib, the print procedure has been derived from the Arduino Print class, so it should work. Can you post the code which produces the error?

Oliver

I'm using u8glib with m2tklib. I wanted a main screen, showing some live data outside of any menu, so I followed your example " Graphics " - and everything is working as expected. But I wanted to put many static strings in flash memory using F macro - like I allways do. But as soon as i add F macro to any of u8glib.print I get error. Full code is way to long to put here but this is the part where I'm displaying some live data when user chooses m2_null_element :

void draw_temperatury(void) {

  if ( m2.getRoot() == &m2_null_element ) {

    if ( wysylane.awaria_czujnika_1 == true )
    {
      u8g.setPrintPos(6, 8);
      u8g.setFont(u8g_font_helvB08);
      u8g.print(F("AWARIA !"));                                          // When F macro is remowed, everything is working ok
      u8g.setFont(u8g_font_timR08);
    }
    else
    {
      u8g.setFont(u8g_font_timR08);
      u8g.setPrintPos(0, 10);
      u8g.print("Tsz 1: ");
      u8g.setFont(u8g_font_6x13B);
      u8g.print(   wysylane.temp_szk_1,1);
      u8g.setFont(u8g_font_timR08);
      u8g.print("\260C");
    }
 }
}

I think there is nothing unusual in this code . It was running ok with F macro but now I'm adding menu based on m2tklib .

There is 35 static string in total - and doesn't matter where I put the F macro - I allway get this error. It's not a big problem because there is enough RAM but still would be nice to have more :slight_smile: