u8glib and M2tklib, showing a menu on button press..

how can i make the menu appear by button press?

i have the "main" window with temperature, humidity, soil moisture and the current time...

i want to be able to set a few things:

  • Temperature Goal
  • Humidity Goal
  • Milliliters per day
  • Start Date

How can i invoke a M2tklib menu?

Hi

This is discussed here: Google Code Archive - Long-term storage for Google Code Project Hosting.. The trick will be to provide a "m2_null_element" as root object for the M2tk constructor.

Implement your "main" window as "direct graphics output" for U8glib. While displaying this "main" window, check for keys as described in the above link. Then set your meno via "setRoot" command.

Oliver

Thank you, that got it working!
But now i'm facing more trouble, gridlist isn't scrolling, i've added 5 items + two buttons and my screen isn't big enough, how can i fix this?

how can i fix this?

This is an embedded system and resources are limited. As a result also libs are limited to fit into the small amount of RAM and ROM. So, all of the container elements can not scroll. This includes gridlist. The art of embedded systems programming includes finding a "good enough" solution, that still fits, this includes:

  • use a larger display
  • use smaller fonts (so that you get more lines or coloumns)
  • reduce spacing between the cells (Google Code Archive - Long-term storage for Google Code Project Hosting.)
  • change menu structure by introducing another menu level: Two buttons from which you jump to three and two more buttons
  • use "strlist", which is scrollable. It behaves like a 1 x n (e.g. 1.x5) gridlist of buttons.

Oliver

Okay, so i'm dropping combining graphics with m2tklib, but, how can i make a status screen then?
It should show the current time and some other variables like current temperature, air humidity, soil humidity and fan speeds etc.

Okay, so i'm dropping combining graphics with m2tklib, but, how can i make a status screen then?

I would say this: M2tklib is a strong library to enter data and menus. It is not a perfect solution to display something. If you only need to display something, you do not need M2tklib.

What about this: Make a list of all the sensor values you want to display. Combine these value onto groups which fit on one graphics pages. Maybe you will end up with 3 different pages of sensor values.
Initially you will display page 1. If the user presses a button, then display page 2. Another button press, display page 3. With one more button press, page 1 again will be visible.

Still you can combine this with M2tklib. A second button will bring you to M2tklib. For example if you want to display the time, then it might be required, that the user enters the time zone. This could be handled by m2tklib. Once this information is given from the user, m2tklib can jump back to the sensor pages.

Oliver

I'm having a lot of trouble with my current code:

https://github.com/iSDP/SpaceBucketArduinoController/blob/8be63574e1f2f46106dcd3d014229f63abb40090/brains/brains.ino

draw_info() is the part where i draw the info...

Without knowing what you mean by "trouble" it is difficult to make any suggestions.
However, what i see, is that you could optimize the code a little bit by better using the snprintf fomat options (if this is available with your implementation of snprintf).

printf("%d", 12) --> 12
printf("%d", 3) --> 3

printf("%02d", 12) --> 12
printf("%02d", 3) --> 03

where "0" tells printf to precede the number with "0" if required
and
2 tells printf the minimal number of digits to use.

Oliver

I mean showing multiple graphics screens, like a screen for temperature and humidity info, a screen for soil info and a screen for an overview :slight_smile:

And temperature and humidity gets updated every x minutes, and the soil info only daily.

i want to have a button on those two screens to update the values and the last time it refreshed.

Also an overview with a clock on it, so that needs to update every second...

Somehow, this seems to be very difficult for me, especially following the tutorial on Google Code Archive - Long-term storage for Google Code Project Hosting.

Do you have any tips and pointers?

Do you have any tips and pointers?

I quote myself from above:

M2tklib is a strong library to enter data and menus. It is not a perfect solution to display something. If you only need to display something, you do not need M2tklib.

What about this: Make a list of all the sensor values you want to display. Combine these value onto groups which fit on one graphics pages. Maybe you will end up with 3 different pages of sensor values.
Initially you will display page 1. If the user presses a button, then display page 2. Another button press, display page 3. With one more button press, page 1 again will be visible.

Your additional requirement, that the values needs to be updated more often, is independent. Just let u8glib refresh the current page every second.

Oliver

But how do i switch graphics pages?

hmmm... Not sure if this is what you need, but maybe take a look at the "GraphicsTest" example of u8glib.

Oliver

I'm running into a multitude of issues at the moment...

I have to do stuff simultaneously and currently it's blocking....

Would you have time to possibly rewrite my code so that it will work?

I have 0 experience with Mt2klib....

The code can be found in my Github, you would be helping the project forward a lot! :slight_smile:

Would you have time to possibly rewrite my code so that it will work?

I can try to make some suggestions. But it will be your task to implement this.

Currently, this is a little part of your code:

void draw_graphics(void) {
  if ( m2.getRoot() == &m2_null_element ) {
    draw_info();
  }
}

If i remember correctly, you want to draw different pages with information. Step 1 is to split draw_info() into different pages, say:
draw_info_0(), draw_info_1(), draw_info_2().

Step 2, is to introduce a new variable "uint8_t info_page", which will select the info page. It could be implemented like this:

uint8_t info_page = 0;

void draw_graphics(void) {
  if ( m2.getRoot() == &m2_null_element ) {
    switch(info_page) {
       case 0: draw_info_0(); break;
       case 1: draw_info_1(); break;
       case 2: draw_info_2(); break;
    }
  }
}

At the moment you will return immediatly from the info page to your main menu. Your code looks like this:

uint8_t update_graphics(void) {
  if ( m2.getRoot() == &m2_null_element ) {
    if ( m2.getKey() != M2_KEY_NONE )
      m2.setRoot(&top_el_expandable_menu);
    return 1;
  }
  return 0;
}

But additionally, you now want to switch between different pages, that means the new variable "info_page" must be modified to cycle between the three pages. You could do this (again modifiing your exisiting code):

uint8_t update_graphics(void) {
  uint8_t key;
  if ( m2.getRoot() == &m2_null_element ) {
   key =  m2.getKey();   // call getKey only once, because key is removed from the queue
    if ( key != M2_KEY_NONE ) {
       if ( key == M2_KEY_SELECT ) {
        info_page++;
        if ( info_page >= 3 )
          info_page = 0;
       }
       else {
        m2.setRoot(&top_el_expandable_menu);
       }
      }
    }
    return 1;
  }
  return 0;
}

Of course it is not tested, but i hope you understand the concept and i am sure that you can implement this.

If you have other questions on M2tklib, please ask.

Oliver

And how do I prevent the code in loop() to block the rest of my application?

What is the actual code which blocks your loop()?

Oliver

I suspect the code for the temperature and fan speed control...

Of course i can support you in reviewing u8glib and m2tklib related code, but maybe the programming subforum is better for generic review request. However it looks like, you completly block loop() if temperature is below 20. And also avoid any call to "delay()"

      do
    {
      /* ... */
      temperature = DHT.temperature;
      /* ... */
      delay(10000);
    }
    while( temperature < 20);

Oliver