Go Down

Topic: OpenMoCo Menu Manager - completely automated menus for Arduino (Read 37356 times) previous topic - next topic

Watcher

This is obviously an old thread.
However, does anyone know how to use serial I2C  graphic LCDs with these libraries.
I was going through the examples of m2tklib and it seems it only supports parallel LCDs.

Any help would be greatly appreciated.

Thanks



kallek

However, does anyone know how to use serial I2C  graphic LCDs with these libraries...
Hi.
I am using the "New LiquidCrystal" library (https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home) and OMMenuMgr with character LCD connected to I2C bus via PCF8574* expansion board.

The meny library does not draw the characters on the LCD screen but calls your method. If your LCD library is standard LiquidCrystal compatible then the included example should work (check out the uiDraw and uiClear functions there).

Kalle

dnc40085

Hello,
    I have downloaded this library to add a menu system to my project and when I went to compile the example I get the following errors:

Quote
example.ino:55:19: error: variable 'sel_ign' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:56:19: error: variable 'sel_on' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:57:19: error: variable 'sel_off' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:59:30: error: variable 'state_list' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:64:13: error: variable 'state_select' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:69:12: error: variable 'foo_value' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:70:12: error: variable 'bar_value' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:71:12: error: variable 'baz_value' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:72:12: error: variable 'bak_value' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:73:12: error: variable 'sel_value' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:76:11: error: variable 'item_checkme' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:77:11: error: variable 'item_barme' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:78:11: error: variable 'item_bazme' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:79:11: error: variable 'item_bakme' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:80:11: error: variable 'item_state' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:81:11: error: variable 'item_testme' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:84:21: error: variable 'root_list' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
example.ino:87:11: error: variable 'menu_root' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
In a search for a solution I found a page in the github issues section titled "port to newer avr-gcc" which seemed to be about the same issue I'm having, and it had patch files in one of the responses which I applied and the errors stayed the same.

I tried fiddling around with the library code to try and see if I could fix it myself but I only ended up causing more errors.

LINKS:
I got the OMMenuMgr Library HERE
the Github issue page "port to newer avr-gcc" is HERE


Any help would be greatly appreciated


dnc40085

Please disregard my previous post as I have discovered the solution to my problem.

The solution was updating from Arduino for Linux x64 version 1.0.5 to version 1.0.6.

I should have checked for updates before posting.


Sorry for the needless bump, I'd sage but no field for that here.

pierrotm777

I have convert the OMMenuMgr library for IDE 1.6.3 and can't use it !

This is my code (i want to use digital buttons):
Code: [Select]
/**  Example OMMenuMgr Sketch

 @author
 C. A. Church
 
 */

#include "OMMenuMgr.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

//#define BUTTONTYPE ANALOG
#define BUTTONTYPE DIGITAL

const byte LCD_ROWS = 4;
const byte LCD_COLS = 20;

 // button values
#ifdef BUTTONTYPE ANALOG
 // which input is our button
const byte BUT_PIN = 14;
// analog button read values
const int BUTSEL_VAL  = 70;
const int BUTFWD_VAL  = 250;
const int BUTREV_VAL  = 450;
const int BUTDEC_VAL  = 655;
const int BUTINC_VAL  = 830;

const byte BUT_THRESH  = 60;

// mapping of analog button values for menu
int BUT_MAP_ANALOG[5][2] = {
  {BUTFWD_VAL, BUTTON_FORWARD},
  {BUTINC_VAL, BUTTON_INCREASE},
  {BUTDEC_VAL, BUTTON_DECREASE},
  {BUTREV_VAL, BUTTON_BACK},
  {BUTSEL_VAL, BUTTON_SELECT}
};
#endif

#ifdef BUTTONTYPE DIGTAL                             
int BUT_MAP_DIGITAL[5][2] = {
  {4, BUTTON_FORWARD},
  {5, BUTTON_INCREASE},
  {6, BUTTON_DECREASE},
  {7, BUTTON_BACK},
  {8, BUTTON_SELECT}
};
#endif

// ====== Test Menu ===========

byte foo = 0;
byte sel = 0;
unsigned int bar = 1;
long baz  = 0;
float bak = 0.0;

  // Create a list of states and values for a select input
const MENU_SELECT_ITEM  sel_ign = { 2, {"Ignore"} };
const MENU_SELECT_ITEM  sel_on  = { 1, {"On"} };
const MENU_SELECT_ITEM  sel_off = { 0, {"Off"} };

const MENU_SELECT_LIST  const state_list[] = { &sel_ign, &sel_on, &sel_off };
                                 
  // the special target for our state input
 
                                   // TARGET VAR   LENGTH                          TARGET SELECT LIST
const MENU_SELECT state_select = { &sel,           MENU_SELECT_SIZE(state_list),   MENU_TARGET(&state_list) };

  // values to use

                          //    TYPE            MAX    MIN    TARGET
const MENU_VALUE foo_value = { TYPE_BYTE,       100,   0,     MENU_TARGET(&foo) };
const MENU_VALUE bar_value = { TYPE_UINT,       10000, 100,   MENU_TARGET(&bar) };
const MENU_VALUE baz_value = { TYPE_LONG,       10000, 1,     MENU_TARGET(&baz) };
const MENU_VALUE bak_value = { TYPE_FLOAT_1000, 0,     0,     MENU_TARGET(&bak) };
const MENU_VALUE sel_value = { TYPE_SELECT,     0,     0,     MENU_TARGET(&state_select) };

                          //        LABEL           TYPE        LENGTH    TARGET
const MENU_ITEM item_checkme  = { {"Byte Edit"},    ITEM_VALUE,  0,        MENU_TARGET(&foo_value) };
const MENU_ITEM item_barme    = { {"UInt Edit"},     ITEM_VALUE,  0,        MENU_TARGET(&bar_value) };
const MENU_ITEM item_bazme    = { {"Long Edit"},    ITEM_VALUE,  0,        MENU_TARGET(&baz_value) };
const MENU_ITEM item_bakme    = { {"Float Edit"},   ITEM_VALUE,  0,        MENU_TARGET(&bak_value) };
const MENU_ITEM item_state    = { {"Select Input"}, ITEM_VALUE,  0,        MENU_TARGET(&sel_value) };
const MENU_ITEM item_testme   = { {"Test Action"},  ITEM_ACTION, 0,        MENU_TARGET(uiQwkScreen) };

                   //        List of items in menu level
const MENU_LIST const root_list[]   = { &item_checkme, &item_barme, &item_bazme, &item_bakme, &item_state, &item_testme };

                  // Root item is always created last, so we can add all other items to it
const MENU_ITEM menu_root     = { {"Root"},        ITEM_MENU,   MENU_SIZE(root_list),    MENU_TARGET(&root_list) };


 // initialize LCD object
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Addr, En, Rw, Rs, d4, d5, d6, d7, backlighpin, polarity



//OMMenuMgr Menu(&menu_root);
OMMenuMgr Menu(&menu_root, MENU_DIGITAL);



void setup() {

  lcd.begin(LCD_COLS, LCD_ROWS);
 
  uiClear();
 
  Menu.setDrawHandler(uiDraw);
  Menu.setExitHandler(uiClear);
#ifdef BUTTONTYPE ANALOG
  Menu.setAnalogButtonPin(BUT_PIN, BUT_MAP_ANALOG, BUT_THRESH);
#endif
#ifdef BUTTONTYPE DIGITAL
  Menu.setDigitalButtonPins(BUT_MAP_DIGITAL);
#endif
  Menu.enable(true);
 
 
}

void loop() {
 Menu.checkInput();//return The button pressed, one of: BUTTON_NONE, BUTTON_FORWARD, BUTTON_BACK, BUTTON_INCREASE, BUTTON_DECREASE, BUTTON_SELECT
 
}

void testAction() {

 digitalWrite(5, HIGH); 
}


void uiDraw(char* p_text, int p_row, int p_col, int len) {
  lcd.setCursor(p_col, p_row);
 
  for( int i = 0; i < len; i++ ) {
    if( p_text[i] < '!' || p_text[i] > '~' )
      lcd.write(' ');
    else 
      lcd.write(p_text[i]);
  }
}


void uiClear() {
 
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(F("Enter for Menu"));
}


void uiQwkScreen() {
  lcd.clear();
  Menu.enable(false);
 
  lcd.print("Action!");
  lcd.setCursor(0, 1);
  lcd.print(F("Enter 2 return"));
 
  while( Menu.checkInput() != BUTTON_SELECT ) {
    ; // wait!
  }
// 
  Menu.enable(true);
  lcd.clear();


If i add a delay into the uiDraw function, i can see the menu that change again and again after a push button !!!
Thanks for your help !!!

Stuartmp

Hi Drone,

As a new user to OMMenuMgr I must say its a great piece of code.

It took me a while to work out what was going on and how to customize it for my own needs.

But finally I have it working and I am very happy.

I have two small question that would help me improve my code.

I was wondering if you could help me.

Q1. Relates to this quoted text from the 'OMMenuMgr.h' file.

Quote
@code
byte foo = 0;

                            //       Data Type        Max    Min    Target
MENU_VALUE value_foo = { TYPE_BYTE,       100,   0,     MENU_TARGET(&foo) };

                //        LABEL           TYPE        LENGTH    TARGET
MENU_ITEM item_foo  = { {"Foo Edit"},    ITEM_VALUE,  0,        MENU_TARGET(&value_foo) };
@endcode


Here, we see that we can specify the type of data the item points to, a maximum value, a minimum
value, and the target variable (by address) to be edited.  Minimum and Maximum values are limited
to the range of a signed long, no matter the data type, and are not used for select lists.

Now specifically the Max and Min value and data type for 'MENU_VALUE value_foo'
I am trying to replace '100' and '0' with a variable.

The help file says

Quote
Minimum and Maximum values are limited to the range of a signed long, no matter the data type
But I have tried a rang of data types with no luck.

Could you please get back to me with you to solve this.

Below is a sample of what I have tried

int z_max = 100;
int z_min = 100;
MENU_VALUE lst_ang_z_s_value = { TYPE_UINT,z_max, z_min,MENU_TARGET(&lst_ang_z_s), Adr_zs_lstread };
MENU_ITEM item_zoom = { {"Zoom"},ITEM_VALUE,0,MENU_TARGET(&lst_ang_z_s_value)};

End Q1.


Q2. When you are exiting the value of a 'ITEM_VALUE' using the LCD and you are increasing or decreasing the values.

Is it possible for it to run some method to do something with the value on the screen.
Currently it appears to me that is only saves the variable once you press the 'BUTTON_SELECT'

The reason I ask is I am trying to set the position of a servo and if I use a 'ITEM_VALUE' menu item I can not get the servo to update as the value changes.

It only updates one I press the 'BUTTON_SELECT' which I assume is as designed.

So at this stage I have written a method that is called by the 'ITEM_ACTION' menu item.
this works but I don't think its the best solution.

Below is a sample of the code I wrote for my method.



Code: [Select]
void setHeightServo() {
 servo_adjustment_State = true;

  lcd.clear();
  Menu.enable(false);

  String Mnu_lbl = menuLabel();


  lcd.print("<- Adj " + Mnu_lbl + " ->");

  lcd.setCursor(0, 1);

  String str_new_lst_ang_ls_s = String(lst_ang_ls_s);
  lcd.print(str_new_lst_ang_ls_s);

  int org_lst_ang_ls_s = lst_ang_ls_s;
  unsigned int  old_lst_ang_ls_s = lst_ang_ls_s;


  while( Menu.checkInput() != BUTTON_SELECT ) {
    //; // wait!
 uint8_t btnPressed =Menu.checkInput();

  currentTime = millis();

 if (currentTime - previousScreenOnTime > screenTimeUntilSleep ){
 if (servo_OnOff_ControlState == 1)sleepServos();
 if (LCD_OnOff_ControlState == 1)sleepDisplay();
 }

 if(btnPressed != BUTTON_NONE){

 setPreviouseTime();

 if (btnPressed == BUTTON_INCREASE)lst_ang_ls_s = lst_ang_ls_s--;
 if (btnPressed == BUTTON_DECREASE)lst_ang_ls_s = lst_ang_ls_s++;

 if (lst_ang_ls_s != old_lst_ang_ls_s){
 if (servo_OnOff_ControlState == 0)wakeServos();
 if (LCD_OnOff_ControlState == 0)wakeDisplay();

 old_lst_ang_ls_s = lst_ang_ls_s;
 lense_shift_Servo.write(lst_ang_ls_s);

 lcd.setCursor(0, 1);
 lcd.print(String(lst_ang_ls_s));
 }


 if (btnPressed == BUTTON_BACK){
 lst_ang_ls_s = org_lst_ang_ls_s;
 lense_shift_Servo.write(org_lst_ang_ls_s);

  if (servo_OnOff_ControlState == 1)sleepServos();

  Menu.enable(true);
  lcd.clear();
  servo_adjustment_State = false;
  return;
  }

 }

  }



I also changed on of your variables from private to public so I could
get the current menu item.

below is the code I used to get the menu item on the LCD.

Code: [Select]
String menuLabel()
{

    //Serial.println("getMenuLabel");

    int i;    // counter variable
    char myChar;
    String menuLabel = "";

    // read back a char
      int len = strlen_P(Menu.m_curSel->label);

      for (i = 0; i < len; i++)
      {
        myChar =  pgm_read_byte_near(Menu.m_curSel->label + i);
        //Serial.print(myChar);
        menuLabel = menuLabel + myChar;
      }

      //Serial.print(menuLabel);
      return menuLabel;

 }



End Q2.


Thanks again for providing such a awesome library for us to use.

Cheers.

Stuart










Rudy216

This is an interesting menu starting point. I am running the sample sketch. If anyone knows something about this set of routines, how to use them, I have a question. Is it possible to have the menu elements appear on four lines when using a 4 line display?

The LCD setup information is set to 20x4 but it only displays the menu on the first two lines. Scrolling up or down works properly but it still only uses the top two lines. I would like the menu to make use of all four lines.

If anyone has any experience with OMMenuMgr I would appreciate any information that you have. Be it a sketch that uses OMMenuMgr. Or any insight in how to use the routines.


kallek

The LCD setup information is set to 20x4 but it only displays the menu on the first two lines. Scrolling up or down works properly but it still only uses the top two lines.
Have you defined the number of lines and columns both in OMMenuMgr.h and in your sketch "lcd.begin" line?

Quote
If anyone has any experience with OMMenuMgr I would appreciate any information that you have. Be it a sketch that uses OMMenuMgr. Or any insight in how to use the routines.
You can check out one example here https://github.com/woodyj21/patchedOMMenu that includes the patched version for a new compiler.
Useful feature is that the menu system supports saving variables to EEPROM. You can combine the variables that you change in the menu to a " struct" and load them all from EEPROM in a "setup".

Rudy216

Thanks.

I didn't have it changed in OMMenuMgr.h  It does display the menu on the four lines but when it edits a selection it leaves the menu items on the bottom two rows visible. Hey but at least I have something to work with now.

I haven't tried the example yet. I am going to update to that library first.

Once again. Thank you.  :)

Rudy216

Deleted post. Me whining.

Rudy216

OK I finally got it working. I took out all the midi code and have the original menu example. I have two problems right now. Setting the display for 4 rows causes the > cursor pointer to be lost. If I have it set for 2 or 3 rows the > is still present. As soon as I have the rows set to 4 (in the sketch and the header file) the > pointer disappears.

The other problem is that when I edit a selection the third and fourth line still shows what was on the menu before the selection was made. If anyone has any solutions for these two problems I I would appreciate some guidance.



There are things I really don't like about this menu code but it is all I have been able to get to work on my hardware so far. So I'm going to continue with it and hope I can fix some of the areas I see as lacking.

Rudy216

You can check out one example here https://github.com/woodyj21/patchedOMMenu that includes the patched version for a new compiler.
Useful feature is that the menu system supports saving variables to EEPROM. You can combine the variables that you change in the menu to a " struct" and load them all from EEPROM in a "setup".
I didn't get the eeprom saving it working with the above version of the library. I did get it with the one in message #34. I will need to check this some more.

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