Pages: 1 ... 5 6 [7] 8 9 ... 32   Go Down
Author Topic: MENWIZ: yet another character lcd menu wizard library  (Read 68062 times)
0 Members and 1 Guest are viewing this topic.
Pakistan
Offline Offline
Sr. Member
****
Karma: 6
Posts: 357
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

At first glance it could, as it seems to emulate multiple "digital" buttons, with integrated debouncing functionalities.
As long  as it gives you back a univoke code for pushed button for each call and "forget" (clean) that given event, it should work...

Hi Again,
Can you help me in this? How can this Analogbuttons.h can be use with scanNavButtons(). Please brunialti help me.
Logged


rome
Offline Offline
Sr. Member
****
Karma: 17
Posts: 481
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Khalid,
i suggest you the following steps:
- let prove your LCD with New LiquidCrystal (NLQ) library
- when the LCD is proved to work with NLQ, test the examples in MENWIZ library
- when you are able to run the example use a 4 or 6 standard button mode to build up your interface
- ONLY  at this stage you can test "advanced" functions in order to replace the navigation button internal method with your own.

I do not want you loose the fun of arduino discovery ...
Seriously, to help you from scratch up to the extend you expect, it is necessary to set up a test env with the analog button end the new button lib.
That is not possible for me in this moment due to the required time, even if i think it could be interesting for me.
I do not exclude to as soon as I can. But I cannot tell you exactly when ....
Logged

Pakistan
Offline Offline
Sr. Member
****
Karma: 6
Posts: 357
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you brunialti smiley
I shall follow the steps ... One question, if i declare the following function in Void Loop (), Will it work?

Code:
int     lastKeyEvent = 0;
int     curKeyEvent  = 0;
int     keyToReturn  = 0;
boolean keyToProcess = false;
int     adc_key_in   = 0;
int detectKey()
{
    keyToReturn = -1;
    adc_key_in = analogRead(ANALOG_PIN);       // read the value from the sensor 
    curKeyEvent = get_key(adc_key_in); // convert into key press
    if (curKeyEvent != lastKeyEvent)
    {
        if (!keyToProcess)
        {
            lastKeyEvent = curKeyEvent;
            keyToProcess = true;
        }
        else
        {
            keyToReturn = lastKeyEvent;
            lastKeyEvent = -1;
            keyToProcess = false;
        }
    }
    return keyToReturn;
}
Code:
int get_key(unsigned int keyboardValue){
  int k;
   keyboardValue = analogRead(ANALOG_PIN); // read the value (0-1023)
   if (keyboardValue <25){k=30; return k;}  //MW_BTNULL
   if ((keyboardValue >25) && (keyboardValue < 67)){k = 31;return k;}  //MW_BTU
   if ((keyboardValue >67) && (keyboardValue < 108)){k = 32;return k;}//MW_BTD
   if ((keyboardValue >108) && (keyboardValue < 162)){k = 33;return k;} //MW_BTL
   if ((keyboardValue >162) && (keyboardValue < 253)){k = 34;return k;} //MW_BTR
   if ((keyboardValue >253) && (keyboardValue < 361)){k = 35;return k;}//MW_BTE
   if ((keyboardValue >361) && (keyboardValue < 479)){k = 36;return k;} //MW_BTC
 

I don't know why in your skecth the Arrow is defined?
Code:
btx->BTU.check()==ON

I shall try to get it working and post my progress smiley
Logged


rome
Offline Offline
Sr. Member
****
Karma: 17
Posts: 481
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You make an analogread in the first function, then you pass the *value* to get_key, and you overwrite it with an other analogread (unusefull).
detect_key should be the function that have to be declared to memwiz with code like the following: menu.addUsrNav(detect_key)

I cannot understand why you declared all the variables as global (external to the get_key function) instead of declaring them as static inside the function. I imagine there is some good reason...

The get_key seems to be able to detect the currently pushed button, but it is not interrupt driven and so it can loose some event.
At first look the detect_key seems to be able to:
- detect a status change (button released/pushed)
- store the last change
- pass the last change (code key) next time it is invoked
- reset the status after returning the last change

so it could work. But of course eye debugging is not the key fo the success :-)

Forget the arrows: that is the internal code you must substitute, and btx is a pointer to an internal structure dinamically allocated ...

« Last Edit: June 16, 2012, 03:27:05 pm by brunialti » Logged

Pakistan
Offline Offline
Sr. Member
****
Karma: 6
Posts: 357
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I have just completed my Solar Tracker PCB module with 3-wire LCD and one wire Analog button. I shall soon try the MENWIZ smiley In the following video i am just displaying the different parameters on 20x4 LCD.. I hope using MENWIZ i shall be able to set the parameter values too smiley






* Solar Tracker with ICPS.jpg (289.17 KB, 1114x572 - viewed 25 times.)
Logged


rome
Offline Offline
Sr. Member
****
Karma: 17
Posts: 481
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sure.
You have the addUsrScreen, activated automatically after x seconds (defined by you) since last menu interaction, where you can show whatever you want.
Logged

Pakistan
Offline Offline
Sr. Member
****
Karma: 6
Posts: 357
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank You brunialti for helping. i really like your dynamic menu:)...I hope you will continue expanding it.. Your programming skills are really great.. What a alien language, C was not difficult for me  before opening your Header files smiley-mr-green smiley-mr-green
Logged


Denmark
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao Brunialti,

Thanks a lot for the introduction pdf, it has made playing with your library a very easy task! smiley
Before I go too much further with my project which is using it, is there any new version on the way? I ask you because the possible feature you mentioned in this thread of auto saving and loading some of the values from the EEPROM is very appealing, and definitely a must for my application.
Logged

rome
Offline Offline
Sr. Member
****
Karma: 17
Posts: 481
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@rafamart
In my "roadmap" the next steps are:

  • implementing the method setBehaviour: the variables should have alternative display layout, as first behaviour i would implement the option of Vertical/horizontal list. The behaviour setting would be activated with a call to the same method for all objects (this is simpler to remember and let the code readable)
  • implement the Flash memory storing of the string variables in addMenu, addMenuItem to spare ram space
  • pinpointing binded variables to EEPROM

Unfortunately I'm not able to give you a deadline for each of the above items. The first two are on the way.Stay tuned on http:/github/brunialti/MENWIZ!

Just for last minute readers I here attach the library and the introductory pdf

* QUICK TOUR V2.0.pdf (117.93 KB - downloaded 15 times.)
* MENWIZ_0_5_3.zip (731.58 KB - downloaded 6 times.)
« Last Edit: July 18, 2012, 03:22:52 pm by brunialti » Logged

Denmark
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Great, these sound like cool features. As to the EEPROM, I will go on then and implement my own save/load functionality. If it turns out to be a fairly generic and useful piece of code, I can share the code with you so that perhaps you can edit and merge to the original library later on.
Logged

rome
Offline Offline
Sr. Member
****
Karma: 17
Posts: 481
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

To store or read values in eeprom is quitE trivial.
I suggest to have a look at this:

http://modelrail.otenko.com/arduino/persistent-data-on-the-arduino-eeprom

The topics in MENWIZ are just to reach the true values to save (only menwiz vars will be stored/recalled) and to decide if the saving is automatic or "manual" (explicit call by he user).



« Last Edit: July 18, 2012, 02:12:45 am by brunialti » Logged

rome
Offline Offline
Sr. Member
****
Karma: 17
Posts: 481
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@RAFAMART

I've implemented the MENWIZ EEPROM variable load/save methods:

menwiz::loadEeprom();
menwiz::saveEeprom();

I did not deeply tested them but it should work.
There is a drawback affecting the library: it is necessary to include EEPROM.h in the sketch afrer MENWIZ.h
I tried to include EEPROM.h  in the MENWIZ.h file but it doesn't work ....

This change would affect all the sketches and add about 900 bytes for the new include.

Before to deliver a new version I would like somebody could test it more extensively.
Here following the modified sketch to run the two method via the menu (you can load variables in setup if you want).

Code:
//MENWIZ ESAMPLE
#include <Wire.h>
//INSERT ALL THE FOLLOWING 4 INCLUDES AFTER INCLUDING WIRE LIB
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <buttons.h>
#include <MENWIZ.h>
#include <EEPROM.h>

// DEFINE ARDUINO PINS FOR THE NAVIGATION BUTTONS
#define UP_BUTTON_PIN       9
#define DOWN_BUTTON_PIN     10
#define LEFT_BUTTON_PIN     7
#define RIGHT_BUTTON_PIN    8
#define CONFIRM_BUTTON_PIN  12
#define ESCAPE_BUTTON_PIN   11

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

//instantiate global variables to bind to menu
int tp=0;
float f=26.0;
boolean bb=0;
byte b=50;

void setup(){
  _menu *r,*s1,*s2;
  _var *v;
  int  mem;

  Serial.begin(19200);  
  
  // have a look on memory before menu creation
  Serial.println(sizeof(menwiz));
  mem=menu.freeRam();
  
  // inizialize the menu object (20 colums x 4 rows)
  menu.begin(&lcd,20,4);

  //create the menu tree
  r=menu.addMenu(MW_ROOT,NULL,"MAIN MENU");           //create a root menu at first (required)
    s1=menu.addMenu(MW_SUBMENU,r,"MEASURE SUBMENU");  //add a child (submenu) node to the root menu
      s2=menu.addMenu(MW_VAR,s1,"Test list");         //add a terminal node (that is "variable");
          s2->addVar(MW_LIST,&tp);                       //create a variable of type "option list"..
                                                         //...associated to the terminal node and bind it to the app variable "tp" of type int
          s2->addItem(MW_LIST,"option 1");            //add option to the OPTION LIST
          s2->addItem(MW_LIST,"option 2");            //add option to the OPTION LIST
          s2->addItem(MW_LIST,"option 3");            //add option to the OPTION LIST
      s2=menu.addMenu(MW_VAR,s1,"Test float var");    //add a terminal node (that is "variable");
          s2->addVar(MW_AUTO_FLOAT,&f,11.00,100.00,0.5); //create a variable of type "float number"...
                                                         //...associated to the terminal node and bind it to the app variable "f" of type float
      s2=menu.addMenu(MW_VAR,s1,"Test byte var");     //add a terminal node (that is "variable");
          s2->addVar(MW_AUTO_BYTE,&b,25,254,10);         //create a variable of type "byte"...
                                                         //...associated to the terminal node and bind it to the app variable "b" of typr byte
      s2=menu.addMenu(MW_VAR,s1,"Test boolean var");  //add a terminal node (that is "variable");
          s2->addVar(MW_BOOLEAN,&bb);                    //create a variable of type "boolean"
                                                         //...associated to the terminal node and bind it to the app variable "bb" of type boolean
    s1=menu.addMenu(MW_VAR,r,"Save");
      s1->addVar(MW_ACTION,save);
    s1=menu.addMenu(MW_VAR,r,"Load");
      s1->addVar(MW_ACTION,load);
    
  //(optional) create a splash screen with some usefull infos
  //the character \n marks end of line
  //(tip): use preallocated internal menu.sbuf buffer to save memory space!
  sprintf(menu.sbuf,"MENWIZ TEST V %s\n.Free mem. :%d\n.Used mem  :%d\n.Lap secs  :%d",menu.getVer(),menu.freeRam(),mem-menu.freeRam(),5);
  menu.addSplash((char *) menu.sbuf, 5000);
 
  //declare navigation buttons (required)
  menu.navButtons(UP_BUTTON_PIN,DOWN_BUTTON_PIN,LEFT_BUTTON_PIN,RIGHT_BUTTON_PIN,ESCAPE_BUTTON_PIN,CONFIRM_BUTTON_PIN);
  //create a user define screen callback to activate after 7 secs since last button push
  menu.addUsrScreen(msc,10000);
  }

void loop(){
  // NAVIGATION & DRAWING MANAGEMENT
  menu.draw();
  //PUT APPLICATION CODE HERE
  }

// user defined default screen
void msc(){
  sprintf(menu.sbuf,"User screen\nUptime (s): %ld\nFree mem  : %d\n\n",millis()/1000,(int)menu.freeRam());
  menu.drawUsrScreen(menu.sbuf);
  }

void load(){
  menu.readEeprom();
  }
void save(){
  menu.writeEeprom();
  }

Can you test it and give me a feedback?
Thanks

p.s. here attached the modified MENWIZ library files. They still contains serial debug prints out
 






* MENWIZ.cpp (22.46 KB - downloaded 13 times.)
* MENWIZ.h (7.04 KB - downloaded 11 times.)
« Last Edit: July 18, 2012, 09:41:05 am by brunialti » Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 128
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, I'm trying to implement MENWIZ with 3 buttons instead of 4.

I have 3 buttons on an analog pin, when any button is pressed an interrupt is triggered to read the pin, set a flag to say button processing required and the button that was pressed.

I defined my own button function as per the Tour pdf (very useful by the way!!) which I guess MENWIZ polls and added submenu items that call my exit function, this just sets a couple of flags like the interrupt would but to emulate an ESCAPE press. Seems to work but I get this confirm to run message too. is it possible to disable that?  or do you have recommendations on implementing MENWIZ with 3 buttons rather than 4?

Not sure if this is something I did but the "Node4" MW_AUTO_INT looses it's label in the menu sometimes (pssibly related to using the List option first.). If you select it it no longer runs instead returning to the root menu. Also I can't seem to access the freeMem() funct, has it been removed?

Code:

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_SR.h>
#include <buttons.h>
#include <MENWIZ.h>
#include <MemoryFree.h>

//INTERRUPT BUTTONS
const int pin = 13;  // test for interrupt
const int buttonPin = A0; // buttons can be read here
volatile byte buttonAct = 0; // flag, follow button press
volatile int buttonValue = 0; // button pressed analogue value
volatile int buttonPressed = 0;  // which button was pressed
volatile byte lastButtonPressed = 0; // prev button pressed
volatile byte state = LOW; // state of led on pin13
volatile byte lastState = HIGH; // unused?

/*
// DEFINE ARDUINO PINS FOR THE NAVIGATION BUTTONS
 #define UP_BOTTON_PIN       9
 #define DOWN_BOTTON_PIN     5
 #define LEFT_BOTTON_PIN     7
 #define RIGHT_BOTTON_PIN    8
 #define CONFIRM_BOTTON_PIN  3
 #define ESCAPE_BOTTON_PIN   4
 */
menwiz tree;
// create lcd obj using LiquidCrystal lib
LiquidCrystal_SR lcd(10, 11, 12); //Data,Clk,Enable.

int  list,sp=110;

void setup(){
  Serial.begin(19200);
  Serial.println(F("STARTED"));
  pinMode(pin, OUTPUT);
  attachInterrupt(0, readButtons, RISING); 


  _menu *r,*s1,*s2;


  tree.addUsrNav(navMenu);
  tree.begin(&lcd,20,4); //declare lcd object and screen size to menwiz lib

  r=tree.addMenu(MW_ROOT,NULL,"Root");
  s1=tree.addMenu(MW_SUBMENU,r,"SUBMENU");
  s2=tree.addMenu(MW_VAR,s1,"Node3");
  s2->addVar(MW_LIST,&list);
  s2->addItem(MW_LIST,"Option1");
  s2->addItem(MW_LIST,"Option2");
  s2->addItem(MW_LIST,"Option3");
  s2=tree.addMenu(MW_VAR,s1,"Node4");
  s2->addVar(MW_AUTO_INT,&sp,0,120,10);
  s2=tree.addMenu(MW_VAR,s1,"Exit");
  s2->addVar(MW_ACTION,exitFunct); 

  // tree.navButtons(UP_BOTTON_PIN,DOWN_BOTTON_PIN,LEFT_BOTTON_PIN,RIGHT_BOTTON_PIN,ESCAPE_BOTTON_PIN,CONFIRM_BOTTON_PIN);
}
int i = 0;
void loop(){
 
  if(i > 1000){
      Serial.print(F("freeMemory() reports "));
    Serial.println( freeMemory() );
    i = 0;
  }else{
    i++;
  }
  tree.draw();
}

void myfunc(){
  Serial.println("ACTION FIRED!");
}


void readButtons(){
  state = !state;
  digitalWrite(pin, state);
  /*   511 : none | 614 : up | 768 : down | 1023 : select   */
  lastButtonPressed = buttonPressed;

  buttonValue = analogRead(buttonPin);
  if(buttonValue >= 900) {
    buttonPressed = 3; // select

  }
  else if(buttonValue >= 700){   
    buttonPressed = 2;  // down

  }
  else if(buttonValue >= 600){   
    buttonPressed = 1;  // up

  }
  buttonAct = 1;
  Serial.print(buttonPressed);
  Serial.print(" ");
  Serial.println(buttonValue);

}


void exitFunct(){
  buttonAct = 1;
  buttonPressed = 4;
}

int navMenu(){
  //MenuItem currentMenu=menu.getCurrent();
  if(buttonAct){
    buttonAct = 0;
    switch (buttonPressed){
    case 4: //simulated escape
      return MW_BTE;
      break;
    case 3: //select     
      return MW_BTC;
      /*
       if (menu.getCurrent().getRight() != 0){  //The current item has an element right, it's a sub menu so nav right.
       
       menu.moveRight();
       Serial.print(menu.getCurrent().getName());
       Serial.println(F("has menu right"));
       }
       else{  //otherwise, menu has no child and has been pressed. enter the current menu
       menu.use();
       }
       */
      break;
    case 2: //down
      return MW_BTD;
      break;     
    case 1: //up
      return MW_BTU;
      break;     
    }
  }
  else{
    return MW_BTNULL;
  }
}

Logged

rome
Offline Offline
Sr. Member
****
Karma: 17
Posts: 481
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Great. I never thought about 3 button mode... :-)

at a first glance:
  • You are calling freeMemory()  instead of tree.freeRam()
  • "confirm to RUN" is the default associated label in order to let the user be warned about starting action. It will be possible to toggle it on/off by next setBehaviour method in the next version
  • about the label missing ... It should'nt. I'll try to investigate better

EDIT in the quick tour doc there was the wrong reference to freeMemory. Is has been incorporated by menwiz class and changed to freeRam, as it returns the free ram and not the prog or eeprom memory. Please be sure to use the latest version of lib at https://github.com/brunialti/MENWIZ
« Last Edit: July 19, 2012, 07:12:15 am by brunialti » Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 128
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Great. I never thought about 3 button mode... :-)

at a first glance:
  • You are calling freeMemory()  instead of tree.freeRam()
  • "confirm to RUN" is the default associated label in order to let the user be warned about starting action. It will be possible to toggle it on/off by next setBehaviour method in the next version
  • about the label missing ... It should'nt. I'll try to investigate better

EDIT in the quick tour doc there was the wrong reference to freeMemory. Is has been incorporated by menwiz class and changed to freeRam, as it returns the free ram and not the prog or eeprom memory. Please be sure to use the latest version of lib at https://github.com/brunialti/MENWIZ

Only a matter of time before someone wants 5 buttons ;-) but then MENWIZ was flexible enough for me.
I'm calling freeMemory() as I've included it myself since the tree.freeRam() didn't compile. 
I will beef this up then while I wait on the next version with setBehaviour.

I must say I've struggled with some other menu librarys, not so with this one :-D
Logged

Pages: 1 ... 5 6 [7] 8 9 ... 32   Go Up
Jump to: