Pages: 1 ... 6 7 [8] 9 10 ... 34   Go Down
Author Topic: MENWIZ: yet another character lcd menu wizard library  (Read 74756 times)
0 Members and 1 Guest are viewing this topic.
rome
Offline Offline
Sr. Member
****
Karma: 17
Posts: 486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yeah. Someone could also ask for 2.5 buttons ...
Be sure you've got the latest version of menwiz as freeRam *must* compile ...
Until the first version 1.0 (soon to be delivered if I get positive feedback) I'm touching the lib and sometime I've got some regression error. Currently I'm struggling with raspi/arduino integration and I've not time enough to finalize this lib.
« Last Edit: July 19, 2012, 10:09:17 am by brunialti » Logged

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

just got my raspi today as it goes smiley-razz

I'll look at the freeRam, after some raspi fiddling of course
Logged

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

Please find the new lib version at https://github.com/brunialti/MENWIZ/downloads .
There are the new following methods:

void menwiz::writeEeprom(); //write all MENWIZ binded variables to eeprom
void menwiz::readEeprom();  //read from eeprom the previously saved variable values
void _menu::setBehaviour(byte behaviour, boolean value); //toggle action confirmation, horizontal/vertical scrolling of list

In order to let you have a better idea of the changes, please read the updated quick tour pdf doc here attached.
Due to the eeprom support it is now necessary to include EEPROM.h file in the user sketch. This introduce a small backward compatibility break.

Feedbacks are welcome

* MENWIZ_0-6-0_QUICK TOUR.pdf (139.44 KB - downloaded 72 times.)
« Last Edit: July 21, 2012, 10:59:56 am by brunialti » Logged

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

Hi, do you have an example of the setBehaviour? I'm not sure how it should be declared and against what object? tree. _menu etc?

I'm getting errors like "MW_ACTION_IMMEDIATE is not defined"
Logged

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

Hi, to be clear I'm using version 0.6.1
I'd defined my own button press detection as before, and emulated an exit press by fireing a custom function. While it asked for confirm to run when pressing confirm it ran. Now it doesn't run, asks for confirm, i press confirm and it goes back to the menu list



Code:
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_SR.h>
#include <buttons.h>
#include <EEPROM.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
 */
// #define MW_ACTION_IMMEDIATE
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
//_menu::setBehaviour(byte MW_ACTION_IMMEDIATE, false);
  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(" XX ");
  Serial.println(buttonValue);

}


void exitFunct(){
  Serial.println("EXIT Called");
  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;
      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: 486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

there is a misalignment between the quick tour doc and the code.
The syntax is

xxx.setBehaviour(MW_ACTION_CONFIRM,false);

Does the example compile and run ? Iin the example there is also this behaviour commented.
« Last Edit: July 26, 2012, 11:56:15 am by brunialti » Logged

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

reading better your code, it is wrong.
The setBehaviour is a menu method that must be called after the menu declarations and for each variable object you want to affect, not before

This is a chunk of real code working

Code:
s1=menu.addMenu(MW_VAR,r,F("TEST ACTION"));             
      s1->addVar(MW_ACTION,act);                         
      s1->setBehaviour(MW_ACTION_CONFIRM,false);         
Logged

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

there is a misalignment between the quick tour doc and the code.
The syntax is

xxx.setBehaviour(MW_ACTION_CONFIRM,false);

Does the example compile and run ? Iin the example there is also this behaviour commented.

Yep it was the CONFIRM vs IMMEDIATE. If set false works as expected.
If not declared at all, asks for confirm to run but don't run when confirm is pressed (not an issue for me)
If declared as true, asks for confirm to run but don't run when confirm is pressed.

Regarding my mistake declaring referenced in your last reply. That was me trying to find a working way but using the none existent  MW_ACTION_IMMEDIATE
Logged

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

I cannot replicate what you noticed.
I downloaded the 0.6.1. version from git hub and modified the example as following
Code:
//MENWIZ ESAMPLE
#include <Wire.h>
//INSERT ALL THE FOLLOWING 5 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"..
          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->setBehaviour(MW_SCROLL_HORIZONTAL,true); //...if you like horizontal scroll  

      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"

    s1=menu.addMenu(MW_VAR,r,"TEST ACTION1");             //add a terminal node (that is "variable") create an "action" associated to the terminal node...
      s1->addVar(MW_ACTION,act1);                         //the act function as default will be called when enter button is pushed
      //s1->setBehaviour(MW_ACTION_CONFIRM,false);         //...if you don't need action confirmation


    s1=menu.addMenu(MW_VAR,r,"TEST ACTION2");             //add a terminal node (that is "variable") create an "action" associated to the terminal node...
      s1->addVar(MW_ACTION,act2);                         //the act function as default will be called when enter button is pushed
      s1->setBehaviour(MW_ACTION_CONFIRM,false);         //...if you don't need action confirmation


  //declare navigation buttons (required)
  menu.navButtons(UP_BUTTON_PIN,DOWN_BUTTON_PIN,LEFT_BUTTON_PIN,RIGHT_BUTTON_PIN,ESCAPE_BUTTON_PIN,CONFIRM_BUTTON_PIN);

  //(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);
  //(optional) create a splash screen (duration 5.000 millis)with some usefull infos the character \n marks end of LCD line
  menu.addSplash((char *) menu.sbuf, 5000);
  //(optional)create a user define screen callback to activate after 10 secs (10.000 millis) since last button push
  menu.addUsrScreen(msc,10000);
  }

void loop(){
  menu.draw();
  //PUT APPLICATION CODE HERE (if any)
  }

// user defined callbacks
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 act1(){
  Serial.println("FIRED ACTION1");
 }

void act2(){
  Serial.println("FIRED ACTION2");
 }
 
void savevar(){
  menu.writeEeprom();
  }
  
void loadvar(){
  menu.readEeprom();
  }

The above code works as expected: the first action ask for confirmation before to write to serial, and second action do'not (EDIT but write correctly to serial).
I think something in the custom button management routine could bias the result.
I'll check.
« Last Edit: July 26, 2012, 02:45:16 pm by brunialti » Logged

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

I can only assume it is something ot do with the custom button function given that's the only difference.
The button pin defines are commented out, could that be a problem?

Here is my full code if it helps:

Code:
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_SR.h>
#include <buttons.h>
#include <EEPROM.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
 */
 #define MW_ACTION_IMMEDIATE
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);
  s2->setBehaviour(MW_ACTION_CONFIRM,false);
 

  // 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("freeRam() reports "));
    Serial.println( tree.freeRam() );
   
    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(" XX ");
  Serial.println(buttonValue);

}


void exitFunct(){
  Serial.println("EXIT Called");
  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;
      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: 486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The code seems to be ok.
By the way it would be more polite to call addUsrNav after begin method.
I cannot test the code as i would need to set up the same custom analog buttons.

You can try the following on my behalf :-)
Replace the actual method addUsrNav in MENWIZ.cpp with the following

Code:
void menwiz::addUsrNav(int (*f)()){
  ERROR(0);
  btx=(_nav*)malloc(sizeof(_nav));if(btx==NULL){ERROR(900); return;}
  usrNav.fl=true;
  usrNav.fi=f;
  }

Let me know
« Last Edit: July 28, 2012, 04:07:54 am by brunialti » Logged

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

I'll give it a try tonight and let you know. I'm not near my Arduino at the moment.

Code:
http://arduino.cc/forum/index.php?topic=109796.0
talks about the button setup if you did want to try the buttons.
Logged

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

Please find in https://github.com/brunialti/MENWIZ/downloads
the latest version of MENWIZ.

This version should be my final one (bug fixing apart).

Starting fron this versione the addMenu and addItem (the two methods used to build menu structure) accepts string labels wrapped by F() operator. It saves quite a lot of flash memory (but requires little changes to the sketch code of the previous versions).

Some more behaviours were added to option list object: now it is possible to display options in 2 or 3 columns.

There is still the dannix issue to check, but it seems limited to custom input devices using the MW_ACTION_CONFIRM behaviour.

Here attached the library guide.

* MENWIZ_1_0_0_QUICK TOUR.pdf (148.45 KB - downloaded 37 times.)
Logged

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

Hi, sorry for the delay getting back to you. I've made the changes you suggested

Code:
//void menwiz::addUsrNav(int (*f)()){
//  usrNav.fl=true;
//  usrNav.fi=f;
//  }
void menwiz::addUsrNav(int (*f)()){
  ERROR(0);
  btx=(_nav*)malloc(sizeof(_nav));if(btx==NULL){ERROR(900); return;}
  usrNav.fl=true;
  usrNav.fi=f;
  }


As before,
setBehaviour false: no confirm and runs ("Exit Called in serial output")
setBehaviour true: confirm msg shown but no exit function run ("button press registered but no serial outout for "Exit called"")
no setBehaviour declaration: same as setBehaviour true

I'm going to update the lib with what you posted above and retry.
Logged

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

Hi, with the latest library it's the same as above. If confirm msg shown, confirm does not run the custom function.

Additionally now if setBehaviour is false, it calls the exit function but when the menu is redrawn it leaves node4 under SUBMENU which shouldn't be there, it's not at prog startup neither can you select Node4

menus is setup like so:

SUBMENU
      Node3
          Option 1
          Option 3
          Option 3
      Node4
          0 [110] 120
      Exit

So node4 should always be the next level up. I didn't reapply the addUsrNav function changes to this library test.
Logged

Pages: 1 ... 6 7 [8] 9 10 ... 34   Go Up
Jump to: