Ciao,
This is a "perfecly" working ( at least I hope ) start base of MENWIZ to be used with the Arduino Lcd Keypad Shield ( http://www.robotshop.com/cytron-lcd-keypad-shield-arduino.html )
// +++++++ Libaries included
#include <Wire.h>
#include <LiquidCrystal.h>
//INSERT ALL THE LIBARIES AFTER INCLUDING WIRE LIB (MENWIZ request)
#include <LiquidCrystal_I2C.h>
#include <buttons.h>
#include <MENWIZ.h>
#include <EEPROM.h>
// Create global object for menu and lcd
menwiz menu;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
/*LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Addr, En, Rw, Rs, d4, d5, d6, d7, backlightpin, polarity 4 x 20 LCD
*/
boolean wr=0; // Instantiate global variables to bind to menu
const int buttonPin = A0; // 4 button switch circuit input connected to analog pin 0
const int led13Pin = 13; // the number of the LED output pin
boolean buttonBlock = 0;
boolean buttonAct = 0; // flag 1
boolean stopMenu = 0; // flag 2
byte buttonPressed = 0; // which button was pressed
byte lastButtonPressed = 0; // prev button pressed
int buttonValue = 0; // read value from analog port for the 4 navigation pushbuttons
long menuOffTime = 0; //used for timer
extern byte MW_navbtn; //needed to run the software key navigation in Menwiz
void setup()
{
Serial.begin(9600); // Output to serial writing
digitalWrite((54), HIGH); // enable the 20k internal pullup for MEGA board for analog port A0
// digitalWrite((A0), HIGH); // enable the 20k internal pullup for UNO based board for analog port A0
//++++++++++++++++++++Menu and LCD
char b[84];
_menu *r,*s1,*s2;
// initialize the menu object ( 4 x rows x 20 colums LCD)
menu.begin(&lcd,16,2); //initialize the menwiz menu object passing the lcd object and the colums and rows params
menu.addUsrNav(navMenu,4);
MW_navbtn=4; // force 4 or 6 buttons mode for menu navigation -> MW_navbtn=4; or MW_navbtn=6;
//create the menu tree
r=menu.addMenu(MW_ROOT,NULL,F("MAIN MENU")); //create a root menu at first (required)
//---------------
s1=menu.addMenu(MW_SUBMENU,r,F("SAW")); //add a submenu node 1 to the root menu (control the heigh of my Saw)
s2=menu.addMenu(MW_VAR,s1,F("ABS Height")); //add a terminal node in the menu tree (that is "variable"); (should move at a certain mm height)
s2=menu.addMenu(MW_VAR,s1,F("REL Move")); //add a terminal node in the menu tree (that is "variable"); (should move of a certain mm the height)
s2=menu.addMenu(MW_VAR,s1,F("Zero")); //add a terminal node in the menu tree (that is "variable");
//---------------
s1=menu.addMenu(MW_SUBMENU,r,F("PLANNER")); //add a submenu node 2 to the root menu (control the heigh of my Planner)
s2=menu.addMenu(MW_VAR,s1,F("ABS Height")); //add a terminal node in the menu tree (that is "variable"); (should move at a certain mm height)
s2=menu.addMenu(MW_VAR,s1,F("REL Move")); //add a terminal node in the menu tree (that is "variable"); (should move of a certain mm the height)
s2=menu.addMenu(MW_VAR,s1,F("Zero")); //add a terminal node in the menu tree (that is "variable"); (should set the zero)
//---------------
s1=menu.addMenu(MW_SUBMENU,r,F("SHAPER")); //add a submenu node 3 to the root menu
s2=menu.addMenu(MW_VAR,s1,F("ABS Height")); //add a terminal node in the menu tree (that is "variable"); (should move at a certain mm height)
s2=menu.addMenu(MW_VAR,s1,F("REL Move")); //add a terminal node in the menu tree (that is "variable"); (should move of a certain mm the height)
s2=menu.addMenu(MW_VAR,s1,F("Zero")); //add a terminal node in the menu tree (that is "variable"); (should set the zero)
/*
//++++++ Splash screen +++++++
sprintf(menu.sbuf,"TEST minimum menu\nwith 4 or 6\nanalog push buttons\n",1);
menu.addSplash((char *) menu.sbuf, 1000);
//++++++ Userscreen ++++++++++
// create an user define screen callback to activate after X secs since last button push
menu.addUsrScreen(msc,3000);
*/
pinMode(led13Pin, OUTPUT); // initialize the led as a output control pin
}
void loop()
{
// NAVIGATION MANAGEMENT & DRAWING ON LCD. NOT BLOCKING has to be the first in the void loop
menu.draw();
/*
put your regular code here
*/
readButtons();
}
// ++++++ functions +++++++
void readButtons()
// ++++ Control 4 buttons ++++
{
lastButtonPressed = buttonPressed;
/*
Analog values representing the pushbutton value are depending on the resitor value used.
Test the values first with the serial.monitor
*/
buttonValue = analogRead(buttonPin); //analog value to simulate the pushed buttons
if(buttonValue >= 850)
{
buttonPressed = 0;
noButtonPressed(); // is calling an extra fucntion
}
else if(buttonValue >= 380 & buttonValue <= 450)
{
buttonPressed = 4;
buttonAct = 1; // set the menu flag1
}
else if(buttonValue >= 200 & buttonValue <=300)
{
buttonPressed = 3;
buttonAct = 1; // set the menu flag1
}
else if(buttonValue >= 0 & buttonValue <=50)
{
buttonPressed = 2;
buttonAct = 1; // set the menu flag1
}
else if(buttonValue >= 80 & buttonValue <=150)
{
buttonPressed = 1;
buttonAct = 1; // set the menu flag1
}
}
int noButtonPressed()
{
return MW_BTNULL;
}
int navMenu() // called from menu.draw
{
/*
As soon as a button is pushed the first time flag 1 is set to HIGH and if the buttonnumber is not 0 then a timer is started.
The menu action then should only be performed once.
After 2000 msecs the flag will be set to LOW and a new buttonpush can be processed.
Menu action is blocked for 2000 msec even if the same button is being kept pressed for 2000 msecs by flag2.
*/
long menublockTime = millis();
if (buttonAct == 1 && buttonPressed != 0 && stopMenu == 0) // we have a state were we process a menu navigation step once and block it for 2 secs
{
digitalWrite(led13Pin,HIGH); // set timer led ON
menuOffTime = menublockTime + 2000; //start the timer. You can change this blocking time to your convenience but do not make it lower aa 200 msecs
stopMenu = 1;
switch (buttonPressed)
{
case 1: // Up
return MW_BTU;
break;
case 2: // Confirm
return MW_BTC;
break;
case 3: // Down
return MW_BTD;
break;
case 4: // Escape
return MW_BTE;
break;
}
}
if (menuOffTime != 0 && menublockTime > menuOffTime) // Reset of the timer so a new menu action can be processed
{
buttonAct = 0; // resets the flag 1
buttonPressed = 0;
menuOffTime = 0; // resets timer to zero
stopMenu = 0;
digitalWrite(led13Pin,LOW); // set timer led OFF
}
}
/*
// 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);
}*/
P.S.
/*
As soon as a button is pushed the first time flag 1 is set to HIGH and if the buttonnumber is not 0 then a timer is started.
The menu action then should only be performed once.
After 2000 msecs the flag will be set to LOW and a new buttonpush can be processed.
Menu action is blocked for 2000 msec even if the same button is being kept pressed for 2000 msecs by flag2.
*/
This is why sometimes I had to push twice a button to operate .... didn't wait enough !