The use of custom button navigation using addUsrNav is giving me a bit of a headache. I can't see why it doesn't work.
I'm using MENWIZ Version 1.2.0 on IDE 1.0.1 with a breadboarded 328P and Arduino Uno selected as the Board.
What I am doing is basing all my input on a 4x4 Keypad, theKeypad and Keypad_I2C libraries. When I use my own buttons I just emulate a particular position on the keypad by connecting across the appropriate row/col; i.e I have 3 buttons on my device that emaulate the keys 4, 6 and #. Thus the Keypad library takes care of all my edge triggering and debouncing for me and I get up to 16 buttons sharing teh I2C lines via a PCF8574 expander.
For this menu I am choosing 2-UP, 4-LEFT, 6-RIGHT, 8-DOWN, *-ESCAPE, #-CONFIRM, so my custom function looks for these particular keypresses and returns the approrpiate MW_BTU, MW_BTL, MW_BTR, MW_BTD, MW_BTE and MW_BTC. It returns MW_BTNULL if no key is pressed when scanned.
I removed all the defines for the buttons in my sketch:-
// DEFINE ARDUINO PINS FOR THE MENU NAVIGATION BUTTONS
//#define UP_BOTTON_PIN 16
//#define DOWN_BOTTON_PIN 17
//#define LEFT_BOTTON_PIN 18
//#define RIGHT_BOTTON_PIN 19
//#define CONFIRM_BOTTON_PIN 20
//#define ESCAPE_BOTTON_PIN 21
I commented out the navButtons declaration and added a line for addUsrNav
//menu.navButtons(UP_BOTTON_PIN,DOWN_BOTTON_PIN,LEFT_BOTTON_PIN,RIGHT_BOTTON_PIN,ESCAPE_BOTTON_PIN,CONFIRM_BOTTON_PIN);
menu.addUsrNav(menuKeys,6);
I created my new function to read the keypad and just check for the keys we are using for menu items
int menuKeys()
{
char keyPressed = keypad1.getKey();
if (keyPressed != NO_KEY)
{
if (keyPressed == '2')
{
return MW_BTU;
}
else if (keyPressed == '8')
{
return MW_BTD;
}
else if (keyPressed == '4')
{
return MW_BTL;
}
else if (keyPressed == '6')
{
return MW_BTR;
}
else if (keyPressed == '*')
{
return MW_BTE;
}
else if (keyPressed == '#')
{
return MW_BTC;
}
else
{
return MW_BTNULL;
}
}
I also comment out the BUTTON_SUPPORT define in MENWIZ.h
#define EEPROM_SUPPORT //uncomment if you want to use the readEeprom and writeEeprom methods!
//#define BUTTON_SUPPORT //uncomment if you want to use the readEeprom and writeEeprom methods!!
(Incidentally, note the incorrect comment, I found the reference to this define and was looking for it up and down the code, but scanning comments too made it look like this section was just for EEPROM)
From what I've seen in previous posts, this should now work and let me navgate the menu structure with the keypad. I can call the function from loop() and Serial.print the returned values to Serial Monitor and I get the values 2,3,4,5,6,7 returned for U,D,L,R,E,C so the function is working fine, it just seems that MENWIZ isn't calling it.
Full sketch code below
//The full code is in library example file Quick_tour.ino
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <buttons.h>
#include <MENWIZ.h>
#include <EEPROM.h>
#include <Keypad_I2C.h>
#include <Keypad.h>
#define keypad1_addr 0x22
#define lcd1_addr 0x27
// DEFINE ARDUINO PINS FOR THE MENU NAVIGATION BUTTONS
//#define UP_BOTTON_PIN 16
//#define DOWN_BOTTON_PIN 17
//#define LEFT_BOTTON_PIN 18
//#define RIGHT_BOTTON_PIN 19
//#define CONFIRM_BOTTON_PIN 20
//#define ESCAPE_BOTTON_PIN 21
int GAMETIME=30, POINTPERIOD=10, POINTSPERPERIODRED=5, POINTSPERPERIODBLUE=5;
int RESETSCOREPERIOD=0, COUNTDOWNTIMER=3, SPLASHSCREEN=1, WIRELESS = 1, DEBUG = 1;
int LEDBLINK =1, LEDBLINKON = 500, LEDBLINKOFF = 500, CURSORBLINKRATE = 500, BACKLIGHTDELAY = 1;
int list, sp;
// Keypad setup
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the symbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {7, 6, 5, 4}; //connect to the column pinouts of the keypad
//initialize an instance of class NewKeypad
Keypad_I2C keypad1( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS, keypad1_addr);
menwiz menu;
// create lcd obj using LiquidCrystal lib
//LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
LiquidCrystal_I2C lcd(lcd1_addr, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE); // addr, EN, RW, RS, D4, D5, D6, D7, Backlight, POLARITY
void setup(){
_menu *r,*s1,*s2,*s3;
keypad1.begin();
Serial.begin(115200);
menu.begin(&lcd,16,2); //declare lcd object and screen size to menwiz lib
menu.setBehaviour(MW_MENU_INDEX,false); // turn off the menu index - 1/3 etc
r=menu.addMenu(MW_ROOT,NULL,F("MAIN MENU"));
s1=menu.addMenu(MW_SUBMENU,r, F("General"));
s2=menu.addMenu(MW_SUBMENU,s1, F("Game Setup"));
s3=menu.addMenu(MW_VAR,s2, F("Game Time (m)"));
s3->addVar(MW_AUTO_INT,&GAMETIME,0,5999,1);
s3=menu.addMenu(MW_VAR,s2, F("Pts Period (s)"));
s3->addVar(MW_AUTO_INT,&POINTPERIOD,0,3600,1);
s3=menu.addMenu(MW_VAR,s2, F("Red Points"));
s3->addVar(MW_AUTO_INT,&POINTSPERPERIODRED,0,1000,5);
s3=menu.addMenu(MW_VAR,s2, F("Blue Points"));
s3->addVar(MW_AUTO_INT,&POINTSPERPERIODBLUE,0,1000,5); // min, max, increment
s3=menu.addMenu(MW_VAR,s2, F("Reset Period"));
s3->addVar(MW_LIST,&RESETSCOREPERIOD);
s3->addItem(MW_LIST, F("No")); // returns index 0
s3->addItem(MW_LIST, F("Yes")); // returns index 1
s3=menu.addMenu(MW_VAR,s2, F("Countdown (s)"));
s3->addVar(MW_AUTO_INT,&COUNTDOWNTIMER,0,30,1);
s2=menu.addMenu(MW_SUBMENU,s1, F("Device Setup"));
s3=menu.addMenu(MW_VAR,s2, F("Splash Screen"));
s3->addVar(MW_LIST,&SPLASHSCREEN);
s3->addItem(MW_LIST, F("Off")); // returns index 0
s3->addItem(MW_LIST, F("On")); // returns index 1
s1=menu.addMenu(MW_SUBMENU,r, F("Advanced"));
s2=menu.addMenu(MW_VAR,s1, F("Wireless"));
s2->addVar(MW_LIST,&WIRELESS);
s2->addItem(MW_LIST, F("Off")); // returns index 0
s2->addItem(MW_LIST, F("On")); // returns index 1
s2=menu.addMenu(MW_SUBMENU,s1, F("LED Control"));
s3=menu.addMenu(MW_VAR,s2, F("LED Flashing"));
s3->addVar(MW_LIST,&LEDBLINK);
s3->addItem(MW_LIST, F("Off")); // returns index 0
s3->addItem(MW_LIST, F("On")); // returns index 1
s3=menu.addMenu(MW_VAR,s2, F("On Time (ms)"));
s3->addVar(MW_AUTO_INT,&LEDBLINKON,0,1000,100);
s3=menu.addMenu(MW_VAR,s2, F("Off Time (ms)"));
s3->addVar(MW_AUTO_INT,&LEDBLINKOFF,0,1000,100);
s2=menu.addMenu(MW_VAR,s1, F("Cursor Flash"));
s2->addVar(MW_AUTO_INT,&CURSORBLINKRATE,0,1000,100);
s1=menu.addMenu(MW_SUBMENU,r, F("Developer"));
s2=menu.addMenu(MW_VAR,s1, F("Serial Debug"));
s2->addVar(MW_LIST,&DEBUG);
s2->addItem(MW_LIST, F("Off")); // returns index 0
s2->addItem(MW_LIST, F("On")); // returns index 1
s1=menu.addMenu(MW_VAR,r, F("SAVE & EXIT"));
s1->addVar(MW_ACTION,save_settings);
s1->setBehaviour(MW_ACTION_CONFIRM,false); // turn confirmation off
s1=menu.addMenu(MW_VAR,r, F("EXIT NO SAVE"));
s1->addVar(MW_ACTION,exit_menu);
s1->setBehaviour(MW_ACTION_CONFIRM,false); // turn confirmation off
//menu.navButtons(UP_BOTTON_PIN,DOWN_BOTTON_PIN,LEFT_BOTTON_PIN,RIGHT_BOTTON_PIN,ESCAPE_BOTTON_PIN,CONFIRM_BOTTON_PIN);
menu.addUsrNav(menuKeys,6);
Serial.println(menu.freeRam());
}
void loop()
{
menu.draw();
int key = menuKeys();
if (key != MW_BTNULL)
{
Serial.println(key);
}
//char customKey = keypad1.getKey();
/* if (customKey != NO_KEY){
Serial.println(customKey);
if(customKey == '2')
{
Serial.println(F("Did the comparison"));
}
} */
}
void save_settings()
{
Serial.println(F("SAVE SETTINGS TO EEPROM"));
}
void exit_menu()
{
Serial.println(F("EXIT MENU WITHOUT SAVING TO EEPROM"));
}
void myfunc()
{
Serial.println(F("ACTION FIRED"));
}
int menuKeys()
{
char keyPressed = keypad1.getKey();
if (keyPressed != NO_KEY)
{
if (keyPressed == '2')
{
return MW_BTU;
}
else if (keyPressed == '8')
{
return MW_BTD;
}
else if (keyPressed == '4')
{
return MW_BTL;
}
else if (keyPressed == '6')
{
return MW_BTR;
}
else if (keyPressed == '*')
{
return MW_BTE;
}
else if (keyPressed == '#')
{
return MW_BTC;
}
else
{
return MW_BTNULL;
}
}
}