London-UK
Offline
Jr. Member
Karma: 0
Posts: 67
|
 |
« on: January 10, 2013, 04:48:13 am » |
hello, I have a working menu using push buttons and have attached the navigation function of this menu below. I want to use an encoder and have included the encoder sketch here too. what do I have to change to get the navigation menu working off the encoder....... instead of the push buttons. I will use the right direction of the encoder to move the menu right and left for left. The encoder has a built in push button so I will use that as the "buttonPinEnter" . I have tried putting some of the encoder sketch into the navigation menu but it just stops any menu working. I sure anyhelp here may help others. void navigateMenus() { MenuItem currentMenu=menu.getCurrent();
switch (lastButtonPushed){ case buttonPinEnter: // enter pin this is set up to use a push button BUT need it to use PUSH BUTTON ON ENCODER if(!(currentMenu.moveDown())){ //if the current menu has a child and enter has been pressed then navigate menu to item below menu.use(); } else{ //otherwise, if menu has no child and enter has been pressed---- the current menu is used menu.moveDown(); } break; case buttonPinEsc: //not Set up yet but this will have a push button menu.toRoot(); //back to main break;
case buttonPinRight: menu.moveRight(); break;
case buttonPinLeft: menu.moveLeft(); break;
lastButtonPushed=0; //reset the lastButtonPushed variable } }
and here is a separate working sketch of the encoder int val; int encoder0PinA = 2; int encoder0PinB = 3; int encoder0Pos = 0; int encoder0PinALast = LOW; int n = HIGH;
void setup() { pinMode (encoder0PinA,INPUT); pinMode (encoder0PinB,INPUT); Serial.begin (9600); }
void loop() { n = digitalRead(encoder0PinA); if ((encoder0PinALast == HIGH) && (n == LOW)) { if (digitalRead(encoder0PinB) == LOW) { encoder0Pos--; } else { encoder0Pos++; } Serial.print (encoder0Pos); Serial.print ("/"); } encoder0PinALast = n; }
Any help on implimenting this change would be appreciated.
|
|
|
|
« Last Edit: January 11, 2013, 01:06:15 pm by mark7w »
|
Logged
|
|
|
|
|
East Anglia (UK)
Offline
Edison Member
Karma: 48
Posts: 1408
May all of your blinks be without delay
|
 |
« Reply #1 on: January 10, 2013, 05:01:36 am » |
It should be easy enough to read the button on the encoder. Get that working first by plugging it in instead of the current button.
To use the encoder to navigate the menu you need to determine which way it is rotating. In your encoder sketch you are already working this out and changing the value of encoder0Pos appropriately, so instead of changing the value treat an increasing value as one button and a decreasing value as the other and call menu.moveRight(); or menu.moveLeft(); to suit.
If this is what you have already tried then seeing your code would be helpful.
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 277
Posts: 25499
Solder is electric glue
|
 |
« Reply #2 on: January 10, 2013, 05:19:11 am » |
|
|
|
|
|
Logged
|
|
|
|
|
London-UK
Offline
Jr. Member
Karma: 0
Posts: 67
|
 |
« Reply #3 on: January 10, 2013, 09:31:53 am » |
UKHeliBob It should be easy enough to read the button on the encoder. Get that working first by plugging it in instead of the current button.
I have the push button on the Encoder working now  just the -- and ++ of the encoder to figure out. see my last part of the sketch "void navigateMenus". this is for me the difficult part. 
|
|
|
|
|
Logged
|
|
|
|
|
East Anglia (UK)
Offline
Edison Member
Karma: 48
Posts: 1408
May all of your blinks be without delay
|
 |
« Reply #4 on: January 10, 2013, 09:45:38 am » |
You are working out which way the encoder is turning but you do nothing when you you know except changing the value of encoder0Pos. How about something like this n = digitalRead(encoder0PinA); if ((encoder0PinALast == HIGH) && (n == LOW)) { if (digitalRead(encoder0PinB) == LOW) { lastButtonPushed = buttonPinLeft; } else { lastButtonPushed = buttonPinRight; } encoder0PinALast = n; } You seem to have tried to do something with the value of encoder0Pos but if (encoder0Pos++); is not testing whether its value has changed When you get this working I suggest that you tidy up the variable and function names to remove confusion about whether buttons are being pressed or the encoder is being rotated.
|
|
|
|
|
Logged
|
|
|
|
|
London-UK
Offline
Jr. Member
Karma: 0
Posts: 67
|
 |
« Reply #5 on: January 10, 2013, 10:28:38 am » |
You seem to have tried to do something with the value of encoder0Pos but it is not testing whether its value has changed if (encoder0Pos++);
Do i need to put some code here for this to work or do I leave it as case buttonPinRight: //??????? menu.moveRight(); break;
case buttonPinLeft: //?????? menu.moveLeft(); break;
lastButtonPushed=0; //reset the lastButtonPushed variable }
thanks for the help I am begining to see the wood through the trees. I will tidy up variable and function names when I have a working code
|
|
|
|
|
Logged
|
|
|
|
|
East Anglia (UK)
Offline
Edison Member
Karma: 48
Posts: 1408
May all of your blinks be without delay
|
 |
« Reply #6 on: January 10, 2013, 01:07:45 pm » |
No need for anything to go there. You will have already determined that the encoder is moving and which way and just need to act on it.
Once it works save that version and set about tidying it up in a new sketch. Even if it works then there is plenty that you could do as it seems quite tangled at the moment.
|
|
|
|
|
Logged
|
|
|
|
|
London-UK
Offline
Jr. Member
Karma: 0
Posts: 67
|
 |
« Reply #7 on: January 10, 2013, 06:53:44 pm » |
I can see what Its trying to do but cant code what it needs to do. No matter what I do I cant get his to work. I've tried so many ways, i'm out of Ideas and feel I need to come up with a third option for the menu using a different encoder sketch. Which is not going to help me as I will be back to square one. This is my entire sketch. I have a rotary encoder with pushbutton and one external button that is the exit menu. Thanks for all the help everyone but even now I still dont understand it. Is there a level under noob.  #include <MenuBackend.h> //MenuBackend library - copyright by Alexander Brevig #include <LiquidCrystal.h> //this library is included in the Arduino IDE
int encoder0PinA = 2; int encoder0PinB =3; int encoder0Pos = 0; int encoder0PinALast = LOW; int n = HIGH;
const int encoderRight = ?????; //what should go here???? const int encoderLeft = ??????;// and here ???? const int buttonPinEsc = 42; const int encoderPushButton = 45; // pin for the Enter button
int lastButtonPushed = 0;
LiquidCrystal lcd(7,8,9,10,11,12);
//Menu variables MenuBackend menu = MenuBackend(menuUsed,menuChanged);
//initialize menuitems MenuItem menuLcd = MenuItem("menuLcd");// first menu item MenuItem menuItemOn = MenuItem("menuItemOn");// sub menu MenuItem menuItemOff = MenuItem("menuItemOff");// sub menu
MenuItem menuSetClock = MenuItem("menuSetClock");// 2nd menu item MenuItem menuItemHr = MenuItem("menuItemHr");// sub menu MenuItem menuItemMin = MenuItem("menuItemMin");//sub menu MenuItem menuItemSec = MenuItem("menuItemSec");//sub menu MenuItem menuItemConfirm = MenuItem("menuItemConfirm");//sub menu
MenuItem menuSetDate = MenuItem("menuSetDate");// 2nd menu item MenuItem menuItemDay = MenuItem("menuItemDay");// sub menuu MenuItem menuItemMonth = MenuItem("menuItemMonth");//sub menu MenuItem menuItemYear = MenuItem("menuItemYear");//sub menu
MenuItem menuExit = MenuItem("menuExit");// 3rdh menu item
void setup() { pinMode(encoderRight, INPUT); pinMode(encoderLeft, INPUT); pinMode(encoderPushButton, INPUT); pinMode(buttonPinEsc, INPUT); pinMode (encoder0PinA,INPUT); pinMode (encoder0PinB,INPUT);
lcd.begin(16, 2);
//configure menu lcd.setCursor(0,1); menu.getRoot().addRight(menuLcd).addRight(menuSetClock).addRight(menuSetDate);//set main menu items menuLcd.add(menuItemOn).addRight(menuItemOff);// add first sub menu then addright additional sub menues for that menu menuSetClock.add(menuItemHr).addRight(menuItemMin).addRight(menuItemSec).addRight(menuItemConfirm);// add first sub menu then addright additional sub menues for that menu menuSetDate.add(menuItemDay).addRight(menuItemMonth).addRight(menuItemYear);// add first sub menu then addright additional sub menues for that menu menu.toRoot(); }
void loop() { //readButtons(); //I splitted button reading and navigation in two procedures because navigateMenus(); //in some situations I want to use the button for other purpose (eg. to change some settings) n = digitalRead(encoder0PinA); if ((encoder0PinALast == HIGH) && (n == LOW)) { if (digitalRead(encoder0PinB) == LOW) { lastButtonPushed = encoderRight;//encoder0Pos--; }
else { lastButtonPushed = encoderLeft;//encoder0Pos++; }
encoder0PinALast = n; } }
void menuChanged(MenuChangeEvent changed){
MenuItem newMenuItem=changed.to; //get the destination menu
lcd.setCursor(0,0); //set the start position for lcd printing to the second row
if(newMenuItem.getName()==menu.getRoot()) { lcd.print("Main Menu "); } //menu lcd else if(newMenuItem.getName()=="menuLcd"){ lcd.clear(); lcd.print("Lcd"); } else if(newMenuItem.getName()=="menuItemOn"){ lcd.clear(); lcd.setCursor(0,1); lcd.print("On"); } else if(newMenuItem.getName()=="menuItemOff"){ lcd.clear(); lcd.setCursor(0,1); lcd.print("Off");
} //menu set clock
else if(newMenuItem.getName()=="menuSetClock"){ lcd.clear(); lcd.print("Set Clock"); } else if(newMenuItem.getName()=="menuItemHr"){ lcd.clear(); lcd.setCursor(0,1); lcd.print("Hr"); } else if(newMenuItem.getName()=="menuItemMin"){ lcd.clear(); lcd.setCursor(0,1); lcd.print("Min"); } else if(newMenuItem.getName()=="menuItemSec"){ lcd.clear(); lcd.setCursor(0,1); lcd.print("Sec"); } else if(newMenuItem.getName()=="menuItemConfirm"){ lcd.clear(); lcd.print("Confirmed"); } //menu set date
else if(newMenuItem.getName()=="menuSetDate"){ lcd.clear(); lcd.print("Set Date"); } else if(newMenuItem.getName()=="menuItemDay"){ lcd.clear(); lcd.print("Set Day"); } else if(newMenuItem.getName()=="menuItemMonth"){ lcd.clear(); lcd.print("Set Month"); } else if(newMenuItem.getName()=="menuItemYear"){ lcd.clear(); lcd.print("Set Year"); } //menu exit else if(newMenuItem.getName()=="menuExit"){ lcd.clear(); lcd.print("Exit"); } }
void menuUsed(MenuUseEvent used){ //**if you have a function call it here** if( used.item == menuItemOn ){ lcd.display(); //digitalWrite(10, HIGH); //delay(3000); //digitalWrite(10, LOW); lcd.clear(); menu.toRoot(); } if ( used.item == menuItemOff ){ lcd.noDisplay();//your code here menu.toRoot(); } //etc. }
void navigateMenus() { MenuItem currentMenu=menu.getCurrent();
switch (lastButtonPushed){ digitalWrite (ledPin, HIGH);
case encoderPushButton: // enter pin this is set up to use a push button BUT need it to use PUSH BUTTON ON ENCODER if (!(currentMenu.moveDown())){ //if the current menu has a child and enter has been pressed then navigate menu to item below menu.use();
} else{ //otherwise, if menu has no child and enter has been pressed---- the current menu is used menu.moveDown(); } break; case encoderRight: menu.moveRight(); break; case encoderLeft: menu.moveLeft(); break;
case buttonPinEsc: //not Set up yet but this will have a push button lcd.clear(); menu.toRoot(); //back to main break;
lastButtonPushed=0; //reset the lastButtonPushed variable } }
|
|
|
|
« Last Edit: January 10, 2013, 06:57:02 pm by mark7w »
|
Logged
|
|
|
|
|
East Anglia (UK)
Offline
Edison Member
Karma: 48
Posts: 1408
May all of your blinks be without delay
|
 |
« Reply #8 on: January 11, 2013, 04:56:21 am » |
You have started to tidy up the code as well as using the encoder to fool the program into thinking that buttons have been pressed which has confused things somewhat.
In post 5 I suggested setting the value of LastButtonPushed to buttonPinRight or buttonPinLeft when the encoder moved. You could then use the same code as you did to respond to the fake button presses. What you have done is to set LastButtonPressed to encoderRight or encoderLeft. That is a start at tidying up. It should still work, but in setup() you need to set encoderRight and encoderLeft to the values that buttonPinRight and buttonPinLeft would return when the button(s) are pressed.
NOTE - I have not checked any other parts of your code to see if you have changed anything else.
|
|
|
|
|
Logged
|
|
|
|
|
London-UK
Offline
Jr. Member
Karma: 0
Posts: 67
|
 |
« Reply #9 on: January 11, 2013, 11:54:17 am » |
I have just added some brackets and encoder0Pos-- and encoder0Pos++ and it worked. void loop() {
n = digitalRead(encoder0PinA);// value of n = n is default LOW if ((encoder0PinALast == HIGH) && (n == LOW)) // int encoder0PinALast default LOW { if (digitalRead(encoder0PinB) == LOW) { if(lastButtonPushed = buttonPinLeft) encoder0Pos--; }
else if (lastButtonPushed = buttonPinRight) encoder0Pos++; }
encoder0PinALast = n;
navigateMenus(); //in some situations I want to use the button for other purpose (eg. to change some settings) readButtons(); //I splitted button reading and navigation in two procedures because }
ONE thing about this is that I have PINS assisigned to 43 and 45 for "buttonPinLeft" and "buttonPinRight". I can remove the wire connections for these and it still works but I have lost the use of TWO pins? If I remove 43 and 45 to become const int encoderLeftRotation; const int encoderRightRotation; I get an uninitialized error. Any Ideas on this...............anyone! UKHeliBob as a reward for all your help Karma is duly awarded.
|
|
|
|
« Last Edit: January 11, 2013, 01:01:14 pm by mark7w »
|
Logged
|
|
|
|
|
East Anglia (UK)
Offline
Edison Member
Karma: 48
Posts: 1408
May all of your blinks be without delay
|
 |
« Reply #10 on: January 11, 2013, 03:54:33 pm » |
A const is designed to hold a value that will not change, ie it is constant, so you cannot have a const with no value, hence the error. If you set encoderLeftRotation and encoderRightRotation to 43 and 45 respectively that has nothing to do with using pins 43 and 45 so you could use them for something else.
Can you please post your whole code as it is now ?
|
|
|
|
|
Logged
|
|
|
|
|
London-UK
Offline
Jr. Member
Karma: 0
Posts: 67
|
 |
« Reply #11 on: January 11, 2013, 08:35:07 pm » |
Hers my code. I had to split it in half as the character count exceeds forum limit. now using PINS 42 and 49 as mega board pin to slack. /* This is a Test of a menu and Encoder to be used in a bigger project. I am building it in modules so I can test each one. This module is As. A lcd displayed Menu System using a rotary encoder to navigate the menu system. The "void menuUsed(MenuUseEvent used)" is where I will call functions related to the menu. At present I have just explored turning the lcd light On and Off. The menu is self explanatory and functions to this will follw. */
#include <MenuBackend.h> //MenuBackend library - copyright by Alexander Brevig #include <LiquidCrystal.h> //this library is included in the Arduino IDE
int ledPin = 13; int val; int encoder0PinA = 2;// pin A signal on encoder int encoder0PinB =3;// pin B signal on encoder int encoder0Pos = 0; int encoder0PinALast = LOW; int n = HIGH; LiquidCrystal lcd(7,8,9,10,11,12);
const int encoderLeftRotation = 44; // pin for the Up button const int encoderRightRotation = 46; // pin for the Down button const int encoderPushButton = 49; // pin for the Enter button const int buttonPinEsc = 42; // pin for the Esc button
int lastButtonPushed = HIGH;
int lastEncoderButtonState = LOW; // the previous reading from the Enter input pin int lastButtonEscState = LOW; // the previous reading from the Esc input pin int lastRotationLeftState = LOW; // the previous reading from the Left input pin int lastRotationRightState = LOW; // the previous reading from the Right input pin
long lastEnterDebounceTime = 0; // the last time the output pin was toggled long lastEscDebounceTime = 0; // the last time the output pin was toggled long lastLeftDebounceTime = 0; // the last time the output pin was toggled long lastRightDebounceTime = 0; // the last time the output pin was toggled long debounceDelay = 15; // the debounce time was 100
//Menu variables MenuBackend menu = MenuBackend(menuUsed,menuChanged);
//initialize menuitems MenuItem menuLcd = MenuItem("menuLcd");// first menu item MenuItem menuItemOn = MenuItem("menuItemOn");// sub menu MenuItem menuItemOff = MenuItem("menuItemOff");// sub menu
MenuItem menuSetClock = MenuItem("menuSetClock");// 2nd menu item MenuItem menuItemHr = MenuItem("menuItemHr");// sub menu MenuItem menuItemMin = MenuItem("menuItemMin");//sub menu MenuItem menuItemSec = MenuItem("menuItemSec");//sub menu MenuItem menuItemConfirm = MenuItem("menuItemConfirm");//sub menu
MenuItem menuSetDate = MenuItem("menuSetDate");// 2nd menu item MenuItem menuItemDay = MenuItem("menuItemDay");// sub menuu MenuItem menuItemMonth = MenuItem("menuItemMonth");//sub menu MenuItem menuItemYear = MenuItem("menuItemYear");//sub menu
MenuItem menuSetPhone = MenuItem("menuSetPhone");// 3rd menu item MenuItem menuItemNumber = MenuItem("menuItemNumber");// sub menu
MenuItem menuSetPin = MenuItem("menuSetPin");// 4th menu item MenuItem menuItemPin = MenuItem("menuItemPin");// sub menuu
MenuItem menuSms = MenuItem("menuSms");// 5th menu item MenuItem menuItemSigStr = MenuItem("menuItemSigStr");// sub menu MenuItem menuItemBalance = MenuItem("menuItemBalance");// sub menuu MenuItem menuItemTest = MenuItem("menuItemTest");// sub menuu
MenuItem menuExit = MenuItem("menuExit");// 6th menu item
void setup() { lcd.begin(16, 2); pinMode(encoderLeftRotation, INPUT); pinMode(encoderRightRotation, INPUT); pinMode(encoderPushButton, INPUT); pinMode(buttonPinEsc, INPUT); pinMode (encoder0PinA,INPUT); pinMode (encoder0PinB,INPUT);
//configure menu lcd.setCursor(0,1); menu.getRoot().addRight(menuLcd).addRight(menuSetClock).addRight(menuSetDate).addRight(menuSetPhone).addRight(menuSetPin).addRight(menuSms).addRight(menuExit);//set main menu items menuLcd.add(menuItemOn).addRight(menuItemOff);// add first sub menu then addright additional sub menues for that menu menuSetClock.add(menuItemHr).addRight(menuItemMin).addRight(menuItemSec).addRight(menuItemConfirm);// add first sub menu then addright additional sub menues for that menu menuSetDate.add(menuItemDay).addRight(menuItemMonth).addRight(menuItemYear);// add first sub menu then addright additional sub menues for that menu menuSetPhone.add(menuItemNumber); menuSetPin.add(menuItemPin); menuSms.add(menuItemSigStr).addRight(menuItemBalance).addRight(menuItemTest); menuExit.add(menuExit); menu.toRoot(); }
void loop() { n = digitalRead(encoder0PinA);// value of n = n is default LOW if ((encoder0PinALast == HIGH) && (n == LOW)) // int encoder0PinALast default LOW { if (digitalRead(encoder0PinB) == LOW) { if(lastButtonPushed = encoderLeftRotation) encoder0Pos--; } else if
(lastButtonPushed = encoderRightRotation) encoder0Pos++; } encoder0PinALast = n;
navigateMenus(); //in some situations I want to use the button for other purpose (eg. to change some settings) readButtons(); //I splitted button reading and navigation in two procedures because }
join up to next post.
|
|
|
|
|
Logged
|
|
|
|
|
London-UK
Offline
Jr. Member
Karma: 0
Posts: 67
|
 |
« Reply #12 on: January 11, 2013, 08:36:43 pm » |
here the rest of the code. //Debouncing also- hardware Debounce inplace void readButtons(){ //read buttons status
int reading; int buttonEnterState=LOW; // the current reading from the Enter input pin int buttonEscState=LOW; // the current reading from the input pin int buttonLeftState=LOW; // the current reading from the input pin int buttonRightState=LOW; // the current reading from the input pin
//Enter button reading = digitalRead(encoderPushButton);// read the state of the switch into a local variable: if (reading != lastEncoderButtonState) {// If the switch changed, due to noise or pressing: lastEnterDebounceTime = millis(); // reset the debouncing timer } if ((millis() - lastEnterDebounceTime) > debounceDelay) { // whatever the reading is at, it's been there for longer than the debounce delay, so take it as the actual current state: buttonEnterState=reading; lastEnterDebounceTime=millis(); } lastEncoderButtonState = reading;// save the reading. Next time through the loop, it'll be the lastButtonState:
//Esc button reading = digitalRead(buttonPinEsc);// read the state of the switch into a local variable: if (reading != lastButtonEscState) {// If the switch changed, due to noise or pressing: lastEscDebounceTime = millis();// reset the debouncing timer } if ((millis() - lastEscDebounceTime) > debounceDelay) { // whatever the reading is at, it's been there for longer than the debounce delay, so take it as the actual current state: buttonEscState = reading; lastEscDebounceTime=millis(); } lastButtonEscState = reading;// save the reading. Next time through the loop, it'll be the lastButtonState:
//Right or Down button reading = digitalRead(encoderRightRotation);// read the state of the switch into a local variable if (reading != lastRotationRightState) {//last button state is defaulted int LOW lastRightDebounceTime = millis();// reset the debouncing timer } if ((millis() - lastRightDebounceTime) > debounceDelay) { // whatever the reading is at, it's been there for longer than the debounce delay, so take it as the actual current state: buttonRightState = reading; lastRightDebounceTime =millis(); } lastRotationRightState = reading; // save the reading. Next time through the loop, it'll be the lastButtonState:
//Left or Up button reading = digitalRead(encoderLeftRotation);// read the state of the switch into a local variable: if (reading != lastRotationLeftState) {// If the switch changed, due to noise or pressing: lastLeftDebounceTime = millis();// reset the debouncing timer } if ((millis() - lastLeftDebounceTime) > debounceDelay) { // whatever the reading is at, it's been there for longer than the debounce delay, so take it as the actual current state: buttonLeftState = reading; lastLeftDebounceTime=millis(); } lastRotationLeftState = reading; // save the reading. Next time through the loop, it'll be the lastButtonState:
//records which button has been pressed if (buttonEnterState==HIGH){ lastButtonPushed=encoderPushButton; } else if(buttonEscState==HIGH){ lastButtonPushed=buttonPinEsc; } else if(buttonRightState==HIGH){ lastButtonPushed=encoderRightRotation; } else if(buttonLeftState==HIGH){ lastButtonPushed=encoderLeftRotation; } else{ lastButtonPushed=0; } }
void menuChanged(MenuChangeEvent changed){
MenuItem newMenuItem=changed.to; //get the destination menu
lcd.setCursor(0,0); //set the start position for lcd printing to the second row
if(newMenuItem.getName()==menu.getRoot()) { lcd.print("Main Menu "); } //menu lcd else if(newMenuItem.getName()=="menuLcd"){ lcd.clear(); lcd.print("Lcd"); } else if(newMenuItem.getName()=="menuItemOn"){ lcd.clear(); lcd.setCursor(0,1); lcd.print("On"); } else if(newMenuItem.getName()=="menuItemOff"){ lcd.clear(); lcd.setCursor(0,1); lcd.print("Off"); }
//menu set clock else if(newMenuItem.getName()=="menuSetClock"){ lcd.clear(); lcd.print("Set Clock"); } else if(newMenuItem.getName()=="menuItemHr"){ lcd.clear(); lcd.setCursor(0,1); lcd.print("Hr"); } else if(newMenuItem.getName()=="menuItemMin"){ lcd.clear(); lcd.setCursor(0,1); lcd.print("Min"); } else if(newMenuItem.getName()=="menuItemSec"){ lcd.clear(); lcd.setCursor(0,1); lcd.print("Sec"); } else if(newMenuItem.getName()=="menuItemConfirm"){ lcd.clear(); lcd.print("Confirmed"); }
//menu set date else if(newMenuItem.getName()=="menuSetDate"){ lcd.clear(); lcd.print("Set Date"); } else if(newMenuItem.getName()=="menuItemDay"){ lcd.clear(); lcd.print("Set Day"); } else if(newMenuItem.getName()=="menuItemMonth"){ lcd.clear(); lcd.print("Set Month"); } else if(newMenuItem.getName()=="menuItemYear"){ lcd.clear(); lcd.print("Set Year"); }
//menu set phone number else if(newMenuItem.getName()=="menuSetPhone"){ lcd.clear(); lcd.print("Set Phone"); }
//menu set pin number else if(newMenuItem.getName()=="menuSetPin"){ lcd.clear(); lcd.print("Set Pin"); }
//menu set sms else if(newMenuItem.getName()=="menuSms"){ lcd.clear(); lcd.print("Sms "); } else if(newMenuItem.getName()=="menuItemSigStr"){ lcd.clear(); lcd.print("Signal Stre"); } else if(newMenuItem.getName()=="menuItemBalance"){ lcd.clear(); lcd.print("Balance"); } else if(newMenuItem.getName()=="menuItemTest"){ lcd.clear(); lcd.print("Test Sms"); }
//menu exit to time else if(newMenuItem.getName()=="menuExit"){ lcd.clear(); lcd.print("Exit"); } }
void menuUsed(MenuUseEvent used){ //**if you have a function call it here** if( used.item == menuItemOn ){ lcd.display(); //digitalWrite(10, HIGH); //delay(3000); //digitalWrite(10, LOW); lcd.clear(); menu.toRoot(); } if ( used.item == menuItemOff ){ lcd.noDisplay();//your code here menu.toRoot(); } //etc. }
void navigateMenus() {
MenuItem currentMenu=menu.getCurrent();
switch (lastButtonPushed){ case encoderPushButton: // enter pin if(!(currentMenu.moveDown())){ //if the current menu has a child and enter has been pressed then navigate menu to item below menu.use(); } else{ //otherwise, if menu has no child and enter has been pressed---- the current menu is used menu.moveDown(); } break; case buttonPinEsc: menu.toRoot(); //back to main break; case encoderRightRotation: menu.moveRight(); break; case encoderLeftRotation: menu.moveLeft(); break; }
lastButtonPushed=0; //reset the lastButtonPushed variable }
I still would like to remove const int encoderLeftRotation = 44; // pin for the Up button const int encoderRightRotation = 46; // pin for the Down button
I have tried to remove it but my code fails if I do? even thou they're not wired up? Is the a way rount this?
|
|
|
|
« Last Edit: January 11, 2013, 08:42:15 pm by mark7w »
|
Logged
|
|
|
|
|
East Anglia (UK)
Offline
Edison Member
Karma: 48
Posts: 1408
May all of your blinks be without delay
|
 |
« Reply #13 on: January 12, 2013, 03:29:23 am » |
Mark - this is difficult for me to help with in detail because I don't have the same hardware as you and my Arduino is tied up with a project of my own. I think that the time has come for you to step back and start again. Load the menu navigation sketch that works with buttons and save it with a new name. Copy the encoder declarations and pin setup into the new sketch to create the variables. Make a new function in the sketch called readEncoder() void readEncoder() //read the encoder and set lastButtonPushed to values used by navigateMenu() { n = digitalRead(encoder0PinA); if ((encoder0PinALast == HIGH) && (n == LOW)) { if (digitalRead(encoder0PinB) == LOW) { lastButtonPushed = 46; } else { lastButtonPushed = 44; } } encoder0PinALast = n; } At this point the sketch should still work with buttons as it is not reading the encoder. Fix any compile errors. Change the readButtons() function to read only the button on the encoder and to leave lastButtonPushed alone unless it was pushed. Now, before you call navigateMenu() in loop() call readButtons() and readEncoder() readEncoder() will set lasButtonPushed to 44 or 46 if the encoder has moved and navigateMenu() will interpret that as a button push. Try this much and let us know how you get on. As I said before, once this works you can tidy up. For instance, readEncoder() could read the button as well.
|
|
|
|
|
Logged
|
|
|
|
|
London-UK
Offline
Jr. Member
Karma: 0
Posts: 67
|
 |
« Reply #14 on: January 12, 2013, 12:23:05 pm » |
I have made the changes you advised and it's working perfectly. Here is the new code split again. I have tided it up too, so I think? /* This is a Test of a menu and Encoder to be used in a bigger project. I am building it in modules so I can test each one. This module is As. A lcd displayed Menu System using a rotary encoder to navigate the menu system. The "void menuUsed(MenuUseEvent used)" is where I will call functions related to the menu. At present I have just explored turning the lcd light On and Off. The menu is self explanatory and functions to this will follw. */
#include <MenuBackend.h> //MenuBackend library - copyright by Alexander Brevig #include <LiquidCrystal.h> //this library is included in the Arduino IDE
const int encoderPushButton = 45; // pin for the Enter button const int buttonPinEsc = 42; // pin for the Esc button
int encoder0PinA = 2; int encoder0PinB = 3; int encoder0Pos = 0; int encoder0PinALast = LOW; int n = HIGH; int lastButtonPushed = 0; int lastButtonEnterState = LOW; // the previous reading from the Enter input pin int lastButtonEscState = LOW; // the previous reading from the Esc input pin long lastEnterDebounceTime = 0; // the last time the output pin was toggled long lastEscDebounceTime = 0; // the last time the output pin was toggled long debounceDelay = 150; // the debounce time
LiquidCrystal lcd(7,8,9,10,11,12);
//Menu variables MenuBackend menu = MenuBackend(menuUsed,menuChanged);
//initialize menuitems MenuItem menuLcd = MenuItem("menuLcd"); // first menu item MenuItem menuItemOn = MenuItem("menuItemOn"); // sub menu MenuItem menuItemOff = MenuItem("menuItemOff"); // sub menu MenuItem menuSetClock = MenuItem("menuSetClock"); // 2nd menu item MenuItem menuItemHr = MenuItem("menuItemHr"); // sub menu MenuItem menuItemMin = MenuItem("menuItemMin"); //sub menu MenuItem menuItemSec = MenuItem("menuItemSec"); //sub menu MenuItem menuItemConfirm = MenuItem("menuItemConfirm"); //sub menu MenuItem menuSetDate = MenuItem("menuSetDate"); // 2nd menu item MenuItem menuItemDay = MenuItem("menuItemDay"); // sub menuu MenuItem menuItemMonth = MenuItem("menuItemMonth"); //sub menu MenuItem menuItemYear = MenuItem("menuItemYear"); //sub menu MenuItem menuSetPhone = MenuItem("menuSetPhone"); // 3rd menu item MenuItem menuItemNumber = MenuItem("menuItemNumber"); // sub menu MenuItem menuSetPin = MenuItem("menuSetPin"); // 4th menu item MenuItem menuItemPin = MenuItem("menuItemPin"); // sub menuu MenuItem menuSms = MenuItem("menuSms"); // 5th menu item MenuItem menuItemSigStr = MenuItem("menuItemSigStr"); // sub menu MenuItem menuItemBalance = MenuItem("menuItemBalance"); // sub menuu MenuItem menuItemTest = MenuItem("menuItemTest"); // sub menuu MenuItem menuExit = MenuItem("menuExit"); // 6th menu item
void setup() { pinMode(encoderPushButton, INPUT); pinMode(buttonPinEsc, INPUT);
pinMode (encoder0PinA,INPUT); pinMode (encoder0PinB,INPUT); Serial.begin (9600);
lcd.begin(16, 2);
//configure menu lcd.setCursor(0,1); menu.getRoot().addRight(menuLcd).addRight(menuSetClock).addRight(menuSetDate).addRight(menuSetPhone).addRight(menuSetPin).addRight(menuSms).addRight(menuExit); //set main menu items menuLcd.add(menuItemOn).addRight(menuItemOff); // add first sub menu then addright additional sub menues for that menu menuSetClock.add(menuItemHr).addRight(menuItemMin).addRight(menuItemSec).addRight(menuItemConfirm); // add first sub menu then addright additional sub menues for that menu menuSetDate.add(menuItemDay).addRight(menuItemMonth).addRight(menuItemYear); // add first sub menu then addright additional sub menues for that menu menuSetPhone.add(menuItemNumber); menuSetPin.add(menuItemPin); menuSms.add(menuItemSigStr).addRight(menuItemBalance).addRight(menuItemTest); menuExit.add(menuExit); menu.toRoot(); }
void loop() { readButtons(); //I splitted button reading and navigation in two procedures because readEncoder(); navigateMenus(); //in some situations I want to use the button for other purpose (eg. to change some settings) }
void readButtons() //read buttons status { int reading; int buttonEnterState=LOW; // the current reading from the Enter input pin int buttonEscState=LOW; // the current reading from the input pin
//ENTER BUTTON DEBOUNCE
reading = digitalRead(encoderPushButton); // read the state of the switch into a local variable:
if (reading != lastButtonEnterState) // If the switch changed, due to noise or pressing: { lastEnterDebounceTime = millis(); // reset the debouncing timer } if ((millis() - lastEnterDebounceTime) > debounceDelay) // whatever the reading is at, it's been there for longerthan the debounce delay, so take it as the actual current state: { buttonEnterState=reading; lastEnterDebounceTime=millis(); } lastButtonEnterState = reading; // save the reading. Next time through the loop, it'll be the lastButtonState:
//ESC BUTTON DEBOUNCE
reading = digitalRead(buttonPinEsc); // read the state of the switch into a local variable:
if (reading != lastButtonEscState) // If the switch changed, due to noise or pressing: { lastEscDebounceTime = millis(); // reset the debouncing timer } if ((millis() - lastEscDebounceTime) > debounceDelay)// whatever the reading is at, it's been there for longerthan the debounce delay, so take it as the actual current state: { buttonEscState = reading; lastEscDebounceTime=millis(); } lastButtonEscState = reading; // save the reading. Next time through the loop, it'll be the lastButtonState:
//Records which button has been pressed if (buttonEnterState==HIGH){ lastButtonPushed=encoderPushButton; } else if(buttonEscState==HIGH){ lastButtonPushed=buttonPinEsc; } else{ lastButtonPushed=0; } }
void readEncoder() //read the encoder and set lastButtonPushed to values used by navigateMenu() { n = digitalRead(encoder0PinA); if ((encoder0PinALast == HIGH) && (n == LOW)) { if (digitalRead(encoder0PinB) == LOW) { lastButtonPushed = 46; } else { lastButtonPushed = 44; } } encoder0PinALast = n; }
For instance, readEncoder() could read the button as well. Do I have to move ALL my button bounce code to "Read encoder" as well? what about the separate "Esc button" does that move there too.
|
|
|
|
« Last Edit: January 15, 2013, 10:34:20 am by mark7w »
|
Logged
|
|
|
|
|
|