Coder Social home page Coder Social logo

Comments (24)

neu-rah avatar neu-rah commented on May 13, 2024
  Hi,
  Just don't call the menu function on your loop and clear the
  screen


  Às 19:08 de 30-08-2015, graziano71 escreveu:


  Hello! Really great library, I tested with arduino nano+serial
    1604 display and encoder with button and it works very well! 
    More than the issue already reported few days ago by lfc7 on
    menu refresh, which I haven't solved as well, I am wondering if
    there is any "embedded mechanism" to exit from main menu, and in
    such a case, how to re-enter.
    Currently I have simply included an "Exit" menu option calling
    an exit function which prevent menu to be called in void loop().
    Thanks!
  —
    Reply to this email directly or view
      it on GitHub.

from arduinomenu.

graziano71 avatar graziano71 commented on May 13, 2024

thanks for quick feedback! the problem in clearing the screen is that when the menu is called again in the loop, it doesn't show up until the encoder is moved again and the menu is redrawed. any suggestion to make it appear again without moving within menu options? thanks!!

from arduinomenu.

neu-rah avatar neu-rah commented on May 13, 2024
hi!

  try this:
  «lcd».drawn=NULL;

  «lcd» being your menuOut object


  Às 21:28 de 01-09-2015, graziano71 escreveu:


  thanks for quick feedback! the problem in clearing the screen
    is that when the menu is called again in the loop, it doesn't
    show up until the encoder is moved again and the menu is
    redrawed. any suggestion to make it appear again without moving
    within menu options? thanks!!
  —
    Reply to this email directly or view
      it on GitHub.

from arduinomenu.

graziano71 avatar graziano71 commented on May 13, 2024

It works! Thanks so much!
One last question: When I recall the Menu, it keeps the last position (Exit Option). Any suggestion on how to bring the cursor on top position when I recall the menu? Thanks once again.

from arduinomenu.

benovitch avatar benovitch commented on May 13, 2024

Hi Graziano,

I have the same problem as you. Is it possible to get your code that you used to solve this.

Ben

from arduinomenu.

nicodonte avatar nicodonte commented on May 13, 2024

Hi, have the same problem, when I recall the menu it keeps in the last position. How I put the cursor on the first item again? Thanks!!
Nico.

from arduinomenu.

benovitch avatar benovitch commented on May 13, 2024

Nico,

Together with a friend we came up with a solution to exit the menu and see other things on the LCD. and then go back to the menu when needed. I will try to post my code this evening.

from arduinomenu.

benovitch avatar benovitch commented on May 13, 2024

Here is the code I wrote for my CoG project.

#include <HardwareSerial.h>
#include <LiquidCrystal.h>
#include <menu.h>//menu macros and objects
#include <menuFields.h>
#include <pcint.h>//this is incompatible with software serial (arduino needs an handler!)
#include <quadEncoder.h>//quadrature encoder driver and fake stream
#include <keyStream.h>//keyboard driver and fake stream (for the encoder button)
#include <chainStream.h>// concatenate multiple input streams (this allows adding a button to the encoder)
#include <menuLCD.h>

LiquidCrystal lcd1(7, 6, 5, 4, 3, 2);

////////////////////////////////////////////
// ENCODER (aka rotary switch) PINS
// rotary
#define encA 8
#define encB 9
//this encoder has a button here
#define encBtn A0
#define sensorPin_LA A1 // gewichtssensoren
#define sensorPin_RA A2
#define sensorPin_Nose A3

int opdracht = 0;
//functions to wire as menu actions

//aux function
void nothing() {}

void Afzonderlijke_Gewichten(){opdracht = 1; lcd1.clear();} // Hier zijn alle afzonderlijke gewichten te zien
void calibLA(){opdracht = 2; lcd1.clear();} // voorlopig om te testen
void calibRA(){opdracht = 3; lcd1.clear();}
void calibNose(){opdracht = 4; lcd1.clear();}
void Totaal_Gewicht(){opdracht = 5; lcd1.clear();} // totaal gewicht toestel
void CGmeten(){opdracht = 6; lcd1.clear();} // Hier wordt het toe of af te trekken gewicht weergegeven op het corectiepunt CP

float Zwaartekracht =9.81;
int MainToNose =0;
int MainToCG=0;
int CoGToCP=0;

/////////////////////////////////////////////////////////////////////////
// MENU DEFINITION
// here we define the menu structure and wire actions functions to it
// empty options are just for scroll testing

MENU(Gewichten,"Gewichten",
OP("Gewichten",Afzonderlijke_Gewichten),
OP("Totaal Gewicht",Totaal_Gewicht)
);

MENU(Calibratie,"Calibratie",
OP("Calibratie LA",calibLA),
OP("Calibratie RA",calibRA),
OP("Calibratie Nose",calibNose)
);

MENU(Instellingen,"Instellingen", // Hier zijn de afstanden aan te passen van de onderlinge punten
FIELD(MainToNose,"Main to Nose","mm",-2000,2000,10,1,nothing),
FIELD(MainToCG,"Main to CG","mm",-2000,2000,10,1,nothing),
FIELD(CoGToCP,"CoG to CP","mm",-2000,2000,10,1,nothing)
);

MENU(Metingen,"Metingen",
OP("CG Meten",CGmeten),
SUBMENU(Gewichten)
);

MENU(Meten,"Metingen ",
SUBMENU(Metingen),
SUBMENU(Instellingen)
);

MENU(mainMenu,"Main menu",
SUBMENU(Meten),
SUBMENU(Calibratie)
);

//the quadEncoder
quadEncoder quadEncoder(encA,encB);//simple quad encoder driver
quadEncoderStream enc(quadEncoder,5);// simple quad encoder fake Stream

//a keyboard with only one key :D, this is the encoder button
keyMap encBtn_map[]={{-encBtn,menu::enterCode}};//negative pin numbers means we have a pull-up, this is on when low
keyLook<1> encButton(encBtn_map);

//multiple inputs allow conjugation of the quadEncoder with a single key keyboard that is the quadEncoder button
Stream* in[]={&enc,&encButton};
chainStream<2> quadEncoder_button(in);

//alternative to previous but now we can input from Serial too...
Stream* in3[]={&enc,&encButton,&Serial};
chainStream<3> allIn(in3);

//describing a menu output, alternatives so far are Serial or LiquidCrystal LCD
menuLCD lcd(lcd1,20,4);

/////////////////////////////////////////////////////////////////////////
void setup() {
quadEncoder.begin();
Serial.begin(9600);

lcd1.begin(20,4);
lcd1.clear();
lcd1.setCursor(3,1);
lcd1.print("CoG Calculator");
lcd1.setCursor(4,3);
lcd1.print("By Benovitch");
delay(3000);

pinMode(encBtn, INPUT);
digitalWrite(encBtn,1);

pinMode(sensorPin_LA, INPUT);
pinMode(sensorPin_RA, INPUT);
pinMode(sensorPin_Nose, INPUT);
}

///////////////////////////////////////////////////////////////////////////////
// testing the menu system
static unsigned long NextTrigger = 0;
int plotDelay = 200;
float Sens_LA = 0;
float Sens_RA = 0;
float Sens_Nose = 0;

void loop() {

float Gewicht_LA = 0;
float Gewicht_RA = 0;
float Gewicht_Nose = 0;
float Gewicht_MainGear = (Gewicht_LA + Gewicht_RA);
float Afstand_CGtoNose = (MainToNose - MainToCG);
float Totaal_Gewicht = (Gewicht_LA + Gewicht_RA + Gewicht_Nose);
float Moment_MGtoCG = ((Gewicht_MainGear * Zwaartekracht) * MainToCG);
float Moment_NGtoCG = ((Gewicht_Nose * Zwaartekracht) * Afstand_CGtoNose);
int Gewicht_CP = (((Moment_MGtoCG - Moment_NGtoCG)/(CoGToCP * Zwaartekracht))_1000) ; // Hiermee wordt het eiegnlijke gewicht op het CP berekend
//float Gewicht_CP = ((5000_9.81_4.5)-(1500_9.81_12))/(12_9.81);

switch (opdracht){
case 1: //Gewichten Meten
lcd1.setCursor(0,0);
lcd1.print("Gewichten");
lcd1.setCursor(0,1);
lcd1.print("LA: ");
lcd1.print(Gewicht_LA,3);
lcd1.print(" ");
lcd1.setCursor(0,2);
lcd1.print("RA: ");
lcd1.print(Gewicht_RA,3);
lcd1.print(" ");
lcd1.setCursor(0,3);
lcd1.print("Neus: ");
lcd1.print(Gewicht_Nose,3);
lcd1.print(" ");
break;

case 2:    //Calibreren
 lcd1.setCursor(0,0);
 lcd1.print("Calibreren LA");
 if (millis() > NextTrigger){
  Serial.println(Sens_LA);
  lcd1.setCursor(0,1);
  lcd1.print("Linksachter: ");
  lcd1.print(Sens_LA);
  lcd1.print("  "); 
 } 
 break;

 case 3:
 lcd1.setCursor(0,0);
 lcd1.print("Calibreren RA");
 if (millis() > NextTrigger){
  Serial.println(Sens_RA);
  lcd1.setCursor(0,1);
  lcd1.print("Rechtsachter: ");
  lcd1.print(Sens_RA);
  lcd1.print("  ");
  }
  break;

 case 4:
 lcd1.setCursor(0,0);
 lcd1.print("Calibreren Nose");
 if (millis() > NextTrigger){
  Serial.println(Sens_Nose);
  lcd1.setCursor(0,1);
  lcd1.print("Nose: ");
  lcd1.print(Sens_Nose);
  lcd1.print("  ");
  }
  break;

 case 5:
 /*lcd1.setCursor(0,0);
 lcd1.print("Gewicht");
 if (millis() > NextTrigger)*/{
  Serial.println(Totaal_Gewicht);
  lcd1.setCursor(0,0);
  lcd1.print("Totaal Gewicht: ");
  lcd1.setCursor(0,1);
  lcd1.print(Totaal_Gewicht,3);
  lcd1.print("  ");
  }
  break;

  case 6:
 lcd1.setCursor(0,0);
 lcd1.print("CG meten");
 if (millis() > NextTrigger){
  Serial.println(Gewicht_Nose,3);
  lcd1.setCursor(0,1);
  lcd1.print("Gewicht CP:");
  lcd1.print(Gewicht_CP);
  lcd1.print(" Gr");
  lcd1.print("    ");


  }
  break;

default:
 mainMenu.poll(lcd,allIn);
 break;
}

if (opdracht != 0) { // om vanuit de berekeningen terug naar het menu te gaan
int stateButton = digitalRead(encBtn);
if(stateButton == 0) {
opdracht = 0;
lcd1.clear();
lcd.drawn=NULL;
delay(500);
}
}

if (millis() > NextTrigger){
NextTrigger = (long)(millis() + plotDelay);
}
}

from arduinomenu.

nicodonte avatar nicodonte commented on May 13, 2024

Hi @benovitch, thanks for sharing your code, I have figured out how to refresh the menu when I go to a function, my question now is how I return to the top menu instead of the last item after that I have cleaned the screen. It seems always return to the last item selected when .drawn=NULL; is invoked.

from arduinomenu.

neu-rah avatar neu-rah commented on May 13, 2024

well, the philosophy was that your functions should return only when they are done, and you can have a loop on your functions... but if for some reason you wish to redraw or change focus then I've just added some new functions "redraw" and "focus" for that.

https://github.com/neu-rah/ArduinoMenu/wiki/Customizing-menus

from arduinomenu.

nicodonte avatar nicodonte commented on May 13, 2024

Thanks @neu-rah!!! I will test these new code tonight.

from arduinomenu.

nicodonte avatar nicodonte commented on May 13, 2024

hi @neu-rah, I can't make .focus work in my project. .redraw(); works perfect, I don't need lcd.clear(); menu_lcd.drawn=NULL; anymore. But with .focus(); allways shows me a compile error. I don't understand whats happends.

These are part of my code, tell me if a miss something or I'm doing something wrong:

#include <menu.h>//menu macros and objects
#include <menuLCDs.h>//F. Malpartida LCD's
#include <pcint.h>//this is incompatible with software serial (arduino needs an handler!)
#include <menuFields.h>
#include <quadEncoder.h>//quadrature encoder driver and fake stream
#include <keyStream.h>//keyboard driver and fake stream (for the encoder button)
#include <chainStream.h>// concatenate multiple input streams (this allows adding a button to the encoder)
#include <controls/common/menuTextFields.h>

menuLCD menu_lcd(lcd,20,3);//menu output device



void bklMenu(){
        menuSeleccion = 1;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("AJUSTAR  ILUMINACION");
        lcd.setCursor(0,3);
        lcd.print("(+/-)NIVEL (S)SALIR");

        do{
        if (bPlus.isPressed()) {bl+=5; bl = min (bl,255); analogWrite(6,bl); delay(50);}
        if (bMinus.isPressed()) {bl-=5; bl = max (bl,0); analogWrite(6,bl); delay (50);}
        if (bSelect.uniquePress()) menuSeleccion = 0;
        lbg.drawValue( bl, 255); 
        delay (100);
        } while (menuSeleccion != 0);
        //lcd.clear();
        //menu_lcd.drawn=NULL;
        menu_lcd.focus(1);
       menu_lcd.redraw();
}


MENU(configMenu, "Configuracion",
SUBMENU (relojMenu),
OP("Intensidad Display", bklMenu)
);

MENU(mainMenu,"Main",
SUBMENU(configMenu),
OP("Prueba A",clockMenu),
OP("Prueba B",clockMenu),
OP("Salir",exitMenu)
);



                 mainMenu.poll (menu_lcd, allIn , true);

This is the error in compiler windows:

Reloj_Nico_v2.ino: In function 'void bklMenu()':
Reloj_Nico_v2:537: error: 'class menuLCD' has no member named 'focus'
'class menuLCD' has no member named 'focus'

Thanks for your help!!
Regards,
Nico.

from arduinomenu.

neu-rah avatar neu-rah commented on May 13, 2024

focus is a member of menu, not from menuOut

it should be called from a menu
ex:

mainMenu.focus(2)

or

configMenu.focus(0)

from arduinomenu.

nicodonte avatar nicodonte commented on May 13, 2024

With:

        if (bPlus.isPressed()) {bl+=5; bl = min (bl,255); analogWrite(6,bl); delay(50);}
        if (bMinus.isPressed()) {bl-=5; bl = max (bl,0); analogWrite(6,bl); delay (50);}
        if (bSelect.uniquePress()) menuSeleccion = 0;
        lbg.drawValue( bl, 255); 
        delay (100);
        } while (menuSeleccion != 0);
        mainMenu.focus(1);
       menu_lcd.redraw();

Not working, now its show:

Reloj_Nico_v2.ino: In function 'void bklMenu()':
Reloj_Nico_v2:537: error: 'mainMenu' was not declared in this scope
'mainMenu' was not declared in this scope

from arduinomenu.

neu-rah avatar neu-rah commented on May 13, 2024

well you get that variable by declaring

MENU(mainMenu,"Main menu", ...

and it should be a global variable, no?
I mean the menu definition is NOT inside a function, right?

from arduinomenu.

nicodonte avatar nicodonte commented on May 13, 2024

I found my error, I declare MENU before void setup() but after my bklMenu() routine.

I move all the MENU declaration to the top of the project.

Now it works flawless!!! Thank you so much for your help!!
Regards,
Nico.

from arduinomenu.

neu-rah avatar neu-rah commented on May 13, 2024

great!
sory it took so long...

from arduinomenu.

graziano71 avatar graziano71 commented on May 13, 2024

Hi! Thanks for the precious update, the new functions works perfectly!

Here is my code for the "Button" function, meant to let the Menu appear when keeping it pressed for more than 2 seconds:

void Button(){

Serial.println(Counter-Timer1);
current = digitalRead(encBtn); // Read Encoder Button Status
if (current == LOW && previous == HIGH){ // Check Encoder Button changes status
previous = LOW;
Timer1 = millis(); //Takes note of the times of status change
}

if (current == LOW) { //Check Encoder button being kept pressed
Counter = millis(); //Counts ms of button kept pressed
} else if (current == HIGH){ // Reset Counters if button is released in the meantime
Counter=Timer1;
previous=HIGH;
}
if ((Counter - Timer1)>=2000) { //CHeck if button is pressed for more than 2sec
MenuActive=1; // Variable used in Loop to validate the menu call
GoOut=0; // Reset the variable used to exit menu
lcd.drawn=NULL; // Redraw the menu
mainMenu.focus(0); //Bring the menu focus to first position
}

if (current == HIGH){ // reset the counter if the button is not pressed
Counter = Timer1;
}

}

from arduinomenu.

neu-rah avatar neu-rah commented on May 13, 2024

thanks for sharing 👍

from arduinomenu.

nicodonte avatar nicodonte commented on May 13, 2024

Hi, could you make an example of:
menuNode::activeMenu;
menuNode::activeMenu->sel;

I can't figure out how to use it.

from arduinomenu.

graziano71 avatar graziano71 commented on May 13, 2024

Hello!

I noticed something strange happening when the menu is deactivated. If the encoder is rotated, then when the menu is re-called the encoder stream is executed in the menu. This is happening also if the menu is "focused" on a specific position through your last function. How to avoid that the encoder rotation is buffered by the encoder library? Thanks!

from arduinomenu.

neu-rah avatar neu-rah commented on May 13, 2024

yes, it should be like so as it is interrupt driven...
we can avoid that by calling flush() on the input stream...

enc.flush();//flush encoder position

not sure if on the quad encoder stream or on composed stream.

allIn.flush();//flush all input streams by consuming the input and ignore it

still we should have deactivated (ignored) input while the menu is suspended.
the quad encoder stream is storing only a position, so it can't become full, and the current keyboard stream is a fake stream it does not buffer input, only returns current button status.
But when using the menu over a serial terminal then buffers can get full.

from arduinomenu.

graziano71 avatar graziano71 commented on May 13, 2024

Clear, thanks!

I tried with

enc.flush();

and it works! :-) The Encoder stream is now ignored!

Thanks!!

Graziano

from arduinomenu.

neu-rah avatar neu-rah commented on May 13, 2024

menuNode::activeMenu; is a static member of class menuNode (base for all menus and fields)
it means (static) that there is only one definition of it for all menus. This works like a global variable of the class.
So no matter from what menu or field you read/write it, the same value is affected, in fact for being a static member you can access it with a menu or field (menuNode::activeMenu)
The value contained in it is a pointer to the currect active menu (the one that will receive the actions, and do output) or NULL if no menu is focused, on the last case the invoked menu will receive the input (input processing always start with a menu/field, normally mainMenu)

menuNode::activeMenu->sel; refers tho the current hilited element on the current focused menu/field

from arduinomenu.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.