(solved) reading 4 buttons by analog port

Hi,

I have to control a display driven menu by pushbuttons. Due to the fact I only want to use four wires remotely
1 for +
1 for -
1 for analog variable value
1 for analog value (pushbuttons)
I cant use digital inputs so I opted for the analog version to use 4 analog value buttons.
From all the snippets and samples found on the web I made a sketch that if it goes to work should be implemented in an other larger sketch.
But that is not working.
If one of the buttons are pressed there is no action at all.
Cant put my finger on it although it should be so simple.
Basic resistor ladder with pin pulled up by software resistor.

After a few hours by try and error I was chasing my own tail and had to call it a day.
Any suggestion to push me in the right direction would be appriciated.
Thanks, Paco

// +++++++ Libaries included
#include <Wire.h>
//INSERT ALL THE LIBARIES AFTER INCLUDING WIRE LIB (MENWIZ request) 
#include <LiquidCrystal_I2C.h>
#include <buttons.h>
#include <MENWIZ.h>
#include <EEPROM.h>

menwiz menu;
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Addr, En, Rw, Rs, d4, d5, d6, d7, backlightpin, polarity

int buttonValue;                      
volatile byte buttonAct = 0; // flag, follow button press
volatile byte buttonPressed = 0;  // which button was pressed
volatile byte lastButtonPressed = 0; // prev button pressed

void setup()
{
  Serial.begin(9600);
}

void loop()     
{
// NAVIGATION MANAGEMENT & DRAWING ON LCD. NOT BLOCKING has to be the first in the void loop
  menu.draw();  
  
  lastButtonPressed = buttonPressed;
  buttonValue = analogRead(0);   // read the input pin 0
  // internal 20K ohm pullup is enabled on analog pin 0 (54).
  
  if(buttonValue >= 920 and buttonValue <= 930 ) 
  {
    buttonPressed = 1;//Up button
  }
    else if(buttonValue >= 820 and buttonValue <= 835)
  {
    buttonPressed = 2; // Confirm button
  }
    else if(buttonValue >= 725 and buttonValue <= 740)
  {
    buttonPressed = 3; //Down button
  }
    else if(buttonValue >= 630 and buttonValue <= 645)
  {
    buttonPressed = 4; //Escape button
  }
    buttonAct = 1;
    navMenu();
}

//  ++++++ functions +++++++

int navMenu()
{    
  if(buttonAct)//true if button press not processed
  { 
    buttonAct = 0; // run once per button press
    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;
   }
  }
  else
  {
   return MW_BTNULL;
  }
}
volatile byte buttonAct = 0; // flag, follow button press
volatile byte buttonPressed = 0;  // which button was pressed
volatile byte lastButtonPressed = 0; // prev button pressed

Why are these declared volatile? I don't see any interrupts that could change these values.

  buttonValue = analogRead(0);   // read the input pin 0
  // internal 20K ohm pullup is enabled on analog pin 0 (54).

No, it isn't. The pullup resistors are only available on digital pins. When using analog and digital pins as analog pins, as you are doing here, the pullup resistors are not in effect. If you are trying to use the analog pin as a digital pin, you should be using the alias A0 and the digital functions. like digitalRead().

Given the rest of the code, though, that doesn't appear to be what you are doing, though, so the comment is crap.

Sure would be nice to know what value you read from the analog pin. To bad you have your LCD connected to the only serial port that you could use to tell you that. It would also be nice to know what value gets assigned to buttonPressed.

You haven't said anything at all about what is wired to analog pin 0. What value resistors are you using? How are the switches and resistors wired?

navMenu() returns a value that you discard. What's the purpose of calling the function at all? How do you know that this code is not working?

The pullup resistors are only available on digital pins.

well it is a little known fact that the pull ups are available to use on the analogue pins. However you are right in that the have not been enabled so the comment is not correct.

Yes I agree until we can see a diagram of how this is wired up it is hard to tell. While backbone might think he has fully described the circuit he has not described it in enough detail so that we can see if there is anything wrong.

well it is a little known fact that the pull ups are available to use on the analogue pins.

When used as analog pins? How would that work? What purpose would they serve?

First I apologize for the mess, I did this while now being at my work.

I undressed the orinigal large sketch to make it more viewer friendly, by this I accedently removed more then I needed.
One of that is the analog pin pulled up line. See the new code with the resitors located and the values they measure.
Now it makes sense I hope and the pin really has a purpose in this case with the resistors.
Analog values are correct and taken from serial monitor with other sample code but same resistor wiring.

As said code was mixed and twisted and massaged from several samples.
No problem to learn from my errors.

MW_BTU , MW_BTD etc ... are used for internal calls for menu navigation routine.

BTW "Mega" board used

// +++++++ Libaries included
#include <Wire.h>
//INSERT ALL THE LIBARIES AFTER INCLUDING WIRE LIB (MENWIZ request) 
#include <LiquidCrystal_I2C.h>
#include <buttons.h>
#include <MENWIZ.h>
#include <EEPROM.h>

menwiz menu;
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Addr, En, Rw, Rs, d4, d5, d6, d7, backlightpin, polarity

int buttonValue;                      
byte buttonAct = 0; // flag, follow button press
byte buttonPressed = 0;  // which button was pressed
byte lastButtonPressed = 0; // prev button pressed

/*
 *
 *   analogPin                 
 *      |                      
 *      |                      
 *      ----------------          
 *                     |       
 *                     |____ \____
 *                     |   SW1    |
 *                     |          \
 *                     |          /   
 *                     |          \    1K
 *                     |          /
 *                     |          \
 *                     |____ \____|
 *                     |   SW2    |
 *                     |          |
 *                     |          \
 *                     |          /   
 *                     |          \    1K
 *                     |          /
 *                     |          \
 *                     |____ \____|
 *                     |   SW3    |
 *                     |          |
 *                     |          \
 *                     |          /   
 *                     |          \    1K
 *                     |          /
 *                     |          \
 *                     |____ \____|
 *                         SW4    |
 *                                |
 *                                \
 *                                /
 *                                \     1K
 *                                /
 *                                \
 *                                |
 *                              _____   
 *                               ___     ground
 *                                _
 *
 */



void setup()
{
  Serial.begin(9600);
  digitalWrite((54), HIGH);  // enable the 20k internal pullup for MEGA board
}

void loop()     
{
// NAVIGATION MANAGEMENT & DRAWING ON LCD. NOT BLOCKING has to be the first in the void loop
  menu.draw();  
  
  lastButtonPressed = buttonPressed;
  buttonValue = analogRead(0);   // read the input pin 0
  // internal 20K ohm pullup is enabled on analog pin 0 (54).
  
  if(buttonValue >= 920 and buttonValue <= 930 ) //analog value 910
  {
    buttonPressed = 1;//Up button
  }
    else if(buttonValue >= 820 and buttonValue <= 835) //analog value 827
  {
    buttonPressed = 2; // Confirm button
  }
    else if(buttonValue >= 725 and buttonValue <= 740) //analog value 731
  {
    buttonPressed = 3; //Down button
  }
    else if(buttonValue >= 630 and buttonValue <= 645) //analog value 637
  {
    buttonPressed = 4; //Escape button
  }
    buttonAct = 1;
    navMenu();
}

//  ++++++ functions +++++++

int navMenu()
{    
  if(buttonAct)//true if button press not processed
  { 
    buttonAct = 0; // run once per button press
    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;
   }
  }
  else
  {
   return MW_BTNULL;
  }
}

So, you have a series of resistors between the analog pin and ground. Where does the current come from that provides the voltage that the pin is supposed to measure?

Sure would be nice to know what value you read from the analog pin. To bad you have your LCD connected to the only serial port that you could use to tell you that. It would also be nice to know what value gets assigned to buttonPressed.

Not addressed...

navMenu() returns a value that you discard. What's the purpose of calling the function at all? How do you know that this code is not working?

Not addressed...

MW_BTU , MW_BTD etc ... are used for internal calls for menu navigation routine.

Obviously, but which one? The navMenu returns a value. That value ends up in the bit bucket, though. You can't then navigate through the menu based on a value in the bit bucket.

Values are at the end of for example:
if(buttonValue >= 920 and buttonValue <= 930 ) //analog value 910
So the reading is 910 when that button is pushed.
So this was adressed sir Paul.

5 volt is coming from:

/*
 *
 *   analogPin                 
 *      |                      
 *      |                         +5V 
 *      ----------------          |
 *                     |          |
 *                     |____ \____|
 *                     |   SW1    |
 *                     |          \
 *                     |          /   
 *                     |          \    1K
 *                     |          /
 *                     |          \
 *                     |____ \____|
 *                     |   SW2    |
 *                     |          |
 *                     |          \
 *                     |          /   
 *                     |          \    1K
 *                     |          /
 *                     |          \
 *                     |____ \____|
 *                     |   SW3    |
 *                     |          |
 *                     |          \
 *                     |          /   
 *                     |          \    1K
 *                     |          /
 *                     |          \
 *                     |____ \____|
 *                         SW4    |
 *                                |
 *                                \
 *                                /
 *                                \     1K
 *                                /
 *                                \
 *                                |
 *                              _____   
 *                               ___     ground
 *                                _
 *
 */

Mine typing error.

2 other not adressed I need some more thinking time if allowed Paul?

Paco

I need some more thinking time if allowed Paul?

Sure, take all the time you need.

Worked my way back to something that is working for calling the menu buttons now.
All buttons work.
Only problem left is the fact when the button is pressed continously the menu is changing with the speed of the loop.
I cant find a way to exit the if function so the added flag system could work.

// +++++++ Libaries included
#include <Wire.h>
//INSERT ALL THE LIBARIES AFTER INCLUDING WIRE LIB (MENWIZ request) 
#include <LiquidCrystal_I2C.h>
#include <buttons.h>
#include <MENWIZ.h>
#include <EEPROM.h>
#include <Boards.h>

// Create global object for 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, backlightpin, polarity

// Instantiate global variables to bind to menu
boolean wr=0;
boolean ButtonState= 0;
const int analogPin = A0;             // 10 button switch circuit input connected to analog pin 0
int buttonValue;                      // read value from analog port 0 for 6 QAB
int lookupTable[256];
extern byte MW_navbtn;

void setup()
{
 Serial.begin(9600);                       // Output to serial writing or BT

 digitalWrite((54), HIGH);  // enable the 20k internal pullup for MEGA board

  //++++++++++++++++++++Menu and LCD  
  char b[84];
  _menu *r,*s1,*s2;

  // initialize the menu object (20 colums x 4 rows LCD)
  menu.begin(&lcd,20,4);
  menu.addUsrNav(navMenu);
  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("SET1"));                        //add a submenu node 1 to the root menu
  
  s2=menu.addMenu(MW_VAR,s1,F("MD"));                         //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_AUTO_BYTE,&modelNumber,1,10,1);            //Set value
  s2=menu.addMenu(MW_VAR,s1,F("BR"));                         //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_AUTO_BYTE,&brakeRValue,1,255,stepsMValue); //Set value
  s2=menu.addMenu(MW_VAR,s1,F("RH"));                         //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_AUTO_BYTE,&regenHyValue,1,25,1);           //Set value
  //---------------
  s1=menu.addMenu(MW_SUBMENU,r,F("SET2"));                    //add a submenu node 2 to the root menu
  
  s2=menu.addMenu(MW_VAR,s1,F("CP"));                         //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_AUTO_INT,&endCurvePower,1,50,1);              //Set value
  s2=menu.addMenu(MW_VAR,s1,F("DB"));                         //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_AUTO_BYTE,&deadbandXvalue,1,25,1);         //Set value
  s2=menu.addMenu(MW_VAR,s1,F("SQ"));                         //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_AUTO_BYTE,&stepsQValue,0,10,1);            //Set value
  s2=menu.addMenu(MW_VAR,s1,F("SM"));                         //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_AUTO_BYTE,&stepsMValue,0,10,1);            //Set value
  //---------------
  s1=menu.addMenu(MW_SUBMENU,r,F("SET3"));                    //add a submenu node 3 to the root menu
  
  s2=menu.addMenu(MW_VAR,s1,F("RS"));                         //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_BOOLEAN,&regbrakeState);                   //Set value
  s2=menu.addMenu(MW_VAR,s1,F("RCALIB"));                     //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_ACTION,resetCalibration);                  //Set value
  s2=menu.addMenu(MW_VAR,s1,F("SCALIB"));                     //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_ACTION,saveCalibration);                  //Set value
}

void loop()     
{
// NAVIGATION MANAGEMENT & DRAWING ON LCD. NOT BLOCKING has to be the first in the void loop
  menu.draw();  
}

int navMenu()
{
  //
  buttonValue = analogRead(0);   // read the input pin 0
  // internal 20K ohm pullup is enabled on analog pin 0 (54).
  // as soon as a button is pushed it should be blocked for next loop reading
  // as soon as no button is pushed it should be accepted by the loop reading
  
  if(buttonValue >= 920 and buttonValue <= 930) // @analog value 910 
  {
    ButtonState = 1;// as button is pressed we first set a flag high
    return MW_BTU; // Up button read once to control menu navigation one step
    if (ButtonState = 1) //check if flag is high and if so exit this if
    {
    //exit
    }
  }
  else if(buttonValue >= 820 and buttonValue <= 835) // @analog value 827
  {
    ButtonState = 1;
    return MW_BTC;  // Confirm
    if (ButtonState = 1)
    {
    //exit
    }
  }
  else if(buttonValue >= 725 and buttonValue <= 740) // @analog value 731
  {
    ButtonState = 1;
    return MW_BTD;  // Down
    if (ButtonState = 1)
    {
    //exit
    }
  }
  else if(buttonValue >= 630 and buttonValue <= 645) // @analog value 637
  {
    ButtonState = 1;
    return MW_BTE;  // Escape
    if (ButtonState = 1)
    {
    //exit
    }
  }
  else
  {
    return MW_BTNULL;
    ButtonState= 0; // reset flag so buttons can be read again
  } 
}
else
  {
    return MW_BTNULL;
    ButtonState= 0; // reset flag so buttons can be read again
  }

Statements following a return instruction aren't executed.

@backbone:
What happens if no button is pressed ?
Those 1602lcd+keypad modules typically provide some HIGH( >= 900 ) when no button is pressed, and lower values depending on the button.
I guess they contain appropriate voltage dividers.

Not sure if you build something different. Having the input floating, as in your ascii drawing, is not a good idea.

@GrumpyMike:

well it is a little known fact that the pull ups are available to use on the analogue pins. However you are right in that the have not been enabled so the comment is not correct.

So you might simply do

digitalWrite(A0, HIGH); // in setup()

and then get a 5V reading with analogRead(0); if nothing is pulling that signal down ?

That's a little known fact, to me at least. Thanks.
An open pin or a decent resistor between any pin and GND can't hurt, I'll give that a try. Thanks.

You might get some inspiration from this schematics of a NuElectronics lcd+keypad shield (I own some of them, unfortunately the website is currently suspended...)

HTH

LCDshield_v1_1.pdf (17.5 KB)

Thanks for thinking with me,

I must not been the first encountering this problem...........?

@ michael_x:
If I do not push a button then nothing happens and that is the way it should work.
The resistorladder and analog values are working fine for me that is not the problem.
The last code is working except for blocking when pressed continously.
I do not use a LCD shield with buttons. Just a seperate I2C 4x20 LCD and 10 buttons on a pcb of which 4 are used for the menu navigation.
It is those four buttons I need to be working. The other 6 buttons are not the problem as they only in and decrement variable values.

@ Tuxduino:
That after "RETURN....." no code is executed is new for me so that leaves me with an extra problem to cope. Thanks for pointing out.

All needed is.
When menu navigation button is pressed the menu should only advance one step in either direction.
So as long as the button is kept pressed the flag should prevent a next step in the menu untill the button is released and pressed again.

Is this possible or do I overlook other things needed.

For all analog button samples on the web I found and tried there is no blocking while a button is pressed continously.

Paco

Why don't you keep track of only changes in voltage (analogous to only looking for rising/falling edges) - maybe only trigger a "press" condition when you've had, say, two in-range readings.

First thing you have to do is correct that "return" thing, or else you'll keep trying to fix code that doesn't do what you think it does.

Next I suggest to split the code to keep it simple (tm).

(caution: untested pseudocode ahead!)

First thing is read the analog value and calculate which key is pressed.
This might be the job for a specific function, like:

#define KEY_UP 0
#define KEY_RIGHT 1
...
#define KEY_NONE 0xFF

int analogToKey() {
    value = analogRead
    if value between a and b
        return KEY_UP
    else if value between c and d
        return KEY_RIGHT
    else
        ...
    else
        return KEY_NONE
}

Next comes the code that checks whether a keypress/keyrelease event occurred.
Something along these lines:

_currKey = analogToKey();
if _prevKey != _currkey then
    if _prevKey == KEY_NONE then  // no key was pressed and now a key is pressed
        keyPressed(_currKey)  // _currKey has been pressed
    else if _currKey == KEY_NONE then
        keyReleased(_prevKey)   // _prevKey was pressed and now no key is pressed, thus  _prevKey has been released
    else // directly from one key to another
        keyReleased(_prevKey)
        keyPressed(_currKey)
    endif
endif
_prevKey = _currKey

The keyPressed(int key) and keyRelease(int key) are a sort of callback where you take whatever action is appropriate based on the key that has been pressed or released.
For example, in keyRelease() you could select a different menu page if the argument equalse KEY_RIGHT.

Debug example:

void keyPressed(int key) {
    Serial.print("Pressed: ");
    Serial.println(key, DEC);
}

void keyReleased(int key) {
    Serial.print("Released: ");
    Serial.println(key, DEC);
}

The key point IMHO is don't mix different levels of functionality, e.g. detecting a key based on the analogRead value and deciding which menu page is the next one. Try to write functions that do one thing, and do it independently of all the other code.

My 2 cents.

('nuff time on this forum, back to work! :stuck_out_tongue_winking_eye: )

Tuxduino,

Thanks for your suggestion in your boss time.

The key point IMHO is don't mix different levels of functionality, e.g. detecting a key based on the analogRead value and deciding which menu page is the next one. Try to write functions that do one thing, and do it independently of all the other code.

I worked on the pseudo code with my knowledge to see if I ccould get it running to debug first and then take the next step.

Code below is what I made of it sofar.
It will not compile due to two lines telling me there is else or else if with no previous if.
Lines are marekd with @@@@@@@@ in the end.
I cant get my finger on it.
So I commented those two line and then it compiles but that is not good.

Paco

// +++++++ Libaries included
#include <Wire.h>
//INSERT ALL THE LIBARIES AFTER INCLUDING WIRE LIB (MENWIZ request) 
#include <LiquidCrystal_I2C.h>
#include <buttons.h>
#include <MENWIZ.h>
#include <EEPROM.h>
#include <Boards.h>

// Create global object for 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, backlightpin, polarity

// Instantiate global variables to bind to menu
boolean wr=0;
boolean ButtonState= 0;
const int analogPin = A0;             // 10 button switch circuit input connected to analog pin 0
int buttonValue;                      // read value from analog port 0 for 6 QAB

extern byte MW_navbtn;
int _currKey = 0;
int _prevKey = 0;

#define KEY_UP 1
#define KEY_CONFIRM 2
#define KEY_DOWN 3
#define KEY_ESCAPE 4
#define KEY_NONE 11


void setup()
{
  Serial.begin(9600);                       // Output to serial writing or BT

  digitalWrite((54), HIGH);  // enable the 20k internal pullup for MEGA board

  //++++++++++++++++++++Menu and LCD  
  char b[84];
  _menu *r,*s1,*s2;

  // initialize the menu object (20 colums x 4 rows LCD)
  menu.begin(&lcd,20,4);
  //menu.addUsrNav(navMenu);
  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("SET1"));                        //add a submenu node 1 to the root menu

  s2=menu.addMenu(MW_VAR,s1,F("MD"));                         //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_AUTO_BYTE,&modelNumber,1,10,1);            //Set value
  s2=menu.addMenu(MW_VAR,s1,F("BR"));                         //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_AUTO_BYTE,&brakeRValue,1,255,stepsMValue); //Set value
  s2=menu.addMenu(MW_VAR,s1,F("RH"));                         //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_AUTO_BYTE,&regenHyValue,1,25,1);           //Set value
  //---------------
  s1=menu.addMenu(MW_SUBMENU,r,F("SET2"));                    //add a submenu node 2 to the root menu

  s2=menu.addMenu(MW_VAR,s1,F("CP"));                         //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_AUTO_INT,&endCurvePower,1,50,1);              //Set value
  s2=menu.addMenu(MW_VAR,s1,F("DB"));                         //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_AUTO_BYTE,&deadbandXvalue,1,25,1);         //Set value
  s2=menu.addMenu(MW_VAR,s1,F("SQ"));                         //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_AUTO_BYTE,&stepsQValue,0,10,1);            //Set value
  s2=menu.addMenu(MW_VAR,s1,F("SM"));                         //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_AUTO_BYTE,&stepsMValue,0,10,1);            //Set value
  //---------------
  s1=menu.addMenu(MW_SUBMENU,r,F("SET3"));                    //add a submenu node 3 to the root menu

  s2=menu.addMenu(MW_VAR,s1,F("RS"));                         //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_BOOLEAN,&regbrakeState);                   //Set value
  s2=menu.addMenu(MW_VAR,s1,F("RCALIB"));                     //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_ACTION,resetCalibration);                  //Set value
  s2=menu.addMenu(MW_VAR,s1,F("SCALIB"));                     //add a terminal node in the menu tree (that is "variable");
  //s2->addVar(MW_ACTION,saveCalibration);                  //Set value
}

void loop()     
{
  // NAVIGATION MANAGEMENT & DRAWING ON LCD. NOT BLOCKING has to be the first in the void loop
  menu.draw(); 
}

//++++ functions +++++++++++++++

int analogToKey()
  {
    buttonValue = analogRead(0);   // read the input pin 0
    // internal 20K ohm pullup is enabled on analog pin 0 (54).

    if(buttonValue >= 920 and buttonValue <= 930) // @analog value = 910 
    {
      return KEY_UP; // Up
    }
    else if(buttonValue >= 820 and buttonValue <= 835) // @analog value = 827
    {
      return KEY_CONFIRM;  // Confirm
    }
    else if(buttonValue >= 725 and buttonValue <= 740) // @analog value = 731
    {
      return KEY_DOWN;  // Down
    }
    else if(buttonValue >= 630 and buttonValue <= 645) // @analog value = 637
    {
      return KEY_ESCAPE;  // Escape
    }
    else
    {
      return KEY_NONE;  // no button pushed @analog value = 1021
    } 
  }

int readButton()
{
  _currKey = analogToKey();
  if (_prevKey != _currKey); // if a new key is pressed we go further
  {
    if (_prevKey == KEY_NONE); // no key was pressed and now a key is pressed
    {  
      keyPressed(_currKey); // _currKey has been pressed
    }
    //else if (_currKey == KEY_NONE); //@@@@@@@@@@@@@@@@@@
    {
      keyReleased(_prevKey); // _prevKey was pressed and now no key is pressed, thus  _prevKey has been released
    }    
    //else // directly from one key to another  //@@@@@@@@@@@@@
    {
      keyReleased(_prevKey);
      keyPressed(_currKey);
    }    
  }
  _prevKey = _currKey; 
}

void keyPressed(int key) 
{
  Serial.print("Pressed: ");
  Serial.println(key, DEC);
}

void keyReleased(int key) 
{
  Serial.print("Released: ");
  Serial.println(key, DEC);
}

Do not put a semicolon after an if statement if you want it to do anything!

Grumpy_Mike,

Thanks learned something again, will never happen again.
Revised the code and it compiled.
No button action sofar, so I did a step back to see first that the reading of the analog values is working.

I placed the reading of the analog value inside the void loop and commented the lines that contain the word "return" as the compiler screams it does not allow this inside a void.
Then the serial monitor nicely displays the words "up", "down"..etc when a button is pressed or in the case no button is pressed "none".
OK this works. Next step...
As the "return" can not be used in a void (according to the compiler error message) this analog reading code should be placed in a function and should be called from the void loop?
Is this a correct thinking?

So this function that read the analog values is called "analogTokey".
But as it is not in the void loop it should be called from the void loop?
Is it correct to call it from the void loop as "analogTokey;" ?

With this code the serial monitor stays empty.

Maybe all basic stuff but I need to know what I am doing even if it is step by step. :slight_smile:

void loop()     
{
  // NAVIGATION MANAGEMENT & DRAWING ON LCD. NOT BLOCKING has to be the first in the void loop
  menu.draw();
  analogTokey;
}

int analogTokey()
{
  buttonValue = analogRead(0);   // read the input pin 0
  // internal 20K ohm pullup is enabled on analog pin 0 (54).

  if(buttonValue >= 920 and buttonValue <= 930) // @analog value = 910 
  {
    return KEY_UP; // Up
    Serial.println ("Up");
  }
  else if(buttonValue >= 820 and buttonValue <= 835) // @analog value = 827
  {
    return KEY_CONFIRM;  // Confirm
    Serial.println ("Confirm");
  }
  else if(buttonValue >= 725 and buttonValue <= 740) // @analog value = 731
  {
    return KEY_DOWN;  // Down
    Serial.println ("Down");
  }
  else if(buttonValue >= 630 and buttonValue <= 645) // @analog value = 637
  {
    return KEY_ESCAPE;  // Escape
    Serial.println ("Escape");
  }
  else
  {
    return KEY_NONE;  // no button pushed @analog value = 1021
    Serial.println ("None");   
  } 
}

You're not calling analogTokey with that syntax. This:

analogTokey;

Should be this:

analogTokey();

Although even then, you'd be ignoring the return value. Should get you back to seeing some output from the serial monitor though.

Wildbill,

Changed the call to analogTokey();
But no serial monitor action.

void loop()     
{
  // NAVIGATION MANAGEMENT & DRAWING ON LCD. NOT BLOCKING has to be the first in the void loop
  menu.draw();
  analogTokey(); // to call the function that reads the analogvalues and convert them to button numbers
}

int analogTokey()
{........

......}//end of function

Paco