How to Run a function while button not pressed?

Hello all,

I’ve found a pretty nice sketch about how to make menus in an LCD and I adapted it to a TFT that I have…

#include <MenuBackend.h>    //MenuBackend library


#include <TFT.h>  // Arduino screen library
#include <SPI.h>

#define cs   10
#define dc   9
#define rst  8

TFT screen = TFT(cs, dc, rst);

const int buttonPinLeft = 2;      // pin for the Up button
const int buttonPinRight = 3;    // pin for the Down button
const int buttonPinEsc = 6;     // pin for the Esc button
const int buttonPinEnter = 7;   // pin for the Enter button


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
int lastButtonLeftState = LOW;   // the previous reading from the Left input pin
int lastButtonRightState = 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 = 500;    // the debounce time


char t[3];




// Here I defined the Menu variables
MenuBackend menu = MenuBackend(menuUsed, menuChanged);

//initialize menuitems
MenuItem menu1Item1 = MenuItem("Item1");
MenuItem menuItem1SubItem1 = MenuItem("Item1SubItem1");
MenuItem menuItem1SubItem2 = MenuItem("Item1SubItem2");
//and so on...


void setup()
{

  some initial procedures...

}  


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)

}


void menuChanged(MenuChangeEvent changed) {



  MenuItem newMenuItem = changed.to; //get the destination menu

  screen.stroke(0, 0, 250);
  screen.setTextSize(1);


  if (newMenuItem.getName() == menu.getRoot()) {
    screen.background(250, 250, 250);
    screen.text("Main Menu       ", 0, 10);
    screen.rect(12, 12, 130, 80);

  } else if (newMenuItem.getName() == "Item1") {

    screen.background(250, 250, 250);
    screen.text("Item1           ", 0, 20);

  } else if (newMenuItem.getName() == "Item1SubItem1") {
    screen.background(250, 250, 250);
    screen.text("Item1SubItem1", 0, 30);
  } else if (newMenuItem.getName() == "Item1SubItem2") {
    screen.background(250, 250, 250);
    screen.text("Item1SubItem2   ", 0, 40);
  } else if (newMenuItem.getName() == "Item2") {
    screen.background(250, 250, 250);
    screen.text("Item2           ", 0, 50);
  } else if (newMenuItem.getName() == "Item2SubItem1") {
    screen.background(250, 250, 250);
    screen.text("Item2SubItem1   ", 0, 60);
  } else if (newMenuItem.getName() == "Item2SubItem2") {
    screen.background(250, 250, 250);
    screen.text("Item2SubItem2   ", 0, 70);
  } else if (newMenuItem.getName() == "Item2SubItem3") {
    screen.background(250, 250, 250);
    screen.text("Item2SubItem3   ", 0, 80);
  } else if (newMenuItem.getName() == "Item3") {
    screen.background(250, 250, 250);
    screen.text("Item3           ", 0, 90);
  }
}


void menuUsed(MenuUseEvent used) {
  screen.setCursor(0, 0);
  screen.text("You used        ", 0, 0);
  screen.setCursor(0, 1);
  screen.print(used.item.getName());
  delay(2000);  //delay to allow message reading
  screen.setCursor(0, 0);
  screen.text("www.coagula.org", 0, 0);
  menu.toRoot();  //back to Main
}


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
  // read the state of the switch into a local variable:
  reading = digitalRead(buttonPinEnter);

  // check to see if you just pressed the enter button
  // (i.e. the input went from LOW to HIGH),  and you've waited
  // long enough since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonEnterState) {
    // reset the debouncing timer
    lastEnterDebounceTime = millis();
  }

  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();
  }

  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastButtonEnterState = reading;


  //Esc button
  // read the state of the switch into a local variable:
  reading = digitalRead(buttonPinEsc);

  // check to see if you just pressed the Down button
  // (i.e. the input went from LOW to HIGH),  and you've waited
  // long enough since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonEscState) {
    // reset the debouncing timer
    lastEscDebounceTime = millis();
  }

  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();
  }

  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastButtonEscState = reading;


  //Down button
  // read the state of the switch into a local variable:
  reading = digitalRead(buttonPinRight);

  // check to see if you just pressed the Down button
  // (i.e. the input went from+'
  // LOW to HIGH),  and you've waited
  // long enough since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonRightState) {
    // reset the debouncing timer
    lastRightDebounceTime = millis();
  }

  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();
  }

  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastButtonRightState = reading;


  //Up button
  // read the state of the switch into a local variable:
  reading = digitalRead(buttonPinLeft);

  // check to see if you just pressed the Down button
  // (i.e. the input went from LOW to HIGH),  and you've waited
  // long enough since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonLeftState) {
    // reset the debouncing timer
    lastLeftDebounceTime = millis();
  }

  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();;
  }

  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastButtonLeftState = reading;

  //records which button has been pressed
  if (buttonEnterState == HIGH) {
    lastButtonPushed = buttonPinEnter;

  } else if (buttonEscState == HIGH) {
    lastButtonPushed = buttonPinEsc;

  } else if (buttonRightState == HIGH) {
    lastButtonPushed = buttonPinRight;

  } else if (buttonLeftState == HIGH) {
    lastButtonPushed = buttonPinLeft;

  } else {
    lastButtonPushed = 0;
  }
}

void navigateMenus() {
  MenuItem currentMenu = menu.getCurrent();

  switch (lastButtonPushed) {
    case buttonPinEnter:
      if (!(currentMenu.moveDown())) { //if the current menu has a child and has been pressed enter then menu navigate to item below
        menu.use();
      } else { //otherwise, if menu has no child and has been pressed enter the current menu is used
        menu.moveDown();
      }
      break;
    case buttonPinEsc:
      menu.moveUp();  //back to main    menu.toRoot();
      break;
    case buttonPinRight:
      menu.moveRight();
      break;
    case buttonPinLeft:
      menu.moveLeft();
      break;
  }

  lastButtonPushed = 0; //reset the lastButtonPushed variable
}
void Temp() {

//Here I calculate the temp...
}


void SquareTemp() {

  //used to clean previous reading

}

The problem is: I'm not finding a way to display the function Temp() over and over, while another button is not pressed... I've been trying to solve this, but I always come to the same result: function Temp() is just running once! Why? Where can I call the function?

Why? Where can I call the function?

The more important question is where DO you currently call the function.

A visit to http://snippets-r-us.com seems to be in order.

I'm calling the funtion in item 1:

void menuChanged(MenuChangeEvent changed) {



  MenuItem newMenuItem = changed.to; //get the destination menu

  screen.stroke(0, 0, 250);
  screen.setTextSize(1);


  if (newMenuItem.getName() == menu.getRoot()) {
    screen.background(250, 250, 250);
    screen.text("Main Menu       ", 0, 10);
    screen.rect(12, 12, 130, 80);

  } else if (newMenuItem.getName() == "Item1") {

    screen.background(250, 250, 250);
    screen.text("Item1           ", 0, 20);
    
   Temp();

But it runs just once

But it runs just once

Because you call it only when the menu changes.

What your menu tracking code needs to do is set a state variable.

Then, independently, you perform some action(s) based on the state.