3 button menu for 16x2 LCD - help needed

Maybe you can glean something from this.  You'll have to adapt the encoder parts to your two button method but that shouldn't be too hard since it's just up/down vs. left/right.

/*
  Demonstrate a simple two level menu system on the serial monitor
  using a quadrature encoder and integral pushbutton.

  Navigation mode uses the encoder to select a variable to change.
  Alter mode uses the encoder to adjust the selected value.
  The encoder pushbutton toggles between navigation and alter modes.

  v8 combines the value adjustment code with the 'build an integer'
  code to adjust a large value one digit at a time. The builtup
  number is displayed following the individual digits.

  Toggling the two booleans is retained and added is the ability for
  one of the bools to control the sign of the number.
*/

/*
   Usage for v 2.7 https://github.com/thomasfredericks/Bounce2/blob/master/README.md
   Demonstrates setPressedState() and getPressedState()
*/

#include <Bounce2.h>  // a library to handle the pushbutton
#define BOUNCE_PIN A0
// Bounce encoderPB = Bounce(); // old style instantiation
Bounce2::Button encoderPB = Bounce2::Button();

// variables having to do with the encoder

const uint8_t INTPIN1 = 3;  // Rotary encoder interrupt on this Arduino Uno pin.
const uint8_t INTPIN2 = 2;  // Rotary encoder interrupt on this Arduino Uno pin.

#include <Rotary.h>  // encoder handler by Buxton
//                   https://github.com/buxtronix/arduino/tree/master/libraries/Rotary
//
volatile int8_t encoderDirection = 0;  //  Encoder direction value, set in the 'rotate' ISR
//                                         0 = no movement, +1 = CW, -1 = CCW

const int8_t numberOfValues = 8;  // total number of variables used / displayed
//                                  this determines when to wrap the 'cursor' position
int8_t valueToAdjust = 0;      // Selects which value will be adjusted
bool isNavigationMode = true;  // controls select vs. alter mode

const int8_t numberOfArrayElements = 5;  // The five array elements represent five digits
//                                         which will be joined, according to their
//                                         respective place values, in largeNumber

int8_t digitNumber[numberOfArrayElements];  // compiler will initialize to zero
byte numElements = sizeof(digitNumber) / sizeof(digitNumber[0]);

bool signIndicator = true, bool2;  // one sign toggle, one toggle switch

const uint8_t modeIndicator = 12;  // Pin number for common anode LED

// enum values for the switch / case construct

enum valueSelect { tenPwr0,
                   tenPwr1,
                   tenPwr2,
                   tenPwr3,
                   tenPwr4,
                   fullNumber,
                   signToggle,
                   switchToggle };

/*
   Rotary encoder pin assignments
*/
Rotary rotary = Rotary(INTPIN1, INTPIN2);  // interrupts are used on both pins 2 & 3
//
// === S E T U P ===

void setup() {
  Serial.begin(115200);
  attachInterrupt(0, rotate, CHANGE);
  pinMode(INTPIN1, INPUT_PULLUP);
  attachInterrupt(1, rotate, CHANGE);
  pinMode(INTPIN2, INPUT_PULLUP);
  encoderPB.attach(BOUNCE_PIN, INPUT_PULLUP);
  encoderPB.interval(5);
  //encoderPB.setPressedState(HIGH); // for library demo only
  pinMode(modeIndicator, OUTPUT);  // Common anode LED
  displayAllValues();
}

void loop() {

  encoderPB.update();  // Refresh the pushbutton object variables

  if (encoderPB.fell()) {                                          // User pushed a button
    isNavigationMode = !isNavigationMode;                          // Toggle navigate/adjust mode
    digitalWrite(modeIndicator, (isNavigationMode ? LOW : HIGH));  // Annunciate mode via LED
    //Serial.println(encoderPB.getPressedState()); // for library demo only
  }

  if (encoderDirection != 0) {  // Test if encoder moved.
    // Select the value of interest
    if (isNavigationMode) {
      selectValue();
    }

    else {
      changeDataValues();
    }

    encoderDirection = 0;  // Reset the increment value
    displayAllValues();    // Update the display
  }
}  // end of loop

//
//-------------------------------------------------------
//

void changeDataValues() {
  //
  // In data change mode we come here to increment/decrement numeric values
  // and toggle boolean values

  uint8_t switchUse = (numberOfArrayElements - 1) - valueToAdjust;

  switch (valueToAdjust) {
    case tenPwr0 ... tenPwr4:
      digitNumber[switchUse] += encoderDirection;
      if (digitNumber[switchUse] < 0) digitNumber[switchUse] = 0;
      if (digitNumber[switchUse] > 9) digitNumber[switchUse] = 9;
      break;

      // For booleans encoder direction is irrelevant. If we've made
      // it this far the encoder moved so toggle the indicated bool.

    case (signToggle):
      signIndicator = !signIndicator;
      break;

    case (switchToggle):
      bool2 = !bool2;
      break;

    default: break;
  }
}

//
//--------------------------------------------------
//

long digitsToNumber() {
  /*
    Build a unified, single integer from separate digits taken
    from an array.

    The array elements (digits) are manipulated individually by
    the changeDataValues menu function
  */
  long largeNumber = 0;
  unsigned long tenXMultiplier = 1;

  for (int8_t i = 0; i < numElements; i++) {
    largeNumber += digitNumber[i] * tenXMultiplier;
    tenXMultiplier *= 10;
  }

  if (signIndicator == false) {
    largeNumber *= -1;
  }
  return largeNumber;
}

//
//-------------------------------------
//

void selectValue() {
  /*
    If the encoder moved, the value which selects the array element
    to be changed is incremented or decremented accordingly. Values
    wrap in both directions.
  */
  valueToAdjust += encoderDirection;
  if (valueToAdjust >= numberOfValues) valueToAdjust = 0;
  if (valueToAdjust < 0) valueToAdjust = numberOfValues - 1;
}

//
//---------------------------------------------------------
//

void rotate() {  // Encoder ISR
  /*
    Interrupt Service Routine for rotary encoder:
    An interrupt is generated any time either of the rotary
    inputs change state. Once the interrupt is acted upon,
    other code will clear encoderDirection to zero.
  */
  byte result = rotary.process();
  if (result == DIR_CW) {
    encoderDirection = +1;
  } else if (result == DIR_CCW) {
    encoderDirection = -1;
  }
}

//
//------------------------------------
//

void displayAllValues() {
  /*
      Format and print the values and add headings and a position cursor
  */
  for (int8_t i = numberOfArrayElements; i > 0; i--) {
    Serial.print(i);
    Serial.print("\t");
  }
  Serial.print("number\t");
  Serial.print("sign\t");
  Serial.println("bool2");

  for (int8_t i = numberOfArrayElements - 1; i >= 0; i--) {
    Serial.print(digitNumber[i]);
    Serial.print("\t");
  }

  //  Serial.print(unifiedDigits);
  long x14 = digitsToNumber();
  Serial.print(x14);
  Serial.print("\t");

  if (signIndicator) Serial.print("pos");
  else Serial.print("neg");
  Serial.print("\t");

  if (bool2) Serial.print("true");
  else Serial.print("false");
  Serial.println();

  // Print a cursor '--' under the value of interest

  for (byte i = 0; i < numberOfValues; i++) {
    if (i == valueToAdjust) Serial.print("--\t");
    else Serial.print("\t");
  }
  Serial.println();
  // Use F macro i Serial.print to save RAM space
  Serial.println(F("............................................................"));
}