Updating values in a sub-menu

Hi,

I am making a menu displayed on an OLED for a project I'm working on but I am having some trouble updating the uptime and voltage. Navigating the menu and sub-menu are working fine for me so I'm not too concerned about that unless someone has a better way. My problem is that when I get into the "sys-info" sub-menu the uptime and voltage do not update. I have to exit the sub-menu and re-enter it for the uptime and voltage to update. I would like to have it so that when I get into the sub-menu the uptime and voltage update continuously. I'm sure I'm missing something obvious and I would greatly appreciate some help.

The "sys info" sub-menu is the second to last "else if" statement at the bottom of the sketch.

#include <Wire.h>             // I2C Library
#include <Adafruit_GFX.h>     // Grafix library
#include <Adafruit_SSD1306.h> // SSD1306 header file for oled

int LeftJoystickY = A0;       // Left Joystick Y Pin
int RightJoystickY = A1;      // Right Joystick Y Pin
int LeftJoystickButton = 4;   // Left Joystick Button Pin
int RightJoystickButton = 2;  // Right Joystick Button Pin

bool sysInfo = false;         // Used in if statements for going into sub menus
bool pinMap = false;          // Used in if statements for going into sub menus
bool select = false;          // Used in if statements for going into sub menus
bool configuration = false;   // Used in if statements for going into sub menus
bool exitMenu = false;      
bool enterMenu = false;

String Version = "Version";   // Firmware version 
String VersionNum ="2.7.3";   // Firmware version 

int LeftJoystickButtonValue; 
int RightJoystickButtonValue;
int LeftJoystickYvalue;
int RightJoystickYvalue;

const int numReadings = 10;
int readings[numReadings];    // Readings from the analog input
int readIndex = 0;            // Index of the current reading
float total = 0;              // Running total of voltage readings
float averageVoltage;         // The average of the voltage readings
int voltageDivider = A6;      // voltage divider pin 
float voltageDividerValue;    // variable to store the value coming from the voltage divider 

int menuPos = 1005;             // Used for referencing the place in the menu
int previousMenuPos;            // Used for referencing the place in the menu
int currentMenuPos;             // Used for referencing the place in the menu
bool increment = false;         // Used for incrementing place in the menu

int Selection = HIGH;                // Selection to test against
int SelectionState = HIGH;           // the current state of the output pin
int buttonState = HIGH;              // the current reading from the input pin
int lastButtonState = HIGH;          // the previous reading from the input pin
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 90;    // the debounce time; increase if the output flickers

unsigned long timeBegin1 = micros();
unsigned long timeEnd1 = micros();   
unsigned long durationA = timeEnd1 - timeBegin1;
unsigned long durationB;
unsigned long timeBegin2 = micros();
unsigned long timeEnd2 = micros();   
unsigned long durationC = timeEnd2 - timeBegin2;
unsigned long durationD;

unsigned long previousMillis = 0;
const long interval = 10;   

#define SCREEN_WIDTH 128    // OLED display width, in pixels
#define SCREEN_HEIGHT 32    // OLED display height, in pixels

#define OLED_RESET -1       // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


void setup(){
  
  Serial.begin(9600);
  
     // From smoothing example v
     // initialize all the readings to 0:
    for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }
  
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // I2C Address 0x3C for 128x32 Oled
  display.clearDisplay();                     // Clearing display
  //display.setTextSize(1);                   // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  
  pinMode(LeftJoystickY, INPUT);
  pinMode(RightJoystickY, INPUT); 
  pinMode(LeftJoystickButton, INPUT_PULLUP);
  pinMode(RightJoystickButton, INPUT_PULLUP); 

}

/**************************************************/

void loop()
{

  unsigned long minutes = millis() / 36000;   // Convert millis to minutes

  voltageDividerValue = analogRead(voltageDivider);
  float batteryVoltage = voltageDividerValue * (4.80 / 1023.00) * 2;
  
  // From smoothing example v
  // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  readings[readIndex] = analogRead(voltageDivider);
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

  // if we're at the end of the array...
  if (readIndex >= numReadings) {
    // ...wrap around to the beginning:
    readIndex = 0;
  }
  // calculate the average:
  averageVoltage = total / numReadings;
  averageVoltage = averageVoltage / 100;
  

  LeftJoystickButtonValue = digitalRead(LeftJoystickButton);              // Left Joystick Button Value Reading
  RightJoystickButtonValue = digitalRead(RightJoystickButton);            // Right Joystick Button Value Reading 
  LeftJoystickYvalue = map(analogRead(LeftJoystickY), 0, 1023, 255, 0);   // Left Joystick Value mapping/inverting reading
  RightJoystickYvalue = map(analogRead(RightJoystickY), 0, 1023, 255, 0); // Right Joystick Value mapping/inverting reading
      
  
// **************** RightJoystickYvalue DOWN **************** // Increment down in the menu:
  
  if(RightJoystickYvalue <= 35 && enterMenu == true){  //Continue if RightJoystickYvalue is <= 35 and enterMenu == true
    timeBegin1 = micros();  //Begin counting micro seconds
    
  Serial.println("timeBegin1");
  while(RightJoystickYvalue < 40){ //Pause while RightJoystickYvalue is <= 110 and enterMenu == true
  Serial.println("Pause");
  RightJoystickYvalue = map(analogRead(RightJoystickY), 0, 1023, 255, 0);
  
  if(RightJoystickYvalue > 35 && enterMenu == true) break;
  }
    timeEnd1 = micros();   //End counting micro seconds
    durationA = timeEnd1 - timeBegin1; //Calculate duration of RightJoystickYvalue <= 110
    durationB = durationA / 10000;
    increment = true;
    Serial.println("timeEnd1");
  }
  // Increment down in the menu
  if(increment == true){
    menuPos--;    
    increment = false;
  }
  increment = false;

  if (menuPos != previousMenuPos) {
    // reset the debouncing timer
    currentMenuPos = menuPos;
  }
  // If the increment in the menu goes under 1001 make the value 1001
  if(menuPos < 1001){
    menuPos = 1001 ;
  }

  
// **************** RightJoystickYvalue UP **************** // Increment up in the menu:  
  
  RightJoystickYvalue = map(analogRead(RightJoystickY), 0, 1023, 255, 0); //(Right JS)
  
  // put your main code here, to run repeatedly:
  if(RightJoystickYvalue >= 220 && enterMenu == true){    //Continue if RightJoystickYvalue is <= 110 and enterMenu == true
    timeBegin2 = micros(); //Begin counting micro seconds
    
  Serial.println("timeBegin2");
  while(RightJoystickYvalue > 210 && enterMenu == true){  //Pause while RightJoystickYvalue is <= 110 and enterMenu == true
  Serial.println("Pause");
  RightJoystickYvalue = map(analogRead(RightJoystickY), 0, 1023, 255, 0);
  
  if(RightJoystickYvalue < 220 && enterMenu == true) break;
  }
    timeEnd2 = micros();   //End counting micro seconds
    durationC = timeEnd2 - timeBegin2; //Calculate duration of RightJoystickYvalue <= 110
    durationD = durationC / 10000;
    increment = true;
    Serial.println("timeEnd2");
  }
  // Increment up in the menu
  if(increment == true){   
    menuPos++;
    increment = false;
  }
  increment = false; 

  if (menuPos != previousMenuPos) {
    // reset the debouncing timer
    currentMenuPos = menuPos;
  }
  // If the increment in the menu goes over 1005 make the value 1005
  if(menuPos > 1005){
    menuPos = 1005 ;
  }


// **************** Joystick Button / Menu Selection ****************
    if (LeftJoystickButtonValue != lastButtonState) { 
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (LeftJoystickButtonValue != buttonState) {
      buttonState = LeftJoystickButtonValue;

      // only toggle the selection state if the new button state is HIGH
      if (buttonState == HIGH) {
        SelectionState = !SelectionState;
      }
    }
  }
  Selection = SelectionState;
  lastButtonState = LeftJoystickButtonValue;
  //Serial.println(Selection);

  // Enter menu if both joystick buttons are pressed:
  if(LeftJoystickButtonValue == LOW && RightJoystickButtonValue == LOW && enterMenu == false){ 
    enterMenu = true;
    Serial.println("Enter Menu = true");
    //delay(30);
  }

  // **************** DEFAULT VIEW ****************
  // Show right Y and left Y as default (readings not present at this time)
  else if (enterMenu == false){ //Displaying Joystick Y Data
  //Serial.println(sent_data.ch2);
  display.clearDisplay();
  display.setTextColor(WHITE,BLACK);
  display.setTextSize(2);
  display.setCursor(0,0);             // Start at top-left corner
  display.print("Right Y");
  display.setCursor(90,0);             
  display.setCursor(0,17);             
  display.print("Left  Y");
  display.setCursor(90,17);             
  display.display();
  Serial.println("Displaying Joystick Y Data"); 
  }


  // **************** MENU ****************
  
  // Highlight "Sys Info" in the menu
  else if (menuPos == 1005 && enterMenu == true && Selection == LOW){
  previousMenuPos = 1005;
  display.clearDisplay();
  display.setTextColor(BLACK,WHITE);
  display.setTextSize(2);
  display.setCursor(0,0);             
  display.print("> Sys Info");
  display.setTextColor(WHITE,BLACK);
  display.setCursor(0,17);             
  display.print("> Pin Map");
  display.display();
  sysInfo = true;
  pinMap = false;
  select = false;
  configuration = false;
  Serial.println("> Sys Info");
  }

  // Highlight "Pin Map" in the menu
  else if (menuPos == 1004 && previousMenuPos > 1004 && enterMenu == true && Selection == LOW){
  previousMenuPos = 1004;
  display.clearDisplay();
  display.setTextColor(WHITE,BLACK);
  display.setTextSize(2);
  display.setCursor(0,0);
  display.print("> Sys Info");
  display.setTextColor(BLACK,WHITE);
  display.setCursor(0,17);             
  display.print("> Pin Map");
  display.display();
  sysInfo = false;
  pinMap = true;
  select = false;
  configuration = false;
  Serial.println("> Pin Map");
  }

  // Highlight "Pin Map" in the menu
  else if (menuPos == 1004 && previousMenuPos < 1004 && enterMenu == true && Selection == LOW){
  previousMenuPos = 1004;
  display.clearDisplay();
  display.setTextColor(BLACK,WHITE);
  display.setTextSize(2);
  display.setCursor(0,0);
  display.print("> Pin Map");
  display.setTextColor(WHITE,BLACK);
  display.setCursor(0,17);             
  display.print("> Select");
  display.display();
  sysInfo = false;
  pinMap = true;
  select = false;
  configuration = false;
  Serial.println("> Pin Map");
  }

  // Highlight "Select" in the menu
  else if (menuPos == 1003 && previousMenuPos > 1003 && enterMenu == true && Selection == LOW){
  previousMenuPos = 1003;
  display.clearDisplay();
  display.setTextColor(WHITE,BLACK);
  display.setTextSize(2);
  display.setCursor(0,0);
  display.print("> Pin Map");
  display.setTextColor(BLACK,WHITE);
  display.setCursor(0,17);             
  display.print("> Select");
  display.display();
  sysInfo = false;
  pinMap = false;
  select = true;
  configuration = false;
  Serial.println("> Select");
  }

  // Highlight "Select" in the menu
  else if (menuPos == 1003 && previousMenuPos < 1003 && enterMenu == true && Selection == LOW){
  previousMenuPos = 1003;
  display.clearDisplay();
  display.setTextColor(BLACK,WHITE);
  display.setTextSize(2);
  display.setCursor(0,0);
  display.print("> Select");
  display.setTextColor(WHITE,BLACK);
  display.setCursor(0,17);             
  display.print("> Config");
  display.display();
  sysInfo = false;
  pinMap = false;
  select = true;
  configuration = false;
  Serial.println("> Select");
  }

  // Highlight "Config" in the menu
  else if (menuPos == 1002 && previousMenuPos > 1002 && enterMenu == true && Selection == LOW){ 
  previousMenuPos = 1002;
  display.clearDisplay();
  display.setTextColor(WHITE,BLACK);
  display.setTextSize(2);
  display.setCursor(0,0);
  display.print("> Select");
  display.setTextColor(BLACK,WHITE);
  display.setCursor(0,17);             
  display.print("> Config");
  display.display();
  sysInfo = false;
  pinMap = false;
  select = false;
  configuration = true;
  Serial.println("> Config");
  }

  // Highlight "Config" in the menu
  else if (menuPos == 1002 && previousMenuPos < 1002 && enterMenu == true && Selection == LOW){ 
  previousMenuPos = 1002;
  display.clearDisplay();
  display.setTextColor(BLACK,WHITE);
  display.setTextSize(2);
  display.setCursor(0,0);
  display.print("> Config");
  display.setTextColor(WHITE,BLACK);
  display.setCursor(0,17);             
  display.print("> Exit");
  display.display();
  sysInfo = false;
  pinMap = false;
  select = false;
  configuration = true;
  Serial.println("> Config");
  }

  // Highlight "Exit" in the menu
  else if (menuPos == 1001 && enterMenu == true && Selection == LOW){
  previousMenuPos = 1001;
  display.clearDisplay();
  display.setTextColor(WHITE,BLACK);
  display.setTextSize(2);
  display.setCursor(0,0);
  display.print("> Config");
  display.setTextColor(BLACK,WHITE);
  display.setCursor(0,17);             
  display.print("> Exit");
  display.display();
  sysInfo = false;
  pinMap = false;
  select = false;
  configuration = false;
  Serial.println("> Exit");
  }

  // Enter Sys Info sub menu:
  else if (menuPos == 1005 && enterMenu == true && sysInfo == true && Selection == HIGH){ 
  display.clearDisplay();
  display.setTextColor(WHITE,BLACK);
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print(Version);
  display.setCursor(50,0);             
  display.print(VersionNum);
  display.setCursor(0,13);             
  display.print("Uptime");
  display.setCursor(50,13);             
  display.print(minutes);
  display.setCursor(0,25);             
  display.print("Batt Volt");
  display.setCursor(60,25);
  display.print(averageVoltage);
  display.setCursor(90,25);
  display.print("V");
  display.display();
  Serial.println("Entered Sys Info");
  sysInfo = false;
  pinMap = false;
  select = false;
  configuration = false;
  }

  // Exit menu if "Exit" is selected on the menu
  else if (menuPos == 1001 && enterMenu == true && Selection == HIGH){
    //exitMenu = true;
    enterMenu = false;
    menuPos = 1005;
    Serial.println("Exited Menu"); 
  }
  //Serial.println(Selection);
}

I can see why, but what to do about it is more tricky. In the code that displays sys info you have this:

    sysInfo = false;

So it doesn't display again until you reload that page. Ordinarily, that's good because otherwise you would have the display flashing & refreshing so fast, you wouldn't be able to read it.

You might want to add another variable that tells you which page is being displayed. If it's sys info, once a second, rewrite uptime & voltage.

1 Like

Having a loop function that long is not a very good technique.
Each menu should have its own function. Better would be two functions one to display the current values and another to change them.

I can see in your code where you enter your changes. I can see where you display them, which is when the section of code is first entered. But after changing them you do not display the changes which is exactly what you are saying happens.

1 Like

Thank you!! I can't believe I didn't see that! Changing sysInfo to "true" fixed it now both values are updating. I really appreciate it!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.