make values common in all menus

Hello,

My project is an adjustable Voltage Sensing Relay working injunction with an LCD and buttons (the cheap copy of DFROBOT Shield).

I have 4 menus:

1: Home > (voltage1 , voltage2 , current) // displays the voltage1, voltage2 and current

2: Resting Voltage> (*********) // Enter the “Resting Voltage” menu and it displays the
//restingVoltage and has an option to change the value

3: Running Voltage > (*********) // Enter the " Running Voltage " menu and it displays the
//runningVoltage and has an option to change the value

4: Off Voltage > (*********) //Enter the “Off Voltage” menu and it displays the offVoltage
//and has an option to change it

The problem is when I’m in Menu 2 ( or any other menu) and try to print the value of “voltage1” it errors and says “it’s not declared in the scope”

My question is How can I make my code common to all the other menus?

I’ve attached my code, if you think you’re able to help I would hugely appreciate it.

Thank you.

Final_Stage_VSR_Menu_Continued.ino (14.3 KB)

As far as I can see you have no variable called 'voltage' but you do have one called 'Voltage' . C and C++ are case sensitive.

float voltage1 = sensorValue1 * (50.00 / 1024); // resistor divider, 50volt max input / 1024

    int sensorValue2 = analogRead(A3); // sensorvalue2 is A2
    float voltage2 = sensorValue2 * (50.00 / 1024); // resistor divider, 50volt max input / 1024

You declare and assign values to the voltage1 and 2 variables in menuItem1() function. Those values are only in scope in menuItem1(). Declare the varaibles in global scope and you can use them anywhere in the sketch.

Thanks for the reply!

If I declare the variables in the global scope that then the LCD doesn't print the voltage1, voltage2, or current.

Have I done the declaration right?

// code in global scope

int sensorValue1; // = analogRead(A2);
int sensorValue2; //= analogRead(A3); // sensorvalue2 is A3   
float voltage1 = sensorValue1 * (50.00 / 1024); // resistor divider, 50volt max input / 1024
float voltage2 = sensorValue2 * (50.00 / 1024); // resistor divider, 50volt max input / 1024

Have I done the declaration right?

The declaration, yes. The initialization, no.

Use your delete key, not the // to stop executing code.

It does not make sense to multiply 0 by anything in the initialization of voltage1 and voltage2.

PaulS - I'm really sorry I don't understand what you mean.

Please would you elaborate?

All that you need to do is declare the variables in global scope. For instance:

float voltage1;

Then in the menuItem1() function, just remove the float type.

voltage1 = sensorValue1 * (50.00 / 1024);
float voltage1 = sensorValue1 * (50.00 / 1024);

All variables declared in global scope are automatically [u]assigned the value of 0[/u] if not otherwise initialized. So sensorValue1 and sensorValue2 = 0 and so sensorValue? * (50.00 / 1024 = 0 * (50 / 1024) = 0.

Please would you elaborate?

You have one statement to declare and initialize a variable:

float voltage1 = sensorValue1 * (50.00 / 1024); // resistor divider, 50volt max input / 1024

The comment is pointless, since the variable has nothing to do with a resistor divider. So, the code is actually:

float voltage1 = sensorValue1 * (50.00 / 1024);

Now, since sensorValue1 was declared, but NOT initialized, two lines above this one, the compiler did the initialization for you, so this code is really:

float voltage1 = 0 * (50.00 / 1024);

Now, everyone knows that 0 times anything is 0, so why not just have

float voltage1 = 0.0;

and look like you know what you are doing?

PaulS - Sorry, the comments were because I copied and pasted from another location, I should have removed that to save confusion.

PaulS: You have one statement to declare and initialize a variable:

float voltage1 = sensorValue1 * (50.00 / 1024); // resistor divider, 50volt max input / 1024

The comment is pointless, since the variable has nothing to do with a resistor divider. So, the code is actually:

float voltage1 = sensorValue1 * (50.00 / 1024);

Now, since sensorValue1 was declared, but NOT initialized, two lines above this one, the compiler did the initialization for you, so this code is really:

float voltage1 = 0 * (50.00 / 1024);

Now, everyone knows that 0 times anything is 0, so why not just have

float voltage1 = 0.0;

and look like you know what you are doing?

PaulS - Mainly because I don't know what I'm doing - I'm learning.

Thanks a lot groundFungus - your comments really helped and I've achieved what I wanted.

Can someone explain why in a menu3 (or any menu), the code doesn’t “loop” and so it refreshes the value of voltage1? I’ve tried a good few different ways but with the same outcome.

// Running Voltage Menu

void menuItem3() {
  // Function executes when you select the 3rd item from main menu
   
   int activeButton = 0;

   lcd.clear();
   
 do {
      int sensorValue1 = analogRead(A2);
  voltage1 = sensorValue1  * (50.00 / 1024);
  lcd.setCursor(0,0);
  lcd.print("VOLT LIVE");
  lcd.setCursor (11,0);
  lcd.print(voltage1);
  menuState3=true;
  int button;
    readKey = analogRead(0);
    if (readKey < 790) {
      delay(100);
      menuState3=false;
    }
   } while (menuState3==true);
  {
while (activeButton == 0) {
    int button;
    readKey = analogRead(0);
    if (readKey < 790) {
      delay(100);
      readKey = analogRead(0);
    }
    button = evaluateButton(readKey);
    switch (button) {
      case 4:  // This case will execute if the "back" button is pressed
        button = 0;
        activeButton = 1;
        break;
    }
  }
}
}

I feel like maybe I should try to make my own menu , the problem is I can’t find anything online that shows how to do anything similar to what I’m doing? If you know of something that I may find useful please let me know! Thanks

   while (activeButton == 0)
    {
      int button;
      readKey = analogRead(0);
      if (readKey < 790)
      {
        delay(100);
        readKey = analogRead(0);
      }
      button = evaluateButton(readKey);
      switch (button)
      {
        case 4:  // This case will execute if the "back" button is pressed
          button = 0;
          activeButton = 1;
          break;
      }
    }

Have you tried printing the values of activeButton and button ?

Why use switch/case when there is only one case ?

Hello UKHeliBob,

If I print the values of activeButton and button, they come back as 0.

I'm using switch/case as it was part of the code I downloaded.

basically I wrote the code to do what I want the device to do, but I wanted to add an LCD and be able to change values within my code via buttons... I didn't know where to start and as I couldn't find any similar projects online, I used a code template and am trying to integrate my code into it... which isn't going to well!

If activeButton is always zero then the while.loop will never end

It is time to investigate why its value does my change

Thanks UKHeliBob, your comment helped me look for a solution. This seems to work…

It’s only taken me 12 hours. This project still isn’t even close to finished. I think I may have started something I’m unable to finish due to my lack of knowledge.

// Running Voltage Menu

void menuItem3() {
  // Function executes when you select the 3rd item from main menu
   
  int activeButton = 0;
  int button;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("VOLT LIVE");
  menuState3=true;

  while(menuState3==true){
  int sensorValue1 = analogRead(A2);
  voltage1 = sensorValue1  * (50.00 / 1024);
  

  lcd.setCursor (11,0);
  lcd.print(voltage1);
 
    readKey = analogRead(0);
    if (readKey < 790) {
      delay(100);
      readKey = analogRead(0);
    button = evaluateButton(readKey);
    switch (button) {
      case 4:  // This case will execute if the "back" button is pressed
        button = 0;
        activeButton = 1;
        menuState3=false;
        break;
    }
  }
}
}

Is there a way to return a value to global scope?

for instance I have

float restingVoltage = 13.0;
float runningVoltage = 13.7;
float offVoltage = 14.3;

and in my " resting Voltage Menu" I want to change the "float resting Voltage " in the global scope.

  lcd.setCursor (10,0);
  lcd.print(voltage1);
  lcd.setCursor (10,1);
  lcd.print(restingVoltage);
  analogRead(0);
  if(readKey <195){
    restingVoltage = 13.5 ;
  }
    else if
    (readKey <380) {
      restingVoltage = 13.4;
    }

Is there a way to return a value to global scope?

You do not need to return a global variable from a function as it will be available throughout the program

in my " resting Voltage Menu" I want to change the "float resting Voltage " in the global scope.

Just change its value and you can use it in any part of the program.

Remember to remove the data type specifier (float) from the variable inside the function or you end up with 2 of the same variable, one global and one local to the function.

I'm not quite sure what you both mean...

Am I right in thinking that if I'm in one of my menus I am able to change the value of a global float?

The reason I need to do that is because every menu has to change a global float value so my main code will execute with the newly changed parameters. does that make sense?

The reason for making a variable of global scope is so that the variable is accessible from any where in the sketch. So, yes, you can change the variable in any menu and get its value in any menu.

Am I right in thinking that if I'm in one of my menus I am able to change the value of a global float?

Yes, that is the whole point of making a variable global.