How can I set a variable in loop and use it in setup?

I've made a code in which I set a time in minutes, with a potentiometer, in the void loop() as it allows me to print it in the Serial Monitor as well as in the LCD display. My question is, how can I use the variable time, set in the void loop, in the void setup so the timer can start with that value?

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <Countimer.h>

Countimer timer;

LiquidCrystal_I2C lcd(0x27,16,2);

int time;

int pot = 0;

//int buttonState = 0;

int start = 2;

//const int relay = 2;

void setup() {

  //pinMode(4, INPUT);
  pinMode(2, INPUT);

  Serial.begin(9600);
  lcd.init();
  lcd.backlight();

  time == time;

  // Set up count down timer with 10s and call method onComplete() when timer is complete.
  // 00h:00m:10s
	timer.setCounter(0, time, 0, timer.COUNT_DOWN, onComplete);

  // Print current time every 1s on serial port by calling method refreshClock().
  timer.setInterval(refreshClock, 1000);
  
  //lcd.setCursor(0,0);
  //lcd.print("PUMP CONTROLLER");
  //lcd.setCursor(0,1);
  //lcd.print(" THES");
  //delay(3000);
 	//lcd.clear();

  //Serial.println(time);

}

void refreshClock() {
	Serial.print("Current count time is: ");
    Serial.println(timer.getCurrentTime());
    lcd.setCursor(0,0);
    lcd.print("Time:");
    lcd.setCursor(6,0);
    lcd.print(timer.getCurrentTime());
    Serial.println(time);
}

void onComplete() {
	Serial.println("Complete!!!");
  lcd.setCursor(6,0);
  lcd.print("COMPLETE");
  delay(2000);
  refreshClock();
}

void loop() {
	// Run timer

  time = analogRead(pot);
  time = map(time, 0, 1023, 60, 0);
  
  lcd.setCursor(0,1);
  lcd.print("TIME:");
  lcd.setCursor(6,1);
  //lcd.print("  ");
  lcd.setCursor(6,1);
  lcd.print(time);
  
  //timer.setCounter(0, time, 0, timer.COUNT_DOWN, onComplete);
  
  
  if (digitalRead(start) == HIGH){
    timer.run();
    if(!timer.isCounterCompleted()) {
      timer.start();
    }
  }
	//timer.run();

    // Now timer is running and listening for actions.
    // If you want to start the timer, you have to call start() method.
    //if(!timer.isCounterCompleted()) {
    //  timer.start();
    //}
  if (digitalRead(start) == LOW){
    refreshClock();
  }  
  digitalRead(2);
  delay(1000);
  Serial.println(digitalRead(2));
  Serial.println(time);
}

Anything you can do in Loop you can do in Setup. With that said, why not do what you need in Setup?

The difference between Setup and Loop is it starts at Setup and executes it once. Then it moves to Loop and does that over and over and over....

The setup function runs first, then the loop function runs over and over. When the setup function runs, the loop function hasn't run yet. So nothing from the loop function can affect the setup function.

If you want to give that variable a value in the setup function, then move that code to setup. If you need it to loop in order to work then put it in a while loop.

Add

 time = analogRead(pot);
 time = map(time, 0, 1023, 60, 0);

In setup() rather

time == time;

BTW, that is a comparison not an assignment. The correct thing (although it doesn't make sense) is

time = time;
1 Like

I tried it, the thing is that when I put that in setup instead of loop, the value of time stays where the potentiometer is when Arduino is turned on, and it doesn't change as you move it.

If you need the value of the potentiometer in setup too then
keep

in loop and add the same line in setup()

That's because setup only runs once.

You can either put that code in both places, or explain better what the real problem is and we can help you solve that.

maybe this line should be
exactly that

  time = analogRead(pot);

Ok, I'll try to explain what I'm trying to do with more detail:

I want to set a value of the variable time with the potentiometer, so when I press a switch that turns start to HIGH, the countdown of the timer starts from that time as it can bee seen in this line:

timer.setCounter(0, time, 0, timer.COUNT_DOWN, onComplete);

That is why I need to have that time in setup() so it can be used as the starting time.

Btw, I've already tried putting the potentiometer lines of code in both places (loop and setup) but the value of time does not get set as the starting time.

Taking what you say literally,

int time = 0;
void setup()
{
 bool switchNotPressed = true;
 pinMode(SWITCH_PIN, INPUT_PULLUP);

 while(switchNotPressed )
 {
    time = readPotentiometer()
    switchNotPressed = digitalRead(SWITCH_PIN);
 }
}

void loop()
{
  // do stuff with time here
}

If you don't want the timer to start until you press the button then you need to move this line to wherever you detect the button press. If you put it in setup then it starts the timer in setup. It's not going to wait for your button press.

Actually, I think I kind of solved it: I moved that line to the void refreshClock(). But now I have another problem: when I push the button, the countdown does not start, the time value does change but remains static.

Post the new code.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <Countimer.h>

Countimer timer;

LiquidCrystal_I2C lcd(0x27,16,2);

int time;

int pot = 0;

int res = 3;

//int buttonState = 0;

int start = 2;

//const int relay = 2;

void setup() {

  //pinMode(4, INPUT);
  pinMode(2, INPUT);

  Serial.begin(9600);
  lcd.init();
  lcd.backlight();

  // Set up count down timer with 10s and call method onComplete() when timer is complete.
  // 00h:00m:10s
	//timer.setCounter(0, time, 0, timer.COUNT_DOWN, onComplete);

  // Print current time every 1s on serial port by calling method refreshClock().
  timer.setInterval(refreshClock, 1000);
  
  //lcd.setCursor(0,0);
  //lcd.print("PUMP CONTROLLER");
  //lcd.setCursor(0,1);
  //lcd.print(" THES");
  //delay(3000);
 	//lcd.clear();

  //Serial.println(time);

}

void refreshClock() {
  lcd.clear();
  timer.setCounter(0, time, 0, timer.COUNT_DOWN, onComplete);
  //timer.setInterval(refreshClock, 1000);
	Serial.print("Current count time is: ");
    Serial.println(timer.getCurrentTime());
    lcd.setCursor(0,0);
    lcd.print("Time:");
    lcd.setCursor(6,0);
    lcd.print(timer.getCurrentTime());
    Serial.println(time);
}

void onComplete() {
	Serial.println("Complete!!!");
  lcd.setCursor(6,0);
  lcd.print("COMPLETE");
  delay(2000);
  refreshClock();
}

void loop() {
	// Run timer

  time = analogRead(pot);
  time = map(time, 0, 1023, 60, 0);
  
  lcd.setCursor(0,1);
  lcd.print("Set [min]:");
  lcd.setCursor(11,1);
  //lcd.print("  ");
  //lcd.setCursor(6,1);
  lcd.print(time);

  //return time;
  Serial.println(time);
  //timer.setCounter(0, time, 0, timer.COUNT_DOWN, onComplete);
  
  if (digitalRead(start) == HIGH){
    timer.run();
    
    if(!timer.isCounterCompleted()) {
      timer.start();
    }
  }
	//timer.run();

    // Now timer is running and listening for actions.
    // If you want to start the timer, you have to call start() method.
    //if(!timer.isCounterCompleted()) {
    //  timer.start();
    //}
  if (digitalRead(start) == LOW){
    timer.pause();
  }
    /*else {
      timer.start();
    }*/
  
  digitalRead(2);
  delay(1000);
  Serial.println(digitalRead(2));

}

I also have a video I just made:

After reading your description

and watching your video

I would say in my own words:

You power-up the microcontroller
the code shows the time that is relatd to the actual position of the potentiometer.
You can adjust the time with the potentiometer
the display shows the adjusted time and updates this value all the time
until
you move a switch (not a momentary push-button) to the position "count down"
If switch is in position "count-down" the time shall count down and show the remaining time on the display

This means depending on the switch-position your code shall

  • adjust the time (and show the actual adjusted value on the display
  • count down until zero showing the remaining time on the display

This description has more words than your description and is still not covering it all
What shall happen if the countdown has reached zero?

  • if the switch ist still in position "count down" shall the countdown start imidiately a second, a third, a fourth time?
  • shall the code wait for (you will have to define what) and after that (you will have to define what shall happen

You seem to have still not yet understood how setup-works
If you power-up your microcontroller the program starts running down setup()

one single time

in your both codes the code has finished the code inside setup() within 0,01 seconds !

You can do the things like I have described all inside loop()
with the help of if-conditions.

if in adjusting mode: adjust time
if in count-down-mode count down

best regards Stefan

You are describing different states for your project

Initially you are in a state where you want to let the user pick a value with the potentiometer and validate the selection with a button

Then you are in a state where you use the value to do something else.

This can be solved nicely from studying state machines. Here is a small introduction to the topic: Yet another Finite State Machine introduction

Hi, @redondelos
Welcome to the forum.

From what I can see, you want to store a value so that when you power down then later power up, that value will be used as a start.

Store your value into EPROM before switching OFF.
Read the value from EPROM in setup() when you switch ON.

Instead of a pot, use up down buttons to set your value.

KISS...

Tom.. :grinning: :+1: :coffee: :australia:

Well, with your explanation I have a better understanding of what is happening.
See, when I turn the switch on, the variable time keeps changing even though it should not until I turn the switch off (the program keeps reading the potentiometer value and constantly updating the value of time, that is why the countdown never starts).
I need to find a way to do the following:
When I turn the switch on, time takes the value at that instant and does not change (even if I move the potentiometer) until I turn the switch off.

I have the reading of a potentiometer:

void loop(){
  time = analogRead(pot);
  time = map(time, 0, 1023, 60, 0);
}

When I push a switch, I want the value of time at that instant to be stored static to be used in other loop, so it doesn't change even if I move the potentiometer.
I do not know how to do that.

someOtherVariable = time

Now someOtherVariable has whatever value was in the time variable when that line was called.

Although, given what we learned in your other thread, which you shouldn't have split, I don't think this is what you need. You just need to use the time variable you already have and stop giving it a new value on every loop if your button has been pressed. Put the two lines you showed here in an if statement. Check against whether or not that button press has happened yet or not.

I'm going to suggest that this be recombined with your existing thread since it already has all the info on what this program is about.

2 Likes