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....

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;

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

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
}

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.

#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.

You can use an if-statement to read & update the variable only if/when the button is pushed.

You may not need a static variable (another option is to make it global if that's even an issue).

And you may not need any more loops, but in addition to the main loop(), you can use for() loops, while() loops, or do-while() loops. And loops can be nested.

Topics merged

@redondelos

Your two or more topics on the same or similar subject have been merged.

Please do not duplicate your questions as doing so wastes the time and effort of the volunteers trying to help you as they are then answering the same thing in different places.

Please create one topic only for your question and choose the forum category carefully. If you have multiple questions about the same project then please ask your questions in the one topic as the answers to one question provide useful context for the others, and also you won’t have to keep explaining your project repeatedly.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Well, with that help I think I solved it! Thank you!
Now I am trying to solve another problem:

When the timer stops, I want to reset the circuit to the beginning so the timer can be reutilized, with new values if desired (just the timer or stopwatch in your cellphone).
But I am not sure how to make the code reset itself without resetting the Arduino board entirely.

Here is the entire new code:

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

Countimer timer;

LiquidCrystal_I2C lcd(0x27,16,2);

int time;
int time0;

int pot = 0;

//int buttonState = 0;

const int on = 4;

const int push =  5;

int start = 2;

//const int relay = 2;

void setup() {

  //pinMode(4, INPUT);
  pinMode(2, INPUT);
  pinMode(4, OUTPUT);
  pinMode(5, INPUT);
  pinMode(A0, 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, 0, time, 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();

}

/*
void setTime() {
  timer.setCounter(0, time, 0, timer.COUNT_DOWN, onComplete);
  refreshClock();
}
*/

void refreshClock() {
  lcd.clear();
  //timer.setCounter(0, 1, 0, timer.COUNT_DOWN, onComplete);
	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(1000);
  return 0;
}

void loop() {
	// Run timer

  if (digitalRead(start) == LOW){
    timer.pause();
    
    time0 = analogRead(pot);
    time = map(time0, 0, 1023, 60, 0);
    
    
    lcd.setCursor(0,1);
    lcd.print("Set [sec]: ");
    lcd.setCursor(11,1);
    lcd.print(time);

    //Serial.println(digitalRead(push));

    
    if (digitalRead(push) == HIGH){
      lcd.setCursor(11,1);
      lcd.print("SET");
      delay(2000);
      Serial.println(digitalRead(push));
      setup();
    }
    
  }
  
  if (digitalRead(start) == HIGH){
    timer.run();
    //Serial.println(digitalRead(start));
 
    if(!timer.isCounterCompleted()) {
      timer.start();
      digitalWrite(on, HIGH);
      }
      else{
        digitalWrite(on, LOW);
      }
      
  }
  delay(1000);
  Serial.println(digitalRead(start));
  
  if (timer.isCounterCompleted()){
    Serial.println("Completed");
    //timer.stop();
    setup();
    lcd.setCursor(0,1);
    lcd.print("PRESS SWITCH");
    //loop();
  }
  

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

    /*
    Serial.println(digitalRead(2));
    Serial.println(time);
    delay(1000);
    Serial.println("Pushbutton:");
    Serial.println(digitalRead(push));
    */

}

As it can be seen in the video I attached, the timer stops and switch is turned back to off, but it still does not let me reuse the timer because the program is kept stopped and won't tun again unless I reset the board.

May I add that I tried putting a return 0; at the end of onComplete() loop, but it doesn't work either.

https://youtube.com/shorts/gwsTvQysyhg

Well, that does change the time, but it doesn't initialize the program, that's problem, because even though the new time gets set, the timer appears as completed and doesn't move from there.