How to time a certain period after threshold value has been reached

Hi everyone,

I am new to Arduino but loving it. I would be very grateful for a pointer in the direction for a solution to the following challenge which I have not been able to resolve.

The goal: Control a heating sequence for liquid according to inputs time and temperature (sets).

Example: "heat up liquid to 60°, once 60° is reached keep for 25 minutes, then increase temperature to 80° and hold for 30 minutes, then switch off heater"

Setup: PID controlled heating element, temperature sensor. Input to the function is the current temperature, output is the SetpointTemperature which will feed into the PID controller.

My problem: The timing for a specific temperature step should start when the target temperature is reached, i.e. the timer should start ticking down once TemperatoreNow >= TemperatureTarget. Since I am in the loop, I am not able to 'store' the start time to check weather TimeNow - TimeStart > Interval.
I did not find a simple solution... I looked at Scheduler, Metro, Queuing methods but could not make them work for me.

int t1 = 60; // temperature
int t2 = 80;
int s1 = 25; // time interval in min
int s2 = 30;

void setup(){
int setpoint = t1; //PID setpoint = input Temperature t1
}

void loop(){
int tband = 2; //delta actual temperature to target temperature which is acceptable to trigger timer start
int tempNow = analogRead(SensorPin); //read current temperature from sensor pin (connected to temp sensor)
if(tempNow > t1-tband) [StartTimer - how to set to current millis and keep stored while loop continues??];
if(millis() - StartTimer > s1 * 1000 * 60) Setpoint = t2; // Check if interval has elapsed, if so set next temperature as setpoint
}

Thanks a lot for an suggestions/pointers to the right library or solution. Thanks!!

Matthias

void setup(){
 int setpoint = t1;                                                   //PID setpoint = input Temperature t1
 }

setpoint is a local variable that immediately goes out of scope. You might just as well delete that line.

how to set to current millis and keep stored while loop continues

Use either a global variable or a local (to loop) variable that is declared static.

thank you for the answer.

I do not seem to be able to get the desired result either way (define local variable as static or define global variable to store a millis() reading permanently as reference point).

Here is in simple what I am programming. It does not work.

int startTime;

void setup(){
Serial.begin(9600);
}

void loop(){
startTime = millis(); //this should set the reference point in time when initialized and remain constant during looping
int interval = startTime - millis(); //calculate time elapsed since startTime was initialized
}

When I use the Serial.print command in the loop to print the values startTime and interval to the monitor I see that my code is not working. I am still unclear when a variable in the loop is initialized (and remains constant) and when it is overwritten every time through the loop....

Thanks a lot...

Matthias

int interval = startTime - millis();   //calculate time elapsed since startTime was initialized

I think that the problem is that you have an unrealistic expectation, here. The interval since startTime was initialized until this statement executes is a few hundred nanoseconds. You are using a calendar to time events that happen at the speed of light.

When I use the Serial.print command in the loop to print the values startTime and interval to the monitor I see that my code is not working.

It is working. You have unrealistic expectations, based on THAT code.

The post topic says one thing. Your code has nothing that compares a value to a threshold (which would be when you stored the event time, not every pass through loop).

ok I am not getting there. Here is my code for a simpler timer. Once a threshold value is reached on an analogue input, I want to start a timer and record how long it has been since it was reached.

Any help is much appreciated, I am missing/not understanding sth. fundamental here... startTime is overwritten every run through the loop, therefore is timeElapsed always zero.

Thank you for any correction/pointer in the right direction...

int SensorPin = A0;
int treshHoldTemp = 100;
int timeElapsed;
int startTime = 0;
int i = 1;

void setup(){
Serial.begin(9600);
}

void loop(){
if ((analogRead(SensorPin) > treshHoldTemp) && (i = 1)){
startTime = millis();
timeElapsed = millis() - startTime;
}
Serial.println(startTime);
Serial.println(timeElapsed);
}

A state machine (q.v.) would help here, it looks a bit as though your global i variable is intended for something like that purpose, although it looks like it's a work in progress at the moment.

This:
if ((analogRead(SensorPin) > treshHoldTemp) && (i = 1)){
appears to have a classic C error in it: i=1 should likely be i==1 -assignment vs comparison.

startTime = millis();
timeElapsed = millis() - startTime;

How much time has elapsed between these two statements? Approximately 65 nanoseconds. Is that really the interval you are trying to measure?

Recording when an event occurred is one thing. Determine how long it has been since that event occurred is another. You are recording when, and measuring the interval immediately. Of course, you are not getting useful results.

Are you trying to measure how long it took for the sensor to be read?

That would be more like :

void loop(){  
//Start tracking time before you make the call to analogRead...
   startTime = millis();
   
if ((analogRead(SensorPin) > treshHoldTemp) && (i = 1)){

//...and then check the time again once it has completed.
        timeElapsed = millis() - startTime;
   }
      Serial.println(startTime);
      Serial.println(timeElapsed);
   }

If this IS what you're after, you'll probably want to isolate the call to analogRead (place its return value in a variable) to get a truer idea of the access time, because here you're also measuring the evaluation of the if statement.